【问题标题】:PHP cURL multi handling causing random connection issues between servers?PHP cURL 多处理导致服务器之间的随机连接问题?
【发布时间】:2013-05-25 00:32:32
【问题描述】:

我有一个网站,用于跟踪在线游戏中单个玩家的数据。每天同时运行一个 cron,它使用 cURL 从游戏公司的服务器获取每个玩家的数据(每个玩家需要自己的页面来获取)。以前我循环遍历每个玩家,一次创建他们自己的 cURL 请求并存储数据 - 虽然这是一个缓慢的过程,但几周内一切正常(每天处理 500-1,000 名玩家)。

随着我们获得更多玩家,cron 开始运行时间过长,因此我在大约一周前使用ParallelCurl(cURL 多处理)重写了它。它被设置为一次打开不超过 10 个连接并且运行良好 - 在 3-4 分钟内完成大约 3,000 个页面。直到一两天后我才发现有任何问题,我随机无法连接到他们的服务器(返回的 http 代码为 0)。我以为我被永久禁止/阻止了,直到大约 1-2 小时后我才能突然再次连接。阻塞发生在 cron 运行一天后的几个小时 - 当时唯一发出的请求是偶尔的单个文件请求(这些请求一直运行良好并且几个月都没有受到影响)。

这几天都是这样。 Cron 运行良好,然后一段时间后(几个小时)我一两个小时都无法连接。今天我将 cron 更新为一次只打开 5 个连接 - 一切正常,直到 5-6 小时后我无法连接 2 小时。

我已经进行了大量的谷歌搜索,但似乎找不到任何有用的东西。我猜想可能是防火墙阻止了我的连接,但是当涉及到类似的事情时,我真的很困惑。我真的不知道发生了什么,以及我需要做些什么来解决它。我将不胜感激任何帮助——即使是猜测或正确的方向。

请注意,我使用的是共享网络主机 (HostGator)。 2天前我提交了一张票并在他们的论坛上发了一个帖子,我也给公司发了一封电子邮件,但还没有看到任何回复。

--编辑--

这是我使用 parallelcurl 运行多个请求的代码。包含保持不变,与here显示的相同@

set_time_limit(0);

require('path/to/parallelcurl.php');

$plyrs = array();//normally an array of all the players i need to update

function on_request_done($content, $url, $ch, $player) {
    $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);    
    if ($httpcode !== 200) {
        echo 'Could Not Find '.$player.'<br />';
        return;
    } else {//player was found, store in db
        echo 'Updated '.$player.'<br />';
    }
}

$max_requests = 5;

$curl_options = array(
    CURLOPT_SSL_VERIFYPEER => FALSE,
    CURLOPT_SSL_VERIFYHOST => FALSE,
    CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9',
);

$parallel_curl = new ParallelCurl($max_requests, $curl_options);

foreach ($plyrs as $p) {
    $search_url = "http://website.com/".urlencode($p);
    $parallel_curl->startRequest($search_url, 'on_request_done', $p);
usleep(300);//now that i think about it, does this actually do anything worthwhile positioned here?
}

$parallel_curl->finishAllRequests();

这是我用来查看是否可以连接的代码

$ch = curl_init();

$options = array(
    CURLOPT_URL            => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HEADER         => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_ENCODING       => "",
    CURLOPT_AUTOREFERER    => true,
    CURLOPT_CONNECTTIMEOUT => 120,
    CURLOPT_TIMEOUT        => 120,
    CURLOPT_MAXREDIRS      => 10,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_SSL_VERIFYHOST => false,
);
curl_setopt_array( $ch, $options );
$response = curl_exec($ch); 
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

print_r(curl_getinfo($ch));

if ( $httpCode != 200 ){
    echo "Return code is {$httpCode} \n"
        .curl_error($ch);
} else {
    echo "<pre>".htmlspecialchars($response)."</pre>";
}

curl_close($ch);

当我无法连接时运行它会导致:

Array ( [url] => http://urlicantgetto.com/ [content_type] => [http_code] => 0 [header_size] => 0 [request_size] => 121 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 30.073574 [namelookup_time] => 0.003384 [connect_time] => 0.025365 [pretransfer_time] => 0.025466 [size_upload] => 0 [size_download] => 0 [speed_download] => 0 [speed_upload] => 0 [download_content_length] => -1 [upload_content_length] => 0 [starttransfer_time] => 30.073523 [redirect_time] => 0 ) Return code is 0 Empty reply from server

【问题讨论】:

    标签: php curl connection hosting curl-multi


    【解决方案1】:

    这听起来像是网络或防火墙问题,而不是 PHP/代码问题。

    HostGator 阻止了您的出站连接,因为您的出站流量激增,可能被误解为小型 DOS 攻击,或者游戏网站出于同样的原因阻止了您。特别是因为这只是在请求数量增加后才开始。还有HTTP status code of 0 suggests firewall behaviour

    或者,在 curl 请求之后以及稍后当您尝试加载该网站或下载文件时,连接可能没有正确关闭,因为您的服务器已经有太多打开的连接。

    如果您可以通过 SSH 访问您的服务器,如果是网络连接打开问题,我可能可以帮助调试,否则您需要与 HostGator 和游戏网站所有者交谈,看看是否有任何一方完全阻止了您.

    另一种解决方案可能是更慢地抓取游戏网站(在请求之间引入等待时间)以避免被标记为高网络流量。

    【讨论】:

    • 我终于与 HostGator 取得了联系,虽然他们帮不上什么忙,但他们声称没有触发任何事情来阻止连接。遗憾的是,这家游戏公司因其糟糕的客户服务而臭名昭著,老实说,我怀疑无论我发送多少封电子邮件,我都不会得到回复(尽管会继续尝试)。我知道他们可能会阻止我作为潜在的 ddos​​ 攻击,但是在请求发出数小时后发生阻止是否有意义?我也很好奇你认为我应该在请求之间睡多久。 300毫秒? 1000 毫秒?谢谢。
    • 是的,延迟没有多大意义......只是为了确认,您无法从 HostGator 连接到游戏网站,对吧?这不是您无法连接的家庭/办公室位置吗?我可能会睡 500 毫秒,也可能是 250 毫秒,但你睡得越久,被标记的可能性就越小。
    • 是的,服务器无法连接。 4.5 小时前,我更新了 cron,每个句柄之间的睡眠时间为 300 毫秒。运行一次,直到 5 分钟前我才能够毫无问题地连接 - 现在我无法再次建立连接
    • 建立连接的超时时间是多少?您或许可以使用curl_getinfo 了解更多信息。
    • 用我正在使用的处理连接的所有代码更新了原始帖子。还包括 curl_getinfo 的完整打印。我目前没有设置默认超时,因为我还没有看到单个 parallelcurl 脚本使用一个 - 这可能是我的问题吗?编辑 - 刚刚再次被取消禁止,我想它开始后几乎正好 1 小时
    猜你喜欢
    • 2021-03-08
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-15
    相关资源
    最近更新 更多