【发布时间】:2016-06-11 19:11:04
【问题描述】:
我正在使用 PHP CLI 脚本中的 CURL 库对服务器进行大量 API 调用。
我注意到在 28,219 个连接(顺序打开/执行,而不是同时)之后 curl 失败。尝试的每个后续请求都会失败,直到大约 30 秒后。
正在访问的 API(据我所知)没有挂起或导致错误。我已经尝试过访问不同的远程主机,但错误总是发生,所以我怀疑问题出在 PHP/Curl,而不是远程主机。
这是我为演示该问题而制作的示例脚本:
try {
for ($i = 0; $i < 1000000; ++$i) {
get('https://example.org/'); // change me if you're going to run this
echo '.';
}
} catch (Exception $e) {
echo "Error happened on {$i} - {$e->getMessage()}";
}
function get($url) {
$curl = curl_init($url);
if (! $curl) {
throw new Exception('Error1 - Could not create new curl handle');
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 20);
$contents = curl_exec($curl);
$info = curl_getinfo($curl);
if ($errno = curl_errno($curl)) {
throw new Exception("Error2 " . curl_strerror($errno), $errno);
}
curl_close($curl);
if ($info['http_code'] === 200) {
return $contents;
}
throw new Exception("Error3", (int) $info['http_code']);
}
输出:
.................................................. ..................................................... ..................................................... ..................................................... ..................................................... ..................................................... ................................................发生错误在 28219 - Error2 无法连接到服务器
我倾向于相信这个错误正在发生,因为我已经用尽了可用的 TCP 套接字,但我对它的工作原理不够熟悉,无法知道这个问题的正确解决方案(没有发出更少的请求)。
编辑:
由于人们一直建议它是远程服务器,因此这里是 siege 对我的测试服务器(具有 API 的服务器)执行 1000000 次请求的结果。我不能 100% 确定导致单次失败的原因,但它只发生了一次,所以我将其视为异常情况,这与我在 28,219 次请求后从 CURL 获得的持续失败不同。
siege -c 1 -r 1000000 http://mytestserver/same/url/as/with/curl
* SIEGE 3.0.5
** Preparing 1 concurrent users for battle.
The server is now under siege...
The server is now under siege...[error] socket: -187603200 connection refused.: Connection refused
done.
Transactions: 999999 hits
Availability: 100.00 %
Elapsed time: 626.70 secs
Data transferred: 7719.03 MB
Response time: 0.00 secs
Transaction rate: 1595.66 trans/sec
Throughput: 12.32 MB/sec
Concurrency: 0.94
Successful transactions: 999999
Failed transactions: 1
Longest transaction: 0.14
Shortest transaction: 0.00
【问题讨论】:
-
请更详细地告诉我们您遇到了什么错误
-
可能被屏蔽了——请求太多了,考虑加个 sleep 语句
-
@self 被什么阻止了?远程服务器没有阻止请求,我可以在它上面运行许多我正在做的请求,没有任何问题。
-
“无法连接到服务器”实际上表明服务器端拒绝了许多连接...如果 curl 本身会用完套接字,它可能会返回另一个错误
-
嗯...,您可以在条件语句中设置计数,设置为您认为它会中断的某个(高)数字,然后退出?之后将该数字更改为更高的数字。我无法解决您的问题,但这就是我要尝试找出失败/停止需要多少次调用。 @伊恩