在PHP中耗尽卷曲的套接字?

时间:2016-02-28 20:23:59

标签: php sockets curl

我在PHP CLI脚本中使用CURL库对服务器进行大量API调用。

我注意到在28,219个连接(顺序打开/执行,而不是同时)之后卷曲失败。每次尝试的后续请求都会在大约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套接字,但我对如何知道这个问题的正确解决方案的工作方式还不够熟悉(简短)减少请求的数量。)

编辑:

由于人们一直建议将其作为远程服务器,因此围攻对我的测试服务器(带有API的服务器)执行1000000次请求的结果。我不是100%确定导致单一失败的原因,但它只发生过一次,因此我将其视为一种异常,不像我在28,219次请求后从CURL获得的一致失败。 / p>

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

1 个答案:

答案 0 :(得分:2)

每次迭代都会创建一个新的curl资源。如果您重新使用连接,一切都应按预期工作。将curl初始化循环并传入curl变量