【发布时间】:2016-01-15 21:58:27
【问题描述】:
尝试使用 Guzzle 5 执行以下代码。
$client = new GuzzleClient(['defaults/headers/User-Agent' => static::$userAgentString]);
$request = $client->createRequest(static::$serviceRequestMethod, $url, $options); // Create signing request.
$signature = new Signature\Signature($this->accessKey, $this->secretKey);
$options = array_merge_recursive($options, ['query' => ['Signature' => $signature->signString($hash)]]);
$request = $client->createRequest(static::$serviceRequestMethod, $url, $options); // Create real request.
$response = $client->send($request);
当我在长时间运行的 CLI 进程中调用此行足够多次时,我得到以下错误,可追溯到 $response = $client->send($request); 行
cURL error 35: error:02001018:system library:fopen:Too many open files
点击之后,服务器上的所有其他网页和命令都会出现相同的“打开的文件过多”错误。
这是堆栈跟踪:
#0 /home/vagrant/code/example.com/vendor/guzzlehttp/guzzle/src/RequestFsm.php(104): GuzzleHttp\Exception\RequestException::wrapException(Object(GuzzleHttp\Message\Request), Object(GuzzleHttp\Ring\Exception\ConnectException))
#1 /home/vagrant/code/example.com/vendor/guzzlehttp/guzzle/src/RequestFsm.php(132): GuzzleHttp\RequestFsm->__invoke(Object(GuzzleHttp\Transaction))
#2 /home/vagrant/code/example.com/vendor/react/promise/src/FulfilledPromise.php(25): GuzzleHttp\RequestFsm->GuzzleHttp\{closure}(Array)
#3 /home/vagrant/code/example.com/vendor/guzzlehttp/ringphp/src/Future/CompletedFutureValue.php(55): React\Promise\FulfilledPromise->then(Object(Closure), NULL, NULL)
#4 /home/vagrant/code/example.com/vendor/guzzlehttp/guzzle/src/Message/FutureResponse.php(43): GuzzleHttp\Ring\Future\CompletedFutureValue->then(Object(Closure), NULL, NULL)
#5 /home/vagrant/code/example.com/vendor/guzzlehttp/guzzle/src/RequestFsm.php(135): GuzzleHttp\Message\FutureResponse::proxy(Object(GuzzleHttp\Ring\Future\CompletedFutureArray), Object(Closure))
#6 /home/vagrant/code/example.com/vendor/guzzlehttp/guzzle/src/Client.php(165): GuzzleHttp\RequestFsm->__invoke(Object(GuzzleHttp\Transaction))
#7 /home/vagrant/code/example.com/app/library/amazon/src/AWS.php(540): GuzzleHttp\Client->send(Object(GuzzleHttp\Message\Request))
我不知道在通过 Guzzle 发送请求后需要显式关闭资源。我是否在这里遗漏了什么或者这可能是 Guzzle 中的错误?
【问题讨论】:
-
你能定义“足够的时间”吗?该过程运行多长时间?由于您自己的遗漏,听起来您正在达到 PHP 的限制之一。您尝试并行执行多少个请求? GuzzleHttp\Pool 对您来说是一个可行的选择吗?
-
@ShaunBramley 应该更具体地说,“足够的时间”范围为来自此脚本的 5,000 多个获取/发布请求,并且根据队列中的记录数运行 2 分钟到 2 小时不等。没有一个是并行执行的。由于依赖于它的代码,每个都是按顺序完成的。
-
您可以选择升级到 Guzzle 6 吗?
-
@ShaunBramley 不幸的是,没有。另一个
mailgun/mailgun-php包依赖于 5 并且在项目中使用。