php - Guzzle send() 方法导致 cURL 错误 35 打开的文件太多

标签 php curl guzzle

尝试使用 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 中的错误?

最佳答案

这不是 Guzzle 或 MailGun 的问题,而是您对库的特定实现。如此多的长时间运行(打开)请求实际上是在达到底层操作系统(libcurl、openssl 和 fopen)的极限。

根据 libcurl errors错误 35 表示 SSL/TLS 握手出错。

根据各种 google 引用错误:02001018 表示 openssl 无法访问(或读取)证书文件。

您可以使用 ulimit查看和修改各种系统范围资源的限制。

您还可以使用 lsof查看打开的文件。

要解决您的问题:

  1. (如果可以)增加系统资源限额 - 请务必研究此更改可能产生的影响。
  2. 重构您的代码,以免达到操作环境的限制。也许我可以对某些请求使用异步通信。一个不同的库,或者可能“下拉”并实现您自己的库。
  3. 找到一些方法来实现某种类型的速率限制(我已将其与 #2 分开列出)但它们可以齐头并进。

关于php - Guzzle send() 方法导致 cURL 错误 35 打开的文件太多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34648812/

相关文章:

php - Jquery onblur 第二次不工作

javascript - 选择时显示值的总和

PHP cURL 身份验证问题

curl - 为 android arm64 构建 libcurl

bash - 读取 HTTP 正文响应并使用 Bash 迭代该结果

php - 使用 Guzzle 6 获取 API 调用持续时间的最佳方法是什么

php - SQL select查询与数据计算

php - 通过 postfix + PHP 以 Apache 用户身份发送电子邮件

php - Laravel - GuzzleHttp 客户端抛出 cURL 错误 35 : Unknown SSL protocol error in connection

php - 使用 GuzzleHttp REST API 客户端在 PHP 中进行非阻塞调用