问题
Trying to execute the following code with 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);
When I call this line enough times on a long running CLI process, I get the following error traced back to the line $response = $client->send($request);
cURL error 35: error:02001018:system library:fopen:Too many open files
After that hits, every other web page and command on the server breaks down with the same "too many open files" error.
Here is the stack trace:
#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))
I'm not aware of any need to explicitly close a resource after sending a request through Guzzle. Am I missing something here or could this be a bug in Guzzle?
回答1:
This is not an issue with Guzzle, or MailGun, so much as it is with your particular implementation of the libraries. You are actually hitting the limits of the underlying operating system (libcurl, openssl, and fopen) by having so many long running (open) requests.
According to libcurl errors error 35 indicates that there was an error with the SSL/TLS handshake.
According to various google references error: 02001018 is an indication that openssl was unable to access (or rather read) the certificate file.
You are able to use ulimit to view and modify the limits various system-wide resources.
You are also able to use lsof to view the open files.
To resolve your issue:
- (if able) increase system resource allowances - be sure to research the implications that this change can have.
- Refactor your code so that you do not hit the operating environments limits. Perhaps it my be possible to use asynchronous communications for some of the requests. A different library, or perhaps "dropping down" and implementing your own.
- Find some way to implement some type of rate limiting (I have listed this separately from #2) but they could go hand in hand.
来源:https://stackoverflow.com/questions/33182490/guzzle-send-method-causes-curl-error-35-too-many-open-files