Guzzle 池:如何等待所有请求完成而不超时?
Guzzle Pool: how to wait for all requests to finish without timing out?
在过去的 6 个月里,我一直在使用 Guzzle 池从外部服务器请求数据(每次请求大约 1-2 MB)。我同时执行 5 个请求。然而,事情发生了变化,外部服务器似乎超载了,因此变得非常慢。有时它很快就像 1-2 秒,但很多时候服务器需要为每个请求等待 2+ 分钟。
但这应该不是问题。但是现在(因为发出请求变得很慢),我在池中的一些请求返回错误:
cURL error 18: transfer closed with outstanding read data remaining
它通常会在正好等待 2 分钟后执行此操作。
虽然有趣的是,如果我通过 Postman 发出请求(例如),我仍然需要等待 2-3+ 分钟,但我最终得到了响应。
所以这让我相信 Guzzle 在 2 分钟后阻止了请求。但是,我找不到任何设置来更改此设置。我什至尝试发送 Keep Alive
和 Content-Length
header,但它们没有用(也许我没有正确使用它们)。
这是我当前执行 Guzzle 池请求的代码的一部分。 (我正在使用 PHP 7.1、Guzzle 6.3 和 Laravel 5.7)。
$headers = ['Authorization' => 'Bearer ' . $token];
$client = new Client();
$requests = function ($urls, $headers)
{
foreach ($urls as $key => $url)
{
yield new Requests('GET', $url, $headers);
}
};
$pool = new Pool($client, $requests($urls, $headers),
[
'concurrency' => 5,
'fulfilled' => function ($response, $index)
{
echo 'fulfilled -> ' . $index;
},
'rejected' => function ($reason, $index)
{
echo 'rejected -> ' . $index . ' -> error:' . $reason->getMessage();
},
]);
$promise = $pool->promise();
$promise->wait();
很遗憾,我无法共享外部服务器 URL,因为它是私有的。
我在这里做错了什么,不允许请求等待它完成/发送数据?
更新: 我已经尝试了@Alexey Shokov 的建议,它摆脱了被拒绝的状态。现在请求不会在 2 分钟后超时。但是,一旦我从以前的 timed out
来源得到一些回复,我就会得到 null 作为响应。
服务器端似乎有问题。该错误表明 cURL 客户端发现服务器发送的预期响应大小与实际响应大小不匹配。
看看this SO topic, same issue. I think it worths trying to set HTTP version to 1.0 as stated in the discussion with Guzzle's version
option或者直接在Request
对象(yield new Requests('GET', $url, $headers, null, '1.0')
).
在过去的 6 个月里,我一直在使用 Guzzle 池从外部服务器请求数据(每次请求大约 1-2 MB)。我同时执行 5 个请求。然而,事情发生了变化,外部服务器似乎超载了,因此变得非常慢。有时它很快就像 1-2 秒,但很多时候服务器需要为每个请求等待 2+ 分钟。
但这应该不是问题。但是现在(因为发出请求变得很慢),我在池中的一些请求返回错误:
cURL error 18: transfer closed with outstanding read data remaining
它通常会在正好等待 2 分钟后执行此操作。
虽然有趣的是,如果我通过 Postman 发出请求(例如),我仍然需要等待 2-3+ 分钟,但我最终得到了响应。
所以这让我相信 Guzzle 在 2 分钟后阻止了请求。但是,我找不到任何设置来更改此设置。我什至尝试发送 Keep Alive
和 Content-Length
header,但它们没有用(也许我没有正确使用它们)。
这是我当前执行 Guzzle 池请求的代码的一部分。 (我正在使用 PHP 7.1、Guzzle 6.3 和 Laravel 5.7)。
$headers = ['Authorization' => 'Bearer ' . $token];
$client = new Client();
$requests = function ($urls, $headers)
{
foreach ($urls as $key => $url)
{
yield new Requests('GET', $url, $headers);
}
};
$pool = new Pool($client, $requests($urls, $headers),
[
'concurrency' => 5,
'fulfilled' => function ($response, $index)
{
echo 'fulfilled -> ' . $index;
},
'rejected' => function ($reason, $index)
{
echo 'rejected -> ' . $index . ' -> error:' . $reason->getMessage();
},
]);
$promise = $pool->promise();
$promise->wait();
很遗憾,我无法共享外部服务器 URL,因为它是私有的。
我在这里做错了什么,不允许请求等待它完成/发送数据?
更新: 我已经尝试了@Alexey Shokov 的建议,它摆脱了被拒绝的状态。现在请求不会在 2 分钟后超时。但是,一旦我从以前的 timed out
来源得到一些回复,我就会得到 null 作为响应。
服务器端似乎有问题。该错误表明 cURL 客户端发现服务器发送的预期响应大小与实际响应大小不匹配。
看看this SO topic, same issue. I think it worths trying to set HTTP version to 1.0 as stated in the discussion with Guzzle's version
option或者直接在Request
对象(yield new Requests('GET', $url, $headers, null, '1.0')
).