在过去6个月中,我一直在使用Guzzle Pool向外部服务器请求数据(每个请求大约1-2 MB)。我一次要同时执行5个请求。但是,情况发生了变化,外部服务器似乎过载,因此变得非常慢。有时速度非常快,例如1-2秒,但是很多时候服务器需要为每个请求等待2分钟以上。
这应该不是问题。但是如今(由于发出请求的速度变慢),我在池中的某些请求返回了错误:
cURL error 18: transfer closed with outstanding read data remaining
通常在等了2分钟后执行此操作。
但是有趣的是,如果我通过邮递员(例如)发出请求,那么我仍然必须等待2-3分钟以上,但最终还是得到了响应。
因此,这使我相信Guzzle在2分钟后阻止了请求。但是,我找不到任何设置来更改此设置。我什至尝试发送Keep Alive
和Content-Length
标头,但它们不起作用(也许我没有正确使用它们)。
这是我当前代码中执行Guzzle Pool请求的一部分。 (我使用的是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作为响应。
答案 0 :(得分:1)
服务器端似乎有问题。该错误表明cURL客户端看到服务器发送的预期响应大小与实际响应大小不匹配。
看看this SO topic,同样的问题。我认为值得尝试像使用Guzzle's version
option或直接在Request
对象(yield new Requests('GET', $url, $headers, null, '1.0')
)中讨论的那样将HTTP版本设置为1.0。