大量异步请求不是真正的异步?问题期望实际结果
问题
我们正在尝试使用 guzzle 执行并发异步请求。在浏览了一些资源(例如这样和这样)之后,我们提出了一些在下面共享的代码。但是,它没有按预期工作。
看起来 Guzzle 正在同步而不是异步执行这些请求。
期望
只是为了测试目的,我们点击了一个内部URL,它会进行5秒的睡眠。对于 10 的并发,我们预计所有 10 个请求最初将排队并几乎同时发送到服务器,在那里它们将等待 5 秒,然后几乎所有这些请求将几乎同时完成。这将使客户从迭代器等处拾取10个新请求。
法典
$iterator = function() {
$index = 0;
while (true) {
$client = new Client(['timeout'=>20]);
$url = 'http://localhost/wait/5' . $index++;
$request = new Request('GET',$url, []);
echo "Queuing $url @ " . (new Carbon())->format('Y-m-d H:i:s') . PHP_EOL;
yield $client
->sendAsync($request)
->then(function(Response $response) use ($request) {
return [$request, $response];
});
}
};
$promise = \GuzzleHttp\Promise\each_limit(
$iterator(),
10, /// concurrency,
function($result, $index) {
/** GuzzleHttp\Psr7\Request $request */
list($request, $response) = $result;
echo (string) $request->getUri() . ' completed '.PHP_EOL;
},
function(RequestException $reason, $index) {
// left empty for brevity
}
);
$promise->wait();
实际结果
我们发现Guzzle在第一个请求完成之前从未提出过第二个请求。等等。
Queuing http://localhost/wait/5/1 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/2 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/3 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/4 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/5 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/6 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/7 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/8 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/9 @ 2017-09-01 17:15:28
Queuing http://localhost/wait/5/10 @ 2017-09-01 17:15:28
http://localhost/wait/5/1 completed
Queuing http://localhost/wait/5/11 @ 2017-09-01 17:15:34
http://localhost/wait/5/2 completed
Queuing http://localhost/wait/5/12 @ 2017-09-01 17:15:39
http://localhost/wait/5/3 completed
Queuing http://localhost/wait/5/13 @ 2017-09-01 17:15:45
http://localhost/wait/5/4 completed
Queuing http://localhost/wait/5/14 @ 2017-09-01 17:15:50
操作系统/版本信息
- 乌班图
- PHP/7.1.3
- 咕噜咕噜/6.2.1
- 卷曲/7.47.0
问题可能出在 \GuzzleHttp\Promise\each_limit ..这也许不能足够快地启动或解决承诺。我们可能不得不把它骗到外部。tick