GuzzleHttp 6.3.2异步请求性能疑问:100个GET请求耗时50秒是否正常?
关于Guzzle 6.3.2异步请求耗时的问题解答
嘿,这个情况我太熟悉了——先给你明确结论:这个表现肯定不是正常的异步并发效果,正常来说100个各耗时5秒的异步请求,总耗时应该接近5秒(忽略连接建立这类微小开销)。你现在用了50秒,说明你的请求其实是分批串行执行的,核心问题出在并发数的配置上。
咱们来拆解一下:
- 50秒总耗时 ÷ 单个请求5秒耗时 = 10,这意味着你的Guzzle实际上是同时跑10个请求,100个请求分成10批,每批5秒,加起来就是50秒。这明显是并发数被限制了,没有真正把异步的威力发挥出来。
为什么会出现这种情况?
Guzzle 6.x的Pool组件(用来管理批量异步请求的核心工具)默认会限制并发数——它不会无限制地同时发起所有请求,而是会根据默认配置或者系统资源情况控制并发量。如果你没有显式设置concurrency参数,它可能会默认使用一个保守的值(比如10),这就导致了请求分批执行。
怎么解决?
很简单,在创建Pool的时候显式设置足够大的concurrency参数(比如直接设为100,当然要考虑你的系统和目标服务端的承受能力——服务端得能扛住100个并发请求才行)。
给你个示例代码参考:
use GuzzleHttp\Client; use GuzzleHttp\Pool; use GuzzleHttp\Psr7\Request; // 初始化客户端 $client = new Client(); // 生成100个GET请求 $requestsGenerator = function ($totalRequests) { $targetUrl = 'http://your-server.com/your-sleep-endpoint'; for ($i = 0; $i < $totalRequests; $i++) { yield new Request('GET', $targetUrl); } }; // 创建请求池,显式设置并发数为100 $pool = new Pool($client, $requestsGenerator(100), [ 'concurrency' => 100, 'fulfilled' => function ($response, $index) { // 处理成功的响应,比如记录日志或解析数据 echo "请求{$index}完成,状态码:{$response->getStatusCode()}\n"; }, 'rejected' => function ($reason, $index) { // 处理失败的请求,比如记录错误 echo "请求{$index}失败:{$reason->getMessage()}\n"; }, ]); // 启动池并等待所有请求完成 $pool->promise()->wait();
额外注意事项
- 系统文件描述符限制:每个HTTP请求都会占用一个套接字(对应系统的文件描述符),如果你的系统
ulimit设置过低(比如默认可能是1024,100个并发完全没问题,但如果更高的话需要调整),可能会导致请求失败。 - 服务端承受能力:虽然你用
sleep(5)模拟响应,但服务端得能同时处理100个并发请求才行,如果服务端本身有连接数限制,那即使Guzzle并发拉满,服务端也会排队,总耗时还是会增加。
调整完并发数后,你应该能看到总耗时接近5秒,这才是异步请求该有的表现~
内容的提问来源于stack exchange,提问作者bijiDango
相关产品推荐
相关产品推荐

