You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP Guzzle7并发请求异常:提升并发数后耗时未下降求助

问题排查与修复建议

嘿,我仔细看了你的代码,调整并发数后耗时没明显下降的核心问题,在于你的请求闭包里塞了太多同步、重复的CPU密集型工作,这些操作阻塞了Guzzle的并发调度,让真正的网络请求并发没发挥作用。下面具体拆解问题和给出修复方案:

核心问题分析

1. 重复同步计算拖慢并发效率

你在每个请求的闭包内部重复做这些完全没必要的工作:

  • 循环40次生成固定的bulk数组,纯浪费CPU资源
  • 每个请求都重新编码JWT token,这是CPU密集型操作,会严重抢占并发调度的资源

Guzzle的Pool是在需要发起请求时才会调用你yield的闭包,这些同步工作会被串行执行(或者说占满CPU),导致真正的网络请求并发度上不去,所以调大concurrency也没明显效果。

2. HTTP请求头设置错误

你把JWT的协议头(alg/typ)直接传给了Request的headers参数,这是完全错误的。正确的做法是把生成好的token放到Authorization HTTP头里,否则你的请求可能根本无法被服务端正确识别,甚至直接请求失败,耗时统计也就失去了参考意义。

3. 潜在的空URI问题

代码里$uri = '',如果实际运行时也是空值,请求根本发不出去,这也会导致耗时异常(比如都是快速失败,但总耗时包含了这些无效请求的处理时间)。

修复后的代码

把重复的工作提前预处理,让请求闭包只负责发起异步请求,彻底释放并发能力:

use GuzzleHttp\Client;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;

$client = new Client();
$start = time();

// --- 提前预处理所有重复内容 ---
// 只生成一次固定的bulk数组
$bulk = [];
for ($count1 = 0; $count1 < 40; $count1++) {
    $bulk[] = json_decode('{}');
}
// 只生成一次JWT token(因为payload完全固定)
$payload = [
    "drone_id" => 56,
    "bulk" => $bulk
];
$jws = new \Gamegos\JWS\JWS();
$jwtHeaders = ['alg' => 'HS256', 'typ' => 'JWT'];
$key = 'your-real-secret-key'; // 替换成你的真实密钥
$token = $jws->encode($jwtHeaders, $payload, $key);
// 正确设置HTTP请求头
$httpHeaders = [
    'Authorization' => "Bearer $token",
    'Content-Type' => 'application/json' // 根据API需求调整
];
$uri = 'your-real-api-endpoint'; // 替换成你的真实API地址

// 请求生成器只负责创建异步请求,不再做同步计算
$requests = function ($total) use ($client, $uri, $httpHeaders, $token) {
    for ($i = 0; $i < $total; $i++) {
        yield function() use ($client, $uri, $httpHeaders, $token) {
            $request = new Request('POST', $uri, $httpHeaders, $token);
            return $client->sendAsync($request);
        };
    }
};

$pool = new Pool($client, $requests(2500), [
    'concurrency' => 10,
]);

// 执行并等待所有请求完成
$promise = $pool->promise();
$promise->wait();

echo 'Request took ' . (time() - $start) . ' seconds' . PHP_EOL;

额外优化建议

  • 如果你的API允许,还可以复用Request对象(因为所有请求参数完全一致),不用每个请求都new一个Request,进一步减少开销
  • 建议添加请求结果回调,比如在Pool配置里加入fulfilled和rejected,统计成功/失败请求数,避免因为大量失败请求导致耗时统计不准
  • 服务端通常会有并发上限,调大concurrency到一定程度后性能不会再提升,可以逐步测试找到最优值

内容的提问来源于stack exchange,提问作者Luke Rayner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 13:57:55