并发请求仅将等待时间并行化,不解决api调用慢的本质问题;需关注超时、重试、错误处理及响应解析效率,合理使用http::pool()并逐个验证响应状态。

并发请求本身不解决第三方 API 调用慢的问题,它只把“等的时间”从串行变并行。真正卡住的,往往是单个请求的超时、重试逻辑缺失、错误未显式处理,或响应体解析方式低效。
Http::pool() 是并发首选,但必须显式检查每个响应状态
很多人以为 Http::pool() 返回数组就万事大吉,其实每个响应对象都需单独验证。不调用 ->successful() 或 ->failed(),就可能把 401/502 当作正常数据往下传。
- 正确做法:对每个响应调用
->throw()(抛异常)或->ok()+->json()组合 - 常见错误:直接
json_decode($response->body(), true),遇到空响应或非 JSON 会返回null,后续数组操作报Trying to access array offset on value of type null - 推荐写法:
$responses['user']->throw()->json(),失败时自动抛Illuminate\Http\Client\RequestException,可集中 try/catch
并发不是万能的,别在循环里滥用 Http::pool()
比如要查 100 个用户的状态,写成 100 次 Http::pool() 调用,反而比串行更慢——连接复用失效、DNS 查询重复、HTTP/2 流控被挤爆。
- 真正适合并发的场景:固定数量、已知 URL 的几个接口(如用户基础信息 + 订单统计 + 通知设置)
- 大量 ID 批量查询,应优先走第三方 API 是否支持批量 endpoint(如
/users?ids=1,2,3),而不是硬拆并发 - 若必须分批,并发组数建议 ≤ 5,每组内请求数 ≤ 3,避免压垮对方服务或触发限流
超时和重试必须按接口粒度配置,不能全局统一
查天气 API 可能 2s 就返回,而支付回调确认可能要等 15s;一个 Http::timeout(5)->retry(2) 套所有接口,要么超时太短频繁失败,要么太长拖垮整体响应。
- 为不同业务场景建命名 client:
Http::client('weather')设 timeout=3,Http::client('payment')设 timeout=12 - 重试只应对网络抖动类错误(
ConnectException、RequestException),不应对 400/404 这类业务错误重试 - 使用
->retry(3, 100, \GuzzleHttp\Exception\ConnectException::class)精确控制重试范围
并发响应体解析要避免重复 json_decode
Http::pool() 返回的是多个 Illuminate\Http\Client\Response 实例,每个调用 ->json() 都会重新解析一次 JSON 字符串——如果响应体大、字段多,这部分 CPU 开销不可忽略。
- 只需一次解析:先
$data = $response->json(),再从$data中取值,不要反复调$response->json()['user']['name'] - 若需结构化数据,建议封装成 DTO 类,构造时传入
$response->json()结果,避免后续多次访问属性时隐式解析 - 注意:不要在 Blade 模板里直接写
{{ $response->json()['status'] }},这会在每次渲染时重复解析
最常被忽略的一点:并发请求的错误日志必须带上下文标签。比如 pool 中某个请求失败,光记 "HTTP request failed" 毫无意义,得记录是哪个 key('inventory' 还是 'price')、URL、请求耗时、原始响应头。否则线上出问题,你得靠猜。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











