2026/4/18 10:10:29
网站建设
项目流程
济南智能网站建设咨询电话,网站建设行业发展趋势,小企业网站建设收费,自适应网站推广Http::get()#xff08;即 Illuminate\Http\Client\Factory 提供的 HTTP 客户端#xff09;默认是同步阻塞的#xff0c;基于 Guzzle cURL 或 stream wrapper 实现。在循环中直接调用会导致#xff1a;
串行请求#xff1a;每个请求必须等前一个完成才发起下一个总耗时 ≈…Http::get()即Illuminate\Http\Client\Factory提供的 HTTP 客户端默认是同步阻塞的基于 Guzzle cURL 或 stream wrapper 实现。在循环中直接调用会导致串行请求每个请求必须等前一个完成才发起下一个总耗时 ≈ ∑(各请求耗时)极易成为性能瓶颈浪费 CPU 资源PHP 进程在 I/O 等待期间无法做其他工作示例反面教材$urls[https://a.com,https://b.com,https://c.com];foreach($urlsas$url){$responseHttp::get($url);// 阻塞// 处理响应}若每个请求耗时 200ms3 次请求总耗时 ≈ 600ms。正确做法✅ 方案 1使用批量接口首选如果目标服务支持批量查询如 GraphQL、/batch endpoint1 次请求解决 N 个问题。✅ 方案 2改用异步协程Swoole / ReactPHP在 Swoole 环境中可用协程并发useSwoole\Coroutine;useSwoole\Coroutine\Http\Client;Coroutine\run(function()use($urls){$results[];foreach($urlsas$url){go(function()use($url,$results){$parsedparse_url($url);$clinewClient($parsed[host],443,true);$cli-get($parsed[path]??/);$results[$url]$cli-body;$cli-close();});}// 所有请求并发执行总耗时 ≈ 最慢单次请求});注意Laravel HTTP Client 本身不支持异步需绕过它直接使用协程 HTTP 客户端。✅ 方案 3分片 队列FPM 环境在传统 FPM 下将任务分片交由队列处理// 控制器中URLBatchJob::dispatch($urls);// 队列任务中可并行多个 workerpublicfunctionhandle(){foreach(array_chunk($this-urls,10)as$chunk){// 可在此 chunk 内用多进程或限制并发的同步请求}}✅ 方案 4用 Guzzle 的异步仅限 CLI且仍非真异步Guzzle 支持异步 promises但 PHP 本身单线程需手动wait()仍阻塞仅能稍作优化$clientnew\GuzzleHttp\Client();$promises[];foreach($urlsas$url){$promises[$url]$client-getAsync($url);}$responses\GuzzleHttp\Promise\unwrap($promises);// 此处才发起并发仅在 CLI 下有效FPM 中仍可能超时且无法与 LaravelHttp客户端直接集成。总结Http::get()是同步阻塞的禁止在循环中直接使用。优先考虑批量 API。若需并发必须脱离 Laravel HTTP Client使用 Swoole 协程或队列分片。在 FPM 环境下队列是安全且可扩展的解法。