湖库一体:2026年数据库架构的“终极答案”还是新瓶装旧酒?
2026/7/11 1:03:27
Http::get()(即Illuminate\Http\Client\Factory提供的 HTTP 客户端)默认是同步阻塞的,基于 Guzzle + cURL 或 stream wrapper 实现。在循环中直接调用会导致:
$urls=['https://a.com','https://b.com','https://c.com'];foreach($urlsas$url){$response=Http::get($url);// 阻塞!// 处理响应}若每个请求耗时 200ms,3 次请求总耗时 ≈ 600ms。
如果目标服务支持批量查询(如 GraphQL、/batch endpoint),1 次请求解决 N 个问题。
在 Swoole 环境中,可用协程并发:
useSwoole\Coroutine;useSwoole\Coroutine\Http\Client;Coroutine\run(function()use($urls){$results=[];foreach($urlsas$url){go(function()use($url,&$results){$parsed=parse_url($url);$cli=newClient($parsed['host'],443,true);$cli->get($parsed['path']??'/');$results[$url]=$cli->body;$cli->close();});}// 所有请求并发执行,总耗时 ≈ 最慢单次请求});注意:Laravel HTTP Client 本身不支持异步,需绕过它直接使用协程 HTTP 客户端。
在传统 FPM 下,将任务分片交由队列处理:
// 控制器中URLBatchJob::dispatch($urls);// 队列任务中(可并行多个 worker)publicfunctionhandle(){foreach(array_chunk($this->urls,10)as$chunk){// 可在此 chunk 内用多进程或限制并发的同步请求}}Guzzle 支持异步 promises,但 PHP 本身单线程,需手动wait(),仍阻塞,仅能稍作优化:
$client=new\GuzzleHttp\Client();$promises=[];foreach($urlsas$url){$promises[$url]=$client->getAsync($url);}$responses=\GuzzleHttp\Promise\unwrap($promises);// 此处才发起并发仅在 CLI 下有效,FPM 中仍可能超时;且无法与 Laravel
Http客户端直接集成。
Http::get()是同步阻塞的,禁止在循环中直接使用。