Laravel 10中使用HTTP Client发送同应用POST请求超时问题排查
问题原因及解决办法
核心原因
你在Laravel Sail容器内部发起http://localhost/receive请求时,这个localhost指向容器自身的localhost,但PHP是单线程运行的,当前/send请求还在处理中,又发起一个指向自身的请求会导致进程阻塞,最终触发超时。而Postman是从宿主机发起请求,容器内单独执行的curl是新进程,都不会和当前应用进程冲突,所以能正常响应。
解决办法
办法一:用容器服务名替换localhost
Laravel Sail默认的应用容器服务名是laravel.test,把请求地址换成这个服务名就能解决阻塞问题:
Route::get('/send', function () { $response = Http::withOptions([ 'verify' => false ])->post('http://laravel.test/receive', [ 'title' => 'My Title', 'body' => 'My Body Content', ]); return $response->successful(); });
容器内部的DNS会自动将laravel.test解析到应用容器的IP,避免单线程阻塞。
办法二:直接调用逻辑代码(更高效)
既然是同应用内的逻辑,没必要走HTTP请求,把接收端的逻辑抽成独立方法直接调用即可:
// 定义复用的处理逻辑 function handleReceive($title, $body) { // 原来的必要业务逻辑... return ['message' => 'Success']; } // 发送路由直接调用逻辑 Route::get('/send', function () { $result = handleReceive('My Title', 'My Body Content'); return response()->json($result)->successful(); }); // 接收路由复用同一逻辑 Route::post('/receive', function(Request $request) { $title = $request->input('title'); $body = $request->input('body'); $result = handleReceive($title, $body); return response()->json($result); });
这种方式既省去了HTTP请求的额外开销,也从根源上避免了超时问题。
内容的提问来源于stack exchange,提问作者Greg Ostry
相关产品推荐
相关产品推荐

