连接超时是分层现象,需按数据库、Redis、HTTP、队列逐层定位;优先查laravel.log中的错误类型、文件行号及具体消息,再结合QUEUE_CONNECTION与retry_after配置匹配性、驱动差异及底层连接测试验证。

连接超时不是单一问题,而是分层现象:数据库、Redis、HTTP 请求、队列服务各自有独立的超时机制,必须按层定位。
查 storage/logs/laravel.log 里真实的错误来源
别猜,先看日志。Laravel 默认把所有连接异常都记在这里,关键信息就三样:
- 错误类型,比如
PDOException(数据库)、RedisException(Redis)、GuzzleHttp\Exception\ConnectException(HTTP) - 报错文件和行号,比如
/app/Services/ApiClient.php:22 - 具体消息,例如
SQLSTATE[HY000] [2002] Connection refused或Failed to connect to redis:6379
如果日志里没报错,但页面卡住或返回 500,大概率是 PHP 自身超时(max_execution_time)或 Nginx/Apache 的 fastcgi_read_timeout 干预了,这时候要去看 Web 服务器日志,而不是 Laravel 日志。
确认 QUEUE_CONNECTION 和 retry_after 是否匹配
队列任务连接超时最常被忽略的点:配置项和实际驱动不一致。
- 若用 Redis 驱动,
retry_after必须 ≤ Redis 的 key 过期时间(默认 90 秒),否则任务可能在重试前就被 Redis 清掉 - 若用 database 驱动,
retry_after要大于任务最长执行时间,否则未完成就被标记为失败 -
QUEUE_CONNECTION=sync时不会触发任何连接超时——它根本不用连,但这也意味着延迟队列、重试、失败记录全失效
检查命令:php artisan queue:work --dry-run 可快速验证当前配置是否能正常初始化连接,不真正消费任务。
用 php artisan tinker 手动测底层连接
绕过框架封装,直连服务验证是不是环境问题:
- 数据库:
DB::connection()->getPdo();—— 报错说明 DB 配置或网络不通 - Redis:
Redis::connection()->ping();—— 返回+PONG才算通 - HTTP 客户端(如 Guzzle):
Http::timeout(5)->get('https://httpbin.org/delay/1');—— 显式设 timeout 避免被全局覆盖
注意:.env 中的 DB_HOST 写 localhost 在 Docker 环境下大概率失败,得换成宿主别名(如 host.docker.internal)或真实 IP。
区分「连接超时」和「读写超时」
很多“超时”其实不是连不上,而是连上了但等不到响应:
- MySQL 的
connect_timeout控制建连阶段,wait_timeout控制空闲连接断开时间 - Redis 的
timeout配置只影响客户端空闲断连,不影响命令执行等待 - Laravel 的
timeout参数(如queue:work --timeout=60)只限制单个任务执行时长,跟网络连接无关
所以看到 SQLSTATE[HY000]: General error: 2013 Lost connection,大概率是 wait_timeout 太小或中间网络中断,不是连不上。


















