Laravel在Vagrant运行时突发SQLSTATE[HY000][2002]连接拒绝故障
核心判定依据:当前Sequel Ace外部连接正常、CLI下migration执行正常,仅Web请求抛出SQLSTATE[HY000] [2002] Connection refused错误,说明MySQL服务本身运行无异常,故障点集中在Web运行时(PHP-FPM)与CLI环境的差异上,无需修改业务配置文件,按以下顺序排查即可:
第一步:验证PHP-FPM运行状态与配置差异
Homestead环境默认使用Nginx+PHP-FPM处理Web请求,与CLI模式的PHP是独立进程、独立加载配置。- 执行命令查看FPM服务状态,确认无异常崩溃、重启循环:
systemctl status php*-fpm - 在Web根目录新建临时探针文件
phpinfo.php,内容为<?php phpinfo();,访问该文件记录pdo_mysql.default_socket配置值;再在CLI下执行php -i | grep pdo_mysql.default_socket,对比两者的socket路径是否一致。如果FPM读取的socket路径与MySQL实际生成的socket文件不匹配,就会触发连接拒绝。 - 执行
ls -l /run/mysqld/mysqld.sock查看MySQL socket文件的权限,确认PHP-FPM运行身份(Homestead默认为vagrant用户)有该文件的读写权限,部分场景下MySQL异常重启会导致socket文件权限重置。
- 执行命令查看FPM服务状态,确认无异常崩溃、重启循环:
第二步:清理Laravel运行时缓存
环境已稳定运行3个月且故障为突发,大概率是运行时缓存异常导致Web请求读取了错误的数据库连接参数——CLI下执行migration会直接读取最新的.env文件,但PHP-FPM会优先加载已生成的配置缓存,两者读取的参数不一致就会出现CLI能连、Web不能连的情况。
到项目根目录执行以下命令清理缓存,全程不需要修改任何配置文件:php artisan config:clear php artisan cache:clear php artisan route:clear清理完成后重载PHP-FPM让配置生效:
systemctl reload php*-fpm第三步:核对MySQL监听地址与连接方式
执行命令查看MySQL实际监听的端口与地址:ss -tulpn | grep mysqld- 如果返回结果仅显示监听
127.0.0.1:3306,说明TCP连接正常,重点排查socket连接权限问题即可; - 注意Sequel Ace能连接是因为Vagrant做了端口转发,走宿主机到虚拟机的TCP通道,和本地Web请求走socket的路径完全不同,不能作为本地socket正常的依据。
- 如果返回结果仅显示监听
第四步:最小化验证连接逻辑
不需要修改业务代码,临时在路由文件加一段测试路由,跳过Laravel的数据库封装直接用PDO发起连接,定位是否为框架层缓存导致的问题:Route::get('/db-check', function () { try { $pdo = new PDO( 'mysql:host=127.0.0.1;port=3306;dbname=替换为你的数据库名', '替换为你的数据库用户名', '替换为你的数据库密码' ); dd('连接成功', $pdo->query('SELECT VERSION()')->fetch()); } catch (PDOException $e) { dd('连接失败', $e->getMessage()); } });访问
/db-check如果返回连接成功,可100%确定是Laravel运行时缓存或环境变量加载异常导致的故障,清理缓存重载FPM即可修复;如果仍然连接拒绝,再检查本地防火墙规则(执行ufw status确认未拦截本地回环请求)。
补充:提供的内存、CPU监控数据显示资源剩余充足,可排除资源不足导致的进程异常退出问题;重启Vagrant无效也说明不是临时进程状态错乱,重点排查上述FPM与CLI的环境差异即可。
内容的提问来源于stack exchange,提问作者Tom Bom

