半夜收到监控告警,打开网站一片 502 Bad Gateway。很多人的第一反应是重启服务器,运气好恢复了,运气不好过一小时又来。502 的本质就一句话:Nginx 活着,但后面的 PHP-FPM 或者上游服务没应答或拒绝连接。顺着这条链路查,比乱重启快得多。
第一步看 PHP-FPM 进程在不在。
ps aux | grep php-fpm
systemctl status php-fpm
# 看监听端口/套接字是否一致
ss -lntp | grep 9000
第二步核对 Nginx 的 fastcgi_pass 和 PHP-FPM 的 listen 是否一致。一个写 127.0.0.1:9000,另一个配的是 unix 套接字,或者反过来,这种低级错误在生产环境出现的频率高得吓人。改任意一边,两边统一就行。
第三步查资源。502 最常见的深层原因是 php-fpm 进程全被占满:并发上来或者某个脚本死循环,把 pm.max_children 个进程全吃了,新请求排队超时。看日志最直接。
tail -100 /var/log/php-fpm/error.log
tail -100 /var/log/nginx/error.log
# 找这类关键字
# [pool www] seems busy (you may need to increase pm.max_children)
# connect() to unix:/run/php-fpm.sock failed (11: Resource temporarily unavailable)
确认是进程池满了,临时救火先重启 php-fpm 释放进程,然后算一下该开多少个子进程:每个 php-fpm 进程平均占用内存(用 ps 看 RSS)乘以进程数,别超过机器内存的七成。比如单个进程 60MB、机器 4GB,max_children 设 45 左右比较稳。
504 Gateway Timeout 是另一回事:进程活着但脚本跑太慢。这时候要抓的是慢日志,把 request_slowlog_timeout 打开,能直接看到卡在哪个文件哪一行。502 查连接、504 查耗时,先分清这两兄弟,排查方向就不会错。
数据来源:Nginx官方文档 ngx_http_proxy_module 错误处理指令
A5创业网 版权所有