502 Bad Gateway这个报错,不少人都碰到过。页面展示网关错误提示。它和404不一样,404代表页面不存在,502代表服务器之间通信异常。简单来说,浏览器先连接网站前端服务器,前端服务器转发请求到后端应用服务器,前端长时间没有收到有效响应,或是收到无法解析的返回内容,就会向浏览器返回502。
这里提到的网关,就是转发请求的中间节点。最常见搭配是Nginx作为前端,后端运行PHP-FPM、Tomcat、Node.js或是Python应用。Nginx接收用户请求,后端程序负责业务处理。后端程序未启动、进程卡死、响应超时、程序崩溃,Nginx就返回502。负载均衡器或是CDN节点也有可能返回502,说明它和源站之间通信故障。

普通用户遇到502,可操作空间不多。优先刷新页面,很多时候只是后端服务重启,等待几秒就能恢复。更换浏览器或是切换手机流量重试,如果依旧返回502,问题基本出在网站服务端,不是本地网络问题。等待几分钟再次访问,持续报错只能联系网站管理员。不用重启路由器或是修改DNS,这类操作解决不了该问题。
如果你是站长或者运维人员,排查502的思路完全不同。第一步查看日志。Nginx的error.log一般会标注故障原因,例如upstream prematurely closed connection,connect() failed while connecting to upstream。这类日志代表Nginx无法连接后端,或是连接建立之后立刻断开。PHP-FPM日志通常存放于/var/log/php-fpm.log或是/var/log/php7.x-fpm.log,记录进程崩溃、超时、内存耗尽相关信息。
接着检查后端服务进程状态。执行systemctl status php-fpm或是ps aux | grep php-fpm查看进程是否运行。进程停止就启动服务,观察运行稳定性。启动之后立刻崩溃,大概率配置错误或是代码致命错误。PHP-FPM进程池参数设置过小,并发请求堆积,等待时长超过Nginx超时阈值,Nginx就返回502。可以适度调大pm.max_children,但要评估服务器内存容量,每个PHP进程都会占用内存,数值过高会拖垮整机。
超时参数也是常见诱因。Nginx配置proxy_read_timeout默认60秒,如果后端处理请求耗时70秒,Nginx等待超时断开连接,用户页面就出现502。调大超时参数只能临时缓解,根源还是后端处理速度慢,要优化代码或是数据库查询。数据库连接异常也会造成后端处理失败,最终抛出502。检查数据库运行状态,连接数是否打满,慢查询数量是否过高。
服务器资源耗尽也会触发报错。内存耗尽,系统触发OOM Killer杀掉PHP-FPM或者Java进程,Nginx立刻返回502。free -m查看内存,top监控CPU,df -h查看磁盘空间。磁盘占满,日志无法写入,会话不能保存,后端程序也会报错。SELinux或是防火墙偶尔拦截Nginx和后端本地通信,出现概率不算高,但修改配置之后可以优先检查。
云环境还多一层节点。前端部署负载均衡或是CDN,这类节点也会返回502。需要查看负载均衡健康检查是否标记后端异常,或是CDN回源访问源站超时。核对负载均衡日志和源站访问日志,确认请求能否到达后端。
502和500经常被混淆。500是后端程序自身处理出错,返回无效响应。502是前端网关没有获取后端有效响应。504代表前端等待后端超时。几种报错可能交替出现,后端程序崩溃时,Nginx可能返回502,也可能返回504,取决于故障节点。查看日志的时候注意区分。
修复故障之后不要马上清理日志。保留error.log和PHP-FPM日志一段时间,观察同类警告是否重复出现。大部分502不是突然爆发,前期日志就会持续出现连接超时、进程重启记录,只是没有查看日志。养成定期查看日志的习惯,比故障发生再搜索解决方案更高效。故障排查时优先读取日志末尾,错误信息一般就在最后几行。