运维知识
悠悠
2026年7月28日

凌晨3点被502叫醒后,我把排查全流程写成了手册

睡梦中手机震个不停,迷迷糊糊摸过来一看,好家伙,告警群里已经炸了:核心业务接口大面积502,客服那边电话快被打爆了。

我盯着天花板愣了两秒,然后爬起来开电脑,远程连上跳板机那一刻,说实话手都是抖的。这种场景做运维的应该都不陌生吧?大晚上被叫起来,脑子还没转过弯来,屏幕上全是红色告警,脑子里只有一个念头:这锅今天是不是得我来背?

后来那次故障复盘会上,领导问我一个问题:502到底是怎么来的?你下次能不能10分钟之内定位清楚?

我当时没敢接话。但事后我花了整整一周时间,把502的所有可能场景、排查路径、命令清单、根因分类全部整理了一遍。今天这篇文章,就是我整理出来的成果。

不敢说100%覆盖,但生产环境里能踩的坑,基本都在里面了。你要是看完能少熬两个夜,少背几次锅,这文章就没白写。

502到底是个什么东西

在开干之前,得先搞清楚502到底是什么,不然排查的时候就是瞎子摸象。

502的全称是Bad Gateway,翻成人话就是:网关或者代理服务器在往上游拿数据的时候,没拿到,或者拿到的东西不对,于是就给你返回了一个502。

这句话听起来简单,但里面的信息量很大。

第一个关键词:网关。也就是说502基本不会出现在直连后端的场景里,它一定是有中间层的情况下才会出现。Nginx、Apache、Haproxy、SLB、CDN、F5这些都是常见的网关。

第二个关键词:上游。502是网关在告诉客户端:我没拿到上游的正常响应。至于是没连上、超时了、还是上游给我返回了一个乱七八糟的东西,那就是后面要具体排查的内容了。

所以你记住一句话:502的锅,永远不在用户和网关之间,一定是网关到上游这段路出了问题。

这也是为什么很多新手排查502的时候,一上来就去看后端服务的日志,看半天发现服务其实跑得好好的,于是就懵了——其实方向就不对。

排查前的三件准备工作

讲具体排查步骤之前,先说几个准备工作,这几个步骤能帮你少走一半弯路。

第一,先确认影响范围。

是所有接口都502,还是只有部分接口?是所有用户都中招,还是只有某个地区、某个运营商的用户?

这个信息决定了你是S级故障还是A级故障,也决定了你需要叫多少人起来一起干。

我之前就吃过亏,大半夜一看到告警就埋头排查,结果搞了半天才发现是某个边缘节点的局部问题,影响范围非常小,但当时我慌得一批,根本没先评估范围。

第二,先抓现场。

故障窗口期是金贵的,你排查过程中产生的所有数据,最好都保留下来。日志、监控截图、网络包、命令输出,能留的都留。

为啥?因为等你查完已经天亮了,领导问你"你确定是这个问题?"的时候,你得有东西给他看。空口无凭的故障复盘,谁都不会买账。

第三,先沟通。

发现故障的第一时间,别自己一个人闷头干。在群里吼一声,说"现在线上有502问题,正在排查,影响范围XXX",这个动作比排查本身还重要。

沟通到位了,出了问题大家一起扛;沟通不到位,最后就是你的锅。这不是甩锅,这是基本的职业素养。

好,准备工作说完,进入正餐。

Nginx返回502的几种典型场景

生产环境里502最多的场景,还是Nginx作为反向代理的时候。所以我重点讲这块。

Nginx的error.log是排查502的第一现场,基本所有502的原因都能在这个日志里找到蛛丝马迹。

所以排查的第一步,永远是去看Nginx的error.log。

一般路径是 /var/log/nginx/error.log,tail一下最近的错误,基本就能看出个大概。

下面是我这些年遇到的高频错误形态。

connect() failed (111: Connection refused)

这种错误的意思是:Nginx去连上游的时候,连接被拒了。

翻译成普通话就是:上游服务根本没在监听那个端口,或者服务挂了。

排查思路很直接:

  • 上游服务是不是活着?直接curl一下上游的IP+端口,看能不能连上
  • 上游服务的端口是不是变了?有时候发版的时候改了端口,Nginx配置没同步
  • 上游服务是不是只监听了127.0.0.1?这种情况下外部根本连不进去

我之前有个项目,后端用的是Spring Boot,默认配置下服务只监听127.0.0.1,本地测试一切正常,一上线就502。后来排查了半天,定位到是这个原因,加上server.address配置才解决。

这种情况其实挺常见的,尤其是开发环境和生产环境配置不一致的时候,特别容易出这种幺蛾子。

connect() failed (110: Connection timed out)

这个比Connection refused更恶心,因为它意味着连接请求发出去之后,对方一直没回应,直到超时。

这种情况一般是网络层面的问题,比如:

  • 上游服务器宕机或者网络断了
  • 防火墙拦截了请求
  • 安全组规则没放行
  • 上游服务卡死了,没法accept新连接

排查这种问题的时候,telnet是最直接的工具。

telnet 上游IP 上游端口

要是telnet都连不上,基本可以确认是网络问题。这时候你要做的事情是:

  • 在Nginx所在的机器上ping一下上游IP
  • traceroute一下看路由路径
  • 检查iptables规则
  • 检查云上的安全组配置

有一回我遇到一个特别坑爹的情况:上游服务器明明在跑,本地telnet也能通,但Nginx就是连不上。最后查出来是两台机器之间的MTU不一致,大的包被丢了。改完MTU立马就好了。

这种问题排查起来特别费时间,因为从表面看一切正常,但就是不通。

upstream prematurely closed connection

这个错误的意思是:Nginx刚和上游建立连接,上游就主动把连接关了,连响应都没给。

这种场景的根因基本都在上游服务,比如:

  • 上游服务crash了
  • 上游服务的worker被kill了
  • 上游服务处理请求太慢,超过了Nginx的超时时间
  • 上游服务在做优雅停机

这种问题光看Nginx的日志是不行的,必须配合上游服务的日志一起看。

我的习惯是定位到上游机器之后,tail -f 应用日志,同时在Nginx那边复现请求,然后两边对照着看。

有一次遇到一个诡异的问题:上游是Java应用,每次Nginx打过来的请求处理到一半就被中断了,Nginx报prematurely closed。查了两天才发现是JVM的某个参数配错了,导致Socket被异常关闭。

504 Gateway Time-out

虽然这个错误码是504不是502,但很多同学会混淆,而且它们的排查思路其实是相通的,所以也放在一起讲。

504的意思是:Nginx和上游建立了连接,但上游在规定时间内没返回响应。

这种场景基本都是上游服务处理能力的问题。

排查思路:

  • 看上游服务的QPS、RT、错误率
  • 看上游服务的CPU、内存、线程数
  • 看上游是否有慢SQL、死锁、FullGC等情况
  • 看上游依赖的下游服务是否正常

我处理过的最典型的一次504,是数据库出现了一条慢SQL,单条查询要跑30秒,拖垮了整个服务池。这种情况下Nginx报错,后端服务看起来也没崩,但请求就是处理不过来。

经验之谈:遇到504的时候,不要只盯着Nginx的timeout配置调大,调大只是掩盖问题,根因还在上游。

no live upstreams

这个错误比较少见,但遇到了就很头疼。它的意思是Nginx配置的upstream组里,所有服务器都被标记为不可用了。

这种情况一般是健康检查配置有问题,或者上游真的全挂了。

排查思路:

  • 检查upstream配置里有没有启用健康检查
  • 看健康检查的阈值配得是否合理
  • 手动测试upstream里的每台机器是否都还活着

我之前有个项目,配了比较激进的健康检查策略,结果服务稍微一抖动就被标记为不可用,后来调整了阈值才好。

SSL握手失败

如果你的Nginx是HTTPS的,上游也是HTTPS的,那中间还有个SSL握手的过程。SSL握手失败也会导致502。

这种场景的错误日志一般是SSL_do_handshake() failed之类的。

排查思路:

  • 检查证书是否过期
  • 检查证书链是否完整
  • 检查SSL协议版本和加密套件是否兼容
  • 检查上游是否要求客户端证书

生产环境里证书过期导致的502,简直是运维的噩梦。尤其是Let's Encrypt的免费证书,90天就要续期一次,没自动化的话很容易忘记。

Nginx自身资源耗尽

还有一种容易被忽略的情况:Nginx自己扛不住了。

Nginx的worker_connections是有上限的,默认是1024。要是连接数打满了,新的请求就处理不了,表现出来也可能是502。

排查命令:

# 查看Nginx当前的连接数
ss -n | grep :80 | wc -l
# 查看Nginx的worker进程状态
ps aux | grep nginx

这种情况一般是遭受了CC攻击,或者上游回包太慢导致大量连接被占用。

完整排查路径图

上面讲的是单点场景,现在串起来讲一个完整的排查流程。

第一步:看监控,确认影响范围和持续时间

Grafana、Zabbix、Prometheus都行,先看一下:

  • 502的QPS和占比
  • 影响的接口范围
  • 故障开始的时间点
  • 是否有发布、配置变更、网络调整等动作同步发生

第二步:看Nginx错误日志

tail -f error.log,观察错误的具体形态。这一步至关重要,能帮你快速定位到是上面几种场景里的哪一种。

第三步:测试上游连通性

从Nginx机器上直接curl上游:

curl -v http://上游IP:端口/health

注意要用-v参数,能看到详细的连接过程。这一步能验证最基本的网络连通性。

第四步:检查上游服务状态

  • 进程是否在跑
  • 端口是否在监听
  • 资源使用情况
  • 应用日志有没有异常

第五步:缩小问题范围

根据前三步的结果,基本能定位到是网络问题、上游服务问题、还是Nginx配置问题。然后针对性地深入排查。

第六步:根因定位 + 临时止血

找到根因之后,先做临时止血,比如重启服务、回滚配置、切流量。然后再彻底解决。

第七步:事后复盘

故障恢复之后,写复盘文档,把时间线、根因、改进措施都写清楚。

几个真实案例

案例一:某天晚上业务高峰期突然大量502

那次的error.log显示是connect() failed (110: Connection timed out)。

我第一反应是上游挂了,结果telnet测试一切正常。继续查,发现是云厂商的负载均衡SLB和后端服务器之间的健康检查出了问题,SLB认为后端不健康,所以把流量都打到了同一台机器上,那台机器扛不住就超时了。

解决方法:在SLB上调整健康检查的阈值,并且增加后端机器数量。

案例二:发版之后部分接口502,部分正常

这种就很典型了,肯定是发布相关的问题。

我查了一下Nginx配置,果然是上游upstream的地址没改,新的服务在新的端口,Nginx还在打老端口。

教训:发布流程里一定要有Nginx配置同步这个环节,最好做配置变更的自动化检查。

案例三:CDN回源502

CDN回源502的排查和直接Nginx的502类似,但要更复杂一些,因为中间多了CDN这一层。

排查思路:

  • 先确认是不是全网502,还是只有某些节点
  • 通过修改hosts的方式直连源站测试
  • 查看CDN的回源配置

CDN的问题很多时候是回源Host配置不对,或者源站有针对CDN的特殊限制(比如限流、白名单)。

502排查的避坑清单

聊几个我踩过的坑,新司机认真看。

不要只看Nginx的配置不看上游。很多时候问题真的不在Nginx,在上游。

不要忽略keepalive配置。Nginx和上游之间的长连接配置不当,会导致大量连接重建,性能急剧下降。

不要在生产环境直接改配置再reload。一定要在测试环境验证通过。

不要忽略时间点的对齐。把监控时间点、Nginx日志时间点、上游日志时间点对齐到秒,往往能发现一些隐藏的关联。

不要只查HTTP状态码。要看完整的请求和响应,包括header、body,这些信息对定位问题非常关键。

502的预防比排查更重要

写到最后,说点预防的事情,因为最好的故障处理就是不让它发生。

做好健康检查。Nginx自带的健康检查比较弱,建议用Tengine或者自己写脚本来做主动健康检查。

做好超时配置。connect_timeout、send_timeout、read_timeout这些参数要根据业务特点合理设置,不要照搬默认值。

做好监控告警。502的错误率一定要有监控,阈值要合理,既不能太敏感导致告警风暴,也不能太迟钝导致故障扩散。

做好容量评估。定期做压测,了解系统的极限在哪里,提前扩容或者优化。

做好变更管理。所有的配置变更、发布操作都要有记录,有回滚方案,有审批流程。

做好预案。针对502这类常见故障,要有标准化的处理流程,新人来了也能照着做。

写在最后

做运维这几年,最大的感受就是:故障是不可避免的,但好的运维能让故障的影响降到最低。

502这个错误码看着简单,背后牵扯到的东西可不少。网络、服务、配置、架构,任何一个环节出问题都可能导致它。

但只要你按照一个标准化的流程去排查,有完整的工具链和监控体系支持,定位它其实并不难。

我今天写的这些,都是我这些年线上实战踩过的坑、走过的弯路。有一些看起来很基础,但恰恰是这些基础的东西,在关键时刻能救你一命。

建议你把这篇文章收藏起来,下次遇到502的时候拿出来对照着排查。说不定能帮你省下一个通宵。


如果觉得这篇内容对你有帮助,记得点个在看,转发给你身边做运维的朋友。关注公众号「耕云躬行录」,后台回复"502",可以领取我整理的《502排查命令清单》和《线上故障应急手册》PDF。

我的个人博客上也会有更多运维实战的干货内容,地址放这里了:躬行笔记,欢迎常来逛逛。

咱们下一篇接着聊线上故障那些事,不见不散。

文章目录

博主介绍

热爱技术的云计算运维工程师,Python全栈工程师,分享开发经验与生活感悟。
欢迎关注我的微信公众号@运维躬行录,领取海量学习资料

微信二维码