线上接口偶发504,最难受的往往不是报错本身。
而是用户已经失败了,你去翻应用日志,却干干净净。
没有Exception。
没有500。
CPU只有30%左右。
Pod也没重启。
健康检查还是绿的。
更让人头疼的是,同一个接口过几分钟再请求一次,又正常了。
这时候很容易开始怀疑:
是不是Nginx?
是不是Ingress?
是不是K8s网络?
还是应用其实卡住了,只是没有留下错误日志?
如果再让 ChatGPT、Codex 直接看一句:
"接口偶尔504,帮我排查。"
它也只能从几十种可能性里猜。
这类问题真正有效的第一步不是改代码,而是先回答一个问题:
这次失败的请求,最后正常到达了哪一层?
一次真实请求可能经过:
Client
↓
Load Balancer
↓
Nginx / Ingress
↓
Service
↓
Application
↓
DB / Redis / 下游API
502、504只是最终表现。
真正的故障点,可能在这条链上的任何一层。
一、第一步先查:请求到底有没有进入应用
假设用户反馈:
21:13:42
GET /api/payment/query
504 Gateway Timeout
先用:
Request ID。
Trace ID。
接口路径。
发生时间。
去应用入口日志里查。
如果完全找不到这次请求:
说明它很可能压根没有真正进入应用。
排查重点就应该前移到:
Load Balancer。
Nginx。
Ingress。
Service Endpoint。
如果应用已经记录:
request received
却没有:
request completed
那范围又缩小了一步:
请求已经进来了,只是在应用内部或者下游调用过程中卡住。
所以502/504排查最重要的分叉就是:
请求到了应用,还是没到应用。
二、应用没收到请求,先看Nginx / Ingress日志
这一层最值得找的不是502这个数字,而是真正的错误描述。
例如:
upstream timed out
通常意味着:
请求已经转给上游服务,但迟迟没有拿到响应。
如果看到:
connect() failed
connection refused
更像是:
网关根本连不上后端。
这时候重点查:
Pod是否Ready。
Service Endpoint是否正常。
端口是否一致。
实例是否正好重启。
如果看到:
upstream prematurely closed connection
说明连接已经建立,但后端在响应完成前把连接断掉了。
这时候可以继续看:
应用是否OOM。
进程是否重启。
连接是否被提前关闭。
所以不要看到502就直接改业务逻辑。
先把Nginx / Ingress这一层真正说了什么看清楚。
三、502和504,排查重点并不一样
502更像是:
网关和上游通信异常。
常见方向包括:
连接被拒绝。
连接被重置。
后端实例重启。
上游返回异常。
而504更常见的是:
网关一直等,但等超时了。
比如:
proxy_read_timeout = 30s
应用某次实际处理了:
35s
那就会出现非常典型的情况:
用户第30秒已经收到504。
但应用第35秒才打印:
request completed successfully
于是你会看到:
应用说成功,用户却说失败。
这种时候问题就不是"接口有没有执行完",而是:
整条链路里的Timeout边界是否一致。
四、如果请求已经进入应用,别第一时间看CPU
很多人遇到504以后会先看:
CPU。
内存。
机器负载。
如果CPU只有30%,就觉得:
应用应该不忙。
但接口慢不一定是CPU问题。
线程可能一直在等:
数据库连接。
Redis。
线程池。
锁。
第三方接口。
内部微服务。
比如一次请求总耗时:
32s
真正拆开以后可能是:
业务计算 300ms
数据库 100ms
连接池等待 7s
下游API 24s
CPU当然不会高。
因为大部分时间都花在:
等待。
所以这时候应该让 ChatGPT、Codex 帮你拆:
这30秒到底消耗在哪一段?
五、有Trace,直接先看最长的Span
如果系统接了链路追踪,这类问题最好处理。
例如:
API Gateway 30.0s
└─ Order Service 29.8s
├─ DB 120ms
├─ Redis 25ms
└─ Payment API 28.9s
这时候根本不用继续猜。
真正瓶颈已经很明显:
Payment API接近29秒。
如果网关Timeout刚好是30秒,只要偶尔再慢一点,就会触发504。
所以遇到502/504,Trace最大的价值不是"看起来专业"。
而是把:
接口偶尔超时
直接缩小成:
某个具体Span偶尔超过阈值。
六、没有Trace,就给关键阶段打时间点
如果现在还没有完整Tracing,也可以先记录:
request_start
db_start
db_end
downstream_start
downstream_end
response_end
例如:
21:13:42.001 request_start
21:13:42.015 db_start
21:13:42.080 db_end
21:13:42.081 payment_start
21:14:12.192 payment_end
这时候已经足够排除:
数据库。
把方向直接指向:
下游支付服务。
这比一句:
request failed
有用得多。
七、连接池满了,也会表现成504
还有一种特别常见:
应用没挂。
数据库也没挂。
SQL单次执行甚至不慢。
但请求还是越来越慢。
最后发现:
大量线程都在等数据库连接。
例如:
业务并发 = 100
DB连接池 = 20
高峰期如果前20个连接又被慢请求占住,后面的请求只能排队。
这时候看SQL本身可能只花100ms。
但拿连接之前已经等了8秒。
所以排查时不能只看:
SQL执行时间。
还要看:
Connection Wait Time。
同理,线程池也一样。
线程池满了,任务排队。
应用日志未必报错。
用户却已经等到网关超时。
八、偶发几秒的502,要对齐Pod和发布事件
如果问题不是持续发生,而是:
偶尔几秒。
随后自动恢复。
那就要特别看:
Pod重启。
滚动发布。
Readiness变化。
Endpoint切换。
OOM。
比如:
10:02:11 pod-a terminating
10:02:12 request → pod-a
10:02:12 502
10:02:15 endpoint removed
这种问题平时看服务:
完全正常。
只有把502发生时间和:
Deployment事件。
Pod事件。
Endpoint变化。
对齐以后才容易发现。
所以"偶发"问题最怕只看当前状态。
九、Timeout配置一定要放在一起比较
真实系统里经常同时存在:
Client timeout 15s
LB timeout 30s
Ingress timeout 60s
Application timeout 20s
Downstream timeout 120s
这种配置很容易让故障表现变得混乱。
例如客户端15秒就放弃了。
应用却还在等下游120秒。
那用户已经失败,后端还在继续消耗资源。
更合理的方向通常是:
内部调用更早失败。
外层Timeout略大。
比如:
下游调用 3s
应用整体 5s
网关 8s
客户端 10s
具体数字要看业务,但核心是:
Timeout不能各配各的。
十、最快排查顺序,建议固定成这5步
以后再遇到502/504,可以直接按这个顺序:
第一步:确认请求有没有进入应用
看:
Access Log。
Request ID。
Trace ID。
第二步:查Nginx / Ingress错误
重点找:
upstream timed out
connection refused
connection reset
prematurely closed
第三步:拆应用耗时
查:
数据库。
连接池。
线程池。
锁。
Redis。
下游API。
第四步:对比所有Timeout
Client。
Gateway。
Ingress。
Application。
Downstream。
第五步:对齐基础设施事件
Pod重启。
滚动发布。
Endpoint变化。
OOM。
网络异常。
这5步走下来,大多数502/504问题都会从:
"完全不知道哪出问题"
缩小到:
"只剩一两个明确层次需要继续验证"。
十一、修完以后,怎么证明真的修好了?
假设最后发现:
下游接口偶尔28秒。
如果只是把:
timeout 30s
改成:
timeout 60s
不一定算真正解决。
这可能只是:
把错误推迟30秒。
修完以后至少再看:
502/504错误率。
接口P95 / P99。
连接池等待时间。
线程池Queue Size。
下游调用耗时。
高峰流量下是否还能复现。
真正要证明的是:
根因消失了,而不是报错暂时没出现。
十二、这种排查场景,Plus和Pro怎么判断?
如果你平时只是偶尔让 ChatGPT、Codex:
分析一次Nginx日志。
看几段Trace。
检查Timeout。
辅助定位一次线上问题。
这种任务通常比较短,调用也不连续。
Plus一般已经够用。
真正影响判断质量的,反而是你有没有把:
Request ID。
Ingress日志。
Trace。
连接池数据。
上下游耗时
这些Evidence准备完整。
如果你的日常工作已经变成:
一天连续排多个线上故障。
一次问题需要看大量日志和Trace。
同时要检查K8s、Nginx、数据库、Redis、下游服务。
还要让Codex继续修改代码、跑测试、做回归。
这种就不再是一次简单问答。
而是:
连续的工程工作流。
在这种高频、长任务、多轮验证场景下,Pro会更合适。
所以这里判断Plus还是Pro,不是看:
502/504这个问题难不难。
而是看:
你每天需要让 ChatGPT、Codex 连续处理多少真实工程任务。
偶发排查、短任务:
Plus通常够用。
高频线上排障、长任务、多轮验证已经成为日常:
再考虑Pro。
最后
线上502/504最让人难受的,往往不是"报错了"。
而是:
用户已经失败,应用却像什么都没发生一样。
这时候最忌讳的就是:
凭感觉从业务代码开始乱改。
更有效的方式是:
先确认请求有没有到应用。
再查网关。
再拆等待时间。
再比Timeout。
最后对齐Pod和基础设施事件。
所以以后再让 ChatGPT、Codex 排这类问题时,不要只问:
"为什么接口504?"
先问:
"这个失败请求,最后一次正常出现在哪一层?"
只要这一层确定下来,
原本非常模糊的502/504问题,通常就已经解决了一半。
持续分享 Codex、大模型开发与 AI 编程实战内容。
长期深度使用各类代码大模型,也整理了稳定的Plus/Pro会员订阅渠道,有需要可自取。