Kubernetes Ingress 报 502,从 upstream 超时查到连接复用
线上一个 Java 服务迁到 K8s 后,Ingress 偶发 502,后端 Pod 日志里却啥都没有。这类"网关报错、应用无感"的问题,八成不是应用代码,而是网关和上游之间的连接层。下面是我这次排查的完整顺序。
第一步,先分清 502 是谁给的。nginx-ingress 的 access log 里 502 有两种来源:一种是 upstream 连接建立失败(connect() failed),一种是上游提前关闭(upstream prematurely closed connection)。直接 grep 日志关键字,能立刻把方向砍一半。我们这次是后者。
第二步,看 upstream 超时配置。annotations 里有三个时间:proxy-connect-timeout、proxy-read-timeout、proxy-send-timeout,默认都是 60 秒。如果后端处理时间长又恰好复用了 keepalive 连接,网关可能在连接被上游主动关闭的瞬间把请求发进去,于是收到 RST。
第三步,确认连接复用。nginx 到 upstream 默认开 keepalive,但上游的连接空闲超时往往比 nginx 短。比如 Tomcat 默认 keepAliveTimeout 是 20 秒,nginx keepalive_timeout 是 60 秒,那么 20 到 60 秒之间的空闲连接在 nginx 看来还活着,实际已经半关闭。请求一打进去就 502。
解法有两条:要么把 nginx 侧 keepalive_timeout 调到比上游小,要么在 upstream 块里显式关闭长连接复用。我们是把 nginx 的 keepalive_timeout 从 60 秒调到 15 秒,同时在上游加了 keepAliveTimeout=65 秒,让上游始终比网关长,502 立刻消失。
最后提醒一句:改完记得看 retry 配置。proxy-next-upstream 默认只对幂等请求重试,POST 请求默认不重试,所以如果业务是写接口,502 对用户就是硬失败,不能指望网关兜底。
- 点赞
- 收藏
- 关注作者
评论(0)