Spring Boot(Tomcat)搭配Emissary/Envoy偶发503错误排查咨询
问题描述
我运行着使用内嵌Tomcat服务器的Spring Boot 3.1.0服务,前端部署了基于Envoy构建的Emissary-ingress作为API网关。整体运行正常,但偶尔(约每10万次请求出现1次)会出现503错误,不想仅通过重试解决,希望找到问题根源。
这些503错误均带有response_flag=UC,根据Envoy文档,该标识含义为:Upstream connection termination in addition to 503 response code.(上游连接终止且返回503响应码),因此推测问题出在Tomcat端,且多数(非全部)503错误来自同一客户。
然而,负责处理请求的上游Pod日志中未发现相关记录。已配置logging.level.root=info(手动设为debug时可看到Tomcat调试信息),同时查看Tomcat的JMX指标也未发现资源使用率异常:

其中红线对应503错误发生时刻。
请问最佳调试方案是什么?是否可能遗漏了Tomcat日志?该问题是否由Envoy导致?
调试方案与问题分析
一、排查Tomcat日志遗漏点
- 针对性开启Tomcat核心组件日志:仅开启
root=debug会产生大量冗余日志,可单独配置Tomcat连接器、核心模块的日志级别,在application.properties中添加:
这类日志会记录连接建立、终止、请求接收的全流程细节,能捕捉到Tomcat主动/被动关闭连接的场景,而这些信息不会出现在常规业务日志中。logging.level.org.apache.coyote=DEBUG logging.level.org.apache.tomcat=DEBUG logging.level.org.apache.catalina=DEBUG - 启用Tomcat访问日志:内嵌Tomcat默认未开启访问日志,需手动配置。可通过Spring Boot配置类实现:
访问日志会记录所有到达Tomcat的请求,包括那些未进入业务代码就被终止的请求,这很可能是当前缺失的关键线索。@Configuration public class TomcatAccessLogConfig { @Bean public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatAccessLogCustomizer() { return factory -> { AccessLogValve accessLogValve = new AccessLogValve(); accessLogValve.setPattern("%h %l %u %t \"%r\" %s %b %D %{X-Forwarded-For}i"); accessLogValve.setDirectory("/var/log/tomcat"); accessLogValve.setPrefix("access_log"); accessLogValve.setSuffix(".txt"); accessLogValve.setRotatable(true); factory.addEngineValves(accessLogValve); }; } } - 补充JVM层面日志:虽然JMX指标显示资源正常,但偶尔的GC停顿或线程阻塞可能导致连接超时终止。在服务启动参数中添加GC日志配置:
同时在503发生时,立即触发线程dump(-Xlog:gc*:file=/var/log/gc.log:time,level,tagsjstack <PID>),检查是否存在线程异常阻塞的情况。
二、排查Envoy/Emissary侧问题
- 分析Envoy日志与核心配置:
UC标识虽指向上游连接终止,但也可能是Envoy侧的超时或健康检查逻辑导致。- 检查Envoy的
connect_timeout、request_timeout配置,确认是否存在超时时间过短,导致Envoy主动断开连接的情况。 - 临时启用Envoy的debug级日志(
log_level: debug),重点关注上游连接建立、终止的日志条目,判断是否是Envoy主动发起的连接终止。
- 检查Envoy的
- 验证健康检查配置:Emissary-ingress的健康检查如果配置不合理(比如检查路径错误、超时时间过短、失败阈值过低),可能误判Tomcat服务不健康,进而返回503。确认健康检查的参数是否符合业务实际。
- 聚焦特定客户端请求:多数503来自同一客户,通过Envoy日志过滤该客户端的所有请求,分析其请求特征:是否请求体过大、请求频率异常、是否使用长连接且连接复用存在异常?
三、网络层深度排查
- 双向抓包分析:在Tomcat Pod和Envoy Pod上同时启动抓包(
tcpdump -i any port <服务端口> -w capture.pcap),在503发生后停止抓包,分析TCP连接的终止原因(是FIN包还是RST包),确定是哪一端主动关闭了连接。 - 检查Kubernetes网络配置:如果运行在K8s环境,确认是否存在网络策略限制导致连接被中断,或者Service的会话保持配置是否存在异常,引发连接复用问题。
四、核心疑问解答
- 是否遗漏了Tomcat日志? 是的。默认的业务日志(
root=info)不会记录未进入业务代码的连接终止事件,Tomcat的连接器日志、访问日志才是捕捉这类问题的关键,当前配置未覆盖这些日志源。 - 是否由Envoy导致? 可能性较低,但不能完全排除。
UC标识仅说明上游连接终止,Envoy多数情况下是被动返回503,但仍需排查其超时、健康检查配置是否存在不合理之处。
内容的提问来源于stack exchange,提问作者Taliebram
相关产品推荐
相关产品推荐

