You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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指标也未发现资源使用率异常:
Tomcat线程使用率
请求大小
其中红线对应503错误发生时刻。

请问最佳调试方案是什么?是否可能遗漏了Tomcat日志?该问题是否由Envoy导致?


调试方案与问题分析

一、排查Tomcat日志遗漏点

  • 针对性开启Tomcat核心组件日志:仅开启root=debug会产生大量冗余日志,可单独配置Tomcat连接器、核心模块的日志级别,在application.properties中添加:
    logging.level.org.apache.coyote=DEBUG
    logging.level.org.apache.tomcat=DEBUG
    logging.level.org.apache.catalina=DEBUG
    
    这类日志会记录连接建立、终止、请求接收的全流程细节,能捕捉到Tomcat主动/被动关闭连接的场景,而这些信息不会出现在常规业务日志中。
  • 启用Tomcat访问日志:内嵌Tomcat默认未开启访问日志,需手动配置。可通过Spring Boot配置类实现:
    @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);
            };
        }
    }
    
    访问日志会记录所有到达Tomcat的请求,包括那些未进入业务代码就被终止的请求,这很可能是当前缺失的关键线索。
  • 补充JVM层面日志:虽然JMX指标显示资源正常,但偶尔的GC停顿或线程阻塞可能导致连接超时终止。在服务启动参数中添加GC日志配置:
    -Xlog:gc*:file=/var/log/gc.log:time,level,tags
    
    同时在503发生时,立即触发线程dump(jstack <PID>),检查是否存在线程异常阻塞的情况。

二、排查Envoy/Emissary侧问题

  • 分析Envoy日志与核心配置:UC标识虽指向上游连接终止,但也可能是Envoy侧的超时或健康检查逻辑导致。
    • 检查Envoy的connect_timeout、request_timeout配置,确认是否存在超时时间过短,导致Envoy主动断开连接的情况。
    • 临时启用Envoy的debug级日志(log_level: debug),重点关注上游连接建立、终止的日志条目,判断是否是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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 13:46:11