AWS 服务报 502 错误排查结果

如下是8月18日 aws网关系统报错 502 Bad GateWay 问题定位、追踪、方案确认等:

一、现象:

周 6 下午 1 点 25 分左右系统报警 5xx 错误;

二、定位:排查过程

  • 查看ELB日志确认错误来源于(商户API:查询支付结果及创建跨境支付单);
  • 查询Pinpoint、Grafana及日志系统各项指标正常;

三、跟踪及分析:

查看ELB监控面板发现,502错误一直都存在,分布比较零散(大概的发生概率:万分之一(一万个请求约1次502错误)]);

  • 确认调用链路确认错误区域:商户 —> ELB —> 业务系统;通过ELB日志发现,商户 —> ELB链路正常,ELB到业务系统链路不正常。可参考:Troubleshoot Elastic Load Balancer HTTP 502 Bad Gateway Errors ,大致猜测可能请求还没有达到业务系统就已经502了(因此业务系统各项监控指标正常)

  • 验证猜想:ELB的TCP连接空闲存活时间60秒,业务系统Tomcat配置默认20秒,因此可能发生在极端的情况,业务系统关闭连接时,ELB刚好使用该连接,然后连接已关闭,ELB认为业务系统出现错误,包装错误:502 返回给调用方。

  • 实验组验证:(验证环境压测环境)

    第一组:ELB 60秒配置,Tomcat 存活时间配置1毫秒,200个并发请求,发现ELB监控502错误;
    第二组:ELB 60秒配置,Tomcat 存活时间配置70秒,200个并发请求,未发现ELB监控502错误;

该验证过程,确认了因为配置的原因导致了此次的502问题,进一步验证是否TCP连接在这种情况下关闭;通过抓取TCP包,发现的确关闭了连接,因此基本可以确认,是由于该问题导致。

四、结论及方案:

结论:502 Bad GateWay 基于AWS ELB的环境部署下,有两种错误可能性:

  • 配置问题(本次502报警问题):在Tomcat KeepAliveTimeOut的时间 < ELB的KeepAliveTimeOut时间,导致极端情况下的连接不可用,ELB 返回502错误码; 解决方案,确保:Tomcat KeepAlive的时间 >= ELB的KeepAlive时间,理论上可彻底消除。
  • 服务不可用或错误:常规的502问题是主要因为服务此刻存在问题导致,此类502无法一次性解决,因为每次发生的情况都可能不一致,并且此类问题,会引起业务监控指标异常,属于长期观察及逐case解决的,能做到的是预防和监控。

将发布收单服务,修改 TomcatKeepAliveTimeOut 参数为 70 秒,解决此次502的问题。

通过修改 Spring Boot 容器工厂 EmbeddedServletContainerFactory 来修改 TomcatKeepAliveTimeOut 参数。

TomcatConnectorConfig.java

@Configuration
@Slf4j
public class TomcatConnectorConfig {

    @Value("${tomcat.keep.alive.timeout:7000}")
    private int tomcatKeepAliveTimeout;

    @Bean
    public EmbeddedServletContainerFactory createEmbeddedServletContainerFactory() {
        TomcatEmbeddedServletContainerFactory tomcatFactory = new TomcatEmbeddedServletContainerFactory();
        tomcatFactory.addConnectorCustomizers(connector -> {
            ProtocolHandler protocolHandler = connector.getProtocolHandler();
            if (protocolHandler instanceof Http11NioProtocol) {
                Http11NioProtocol protocol = Http11NioProtocol.class.cast(protocolHandler);
                log.info("TomcatConnectorConfig.customize setKeepAliveTimeout begin");
                protocol.setKeepAliveTimeout(tomcatKeepAliveTimeout);
                log.info("TomcatConnectorConfig.customize setKeepAliveTimeout end");
            }
        });
        return tomcatFactory;
    }

}

你可能感兴趣的:(Q,&,A,Spring,Boot,&,Cloud)