• restTemplate超时时间引发的生产事故


    1、现象:

      今天下午公司客户群里突然报警,说订单没有推送服务商,经排查发现是rabbitmq堵住了,查询elk和监控没有发现业务异常或超时日志。

      通过rabbitmq后面发现一个队列有异常,队列不ack,未消费数量一直增长,怀疑服务假死,只能保留现场,重启服务,下面是服务重启前后队列截图

    2、分析

      为什么服务重启后队列立马消费一空,证明三方服务商的接口没有问题,经过代码查找发现调用三方用的是restTemplate,核心代码如下:

     1 @Service
     2 public class OrderStatusChangePushService {
     3     private static Logger logger = LoggerFactory.getLogger(OrderStatusChangePushService.class);
     4     @Autowired
     5     private RestTemplate restTemplate;
     6     
     7     public ResponseEntity<PlatformBaseResponse> notify2Thirdparty(OrderInfoReqs orderInfo, String callbackUrl, AssortmentOpenApiEncryptDto encryptConfig, String operateType) {
     8         PlatformBaseRequest request = getRequest(orderInfo, encryptConfig, operateType);
     9         HttpHeaders headers = new HttpHeaders();
    10         headers.setContentType(MediaType.APPLICATION_JSON);
    11         HttpEntity<PlatformBaseRequest> platformBaseRequestHttpEntity = new HttpEntity<>(request, headers);
    12         ResponseEntity<PlatformBaseResponse> exchange = null;
    13         exchange = restTemplate.exchange(callbackUrl, HttpMethod.POST, platformBaseRequestHttpEntity, PlatformBaseResponse.class);
    14         return exchange;
    15     }
    16 }
     1 @SpringBootApplication
     2 public class PlatformOrderConsumerApplication extends SpringBootServletInitializer {
     3     @Bean
     4     RestTemplate restTemplate() {
     5         return new RestTemplate();
     6     }
     7 
     8     public static void main(String[] args) {
     9         SpringApplication.run(PlatformOrderConsumerApplication.class, args);
    10     }
    11 }

    发现restTemplate用的是直接new的,未重写连接池也未设置超时时间。看源码得知底层用的jdk的httpurlconnection,若readTimeOut和connectionTimeOut没有设置,那请求是没有超时时间的,导致请求一直hang住。

     

     3、结论

      restTemplate没有设置超时时间,导致单挑消息不能ack,hang住了整个队列(因为业务需求,一个队列只能单线程消费)

        restTemplate如果没有重写连接池,默认用的SimpleClientHttpRequestFactory,SimpleClientHttpRequestFactory默认的readTimeOut=-1,connectionTimeOut=-1, 导致jdk的HttpUrlConnection是不会超时,进而hang死整个队列

  • 相关阅读:
    316 Remove Duplicate Letters 去除重复字母
    315 Count of Smaller Numbers After Self 计算右侧小于当前元素的个数
    313 Super Ugly Number 超级丑数
    312 Burst Balloons 戳气球
    309 Best Time to Buy and Sell Stock with Cooldown 买股票的最佳时间含冷冻期
    Java 类成员的初始化顺序
    JavaScript 全局
    HTML字符实体
    Java中的toString()方法
    JavaScript 弹窗
  • 原文地址:https://www.cnblogs.com/housh/p/12811326.html
Copyright © 2020-2023  润新知