RestTemplate未使用线程池问题

1. 问题描述:

现场出现springboot服务卡死,无法打开页面现象。

初步分析为服务中使用RestTemplate通信框架,但未使用连接池,如果通信抛出异常(连接失败),连续运行一定时间,导致线程飙升,资源耗尽,服务程序宕机。

2. 问题再现:

模拟无法通信的微服务地址,修改连接2s/次,启动三个微服务demo进行通信,连续测试2小时,现象可再现:

详细如下图:

  • 启动时线程数:

  • 连接异常提示:

  • 线程飙升:

  • 大量未关闭线程:

  • 线程dump信息:

"http-nio-8081-exec-120" #216 daemon prio=5 os_prio=0 tid=0x000000002b0f9800 nid=0x4a28 runnable [0x0000000030349000]

   java.lang.Thread.State: RUNNABLE

        at java.net.SocketInputStream.socketRead0(Native Method)

        at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)

    ……

        at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)

        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:737)

        at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:672)

        at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:313)

3. 问题分析:

        主动健康检查时,RestTemplate默认情况下不使用连接池,每次调用都会打开一个新的本地临时端口和一个新连接,如果通信异常,会导致连接不被回收,持续通信,它会不断新建线程,并且很快突破本地可用端口限制范围,导致服务卡死。

4. 解决方案:

        使用RestTemplate连接池,设置ReadTimeout、ConnectTimeout超时时间,进行连接回收。

5. 回归验证:

        修改后,验证如下:

  • 初始线程:

  • 测试3小时结束时线程:

  • 线程池线程未增加,状态交替

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值