Skip to content

Connection pool shut down

连接池关闭问题

问题描述

业务部门同事反馈,【全部客户】菜单中的企业标签无法打开。

企微的渠道活码也失效了, 无法正常返回欢迎语。

问题排除

查看API接口,根据traceId,查看APM调用情况

bash
scrm/marketing/weworkTagList
json
{
    "code": 500,
    "msg": "服务器异常,请稍后再试",
    "traceId": "b0a0d3e08960a696bf1ef02a18e78ed9",
    "serverTime": 1720590691961,
    "data": null
}

通过APM查看调用链路

image-20240710144839514

进一步查看调用堆栈信息,发现是

org.apache.http.impl.conn.PoolingHttpClientConnectionManager.requestConnection 获取链接失败了。

image-20240710144957018

根据业务判断,肯定不是当前方法调用频繁导致连接池停机,需要定位是哪个方法占用了过多的连接。

我们使用阿里巴巴开源的线上诊断工具 Arthas

官方文档 https://arthas.aliyun.com/

bash
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

这里我们使用 stack 命令,来查看方法被调用的路径

bash
stack org.apache.http.impl.conn.PoolingHttpClientConnectionManager requestConnection

成功定位到频繁调用的源头,询问相关同事,发现该业务是 定时同步 客户接替状态的,可以不用这么频繁执行。

image-20240710145537320

解决方案

方案一

修改定时任务,调整为每小时执行一次即可。

java
/**
 * 查询客户接替状态
 */
@Scheduled(cron = "0 3 * * * ?")
public void transferResult() {
    String date = DateUtils.format(new Date(),DateUtils.DATE_PATTERN);
    log.info("开始定时调度(查询客户接替状态):date={}",date);
    cpSysExternalContactPoolService.transferResult();
}

方案二

修改连接池,使用性能更高的 OKhttp实现,这里因为时间比较紧,官方没有提供现成的OKhttp实现,所以暂时不考虑这个方案。

人生感悟