问题起因:
由于在生产环境误判了某个高峰时间段下的接口并发量,本以为只有一分钟并发几百的量,就设置了自定义线程池的阻塞队列为100,而真实并发量在高峰时段时达到了分钟近1-2k的并发量,每秒均10-20的请求,导致线程池阻塞队列溢出,而此时线程池的设置的拒绝策略是返回调用方执行,变成了主线程去执行,而这个接口有点耗时,导致tomcat的主线程一直不被是否,后续进来的请求都没有空余的线程去处理,导致客户端timeout
排查思路:
由于生产环境在某个高峰时间段,突然出现大量的告警,很多请求已经请求不进服务器了,全部报的timeout,从此推测出应该是刚发版的线程池问题,这里发版前设置的阻塞队列设置的比较小,当异步线程池被打满的时候请求就会返回给调用方线程执行了,从而占用了tomcat的主线程,而这个接口执行也有一点耗时,导致某个高峰时段下tomcat线程池的线程全部被创建完且被一直占用着,后续的请求再请求进来都是被丢到了等待队列中等待执行,而客户端就收到了timeout,根本原因就是本来异步削峰处理的逻辑全部变成了同步执行了。
解决方案:
1、合理配置线程池的配置参数,阻塞队列设置的大一点,根据实际业务场景配置
2、进一步的优化方案是:将异步线程池更换成MQ消息中间件进行异步化,增加接口的吞吐量