添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

一次线上线程池任务问题处理历程

[作者简介] 王日华,小米信息技术部订单组研发工程师,目前主要负责小米订单中台业务。

一、前言

在一次新功能上线过程中,出现线程池提交任务抛出 RejectedExecutionException 异常,即任务提交执行了拒绝策略的操作。查看业务情况和线程池配置,发现并行执行的任务数是小于线程池最大线程数的,为此展开了一次线程池问题排查历程。

二、业务情景

2.1. 任务描述

每次执行一组任务,一组任务最多有 15 个,多线程执行,每个线程处理一个任务;每次执行完一组任务后,再执行下一组,不存在上一组的任务和下一组一起执行的情况。

2.2. 任务提交流程

2.3. 线程池配置

1
2
3
4
5
<bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="14"/>
<property name="maxPoolSize" value="30"/>
<property name="queueCapacity" value="1"/>
</bean>

三、出现问题

执行过程中出现 RejectedExecutionException 异常,由于是采用的是默认拒绝策略 AbortPolicy,因此,可以明确知道任务是提交到线程池后,线程池资源已满,导致任务被拒绝。

四、问题排查

4.1. 检查线程池配置

任务最多 15 个一组,核心线程有 14 个,阻塞队列是 1,最大线程 30,理论上 14 个核心线程+1 个阻塞队列即可完成一组任务,连非核心线程都无需使用,为什么会出现线程被占满的情况?

4.2. 检查业务代码

检查是否存在线程池被多处使用,或者有多批任务被同时执行的情况,并没有发现错误;

4.3. 线下重现