news 2026/9/4 22:46:32

线程池导致的 shutdown失败的完整排查过程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
线程池导致的 shutdown失败的完整排查过程

SpringBoot 中有一种方式可以优雅地关闭应用程序。

(优雅停机是指关闭应用程序时,在规定的超时时间范围内,允许进行中的请求完成,拒绝新的请求进入。 这将使应用在请求处理方面保持一致,即没有未处理请求,每一个请求都被处理(完成或拒绝)

配置如下

yml server: port: 8888 shutdown: graceful management: endpoint: shutdown: enabled: true endpoints: web: exposure: include: shutdown
xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>

现象

直接调用 localhost:8888/actuator/shutdown 即可关闭应用程序。但是在调用某个业务后,再调用 shutdown 的 api,发现实际 shutdown 确实在执行,但是最终并没有把 pid 给 kill 掉,应用程序依然在运行。

第一怀疑就是认为这个程序执行后,还有什么资源没有被关闭掉,导致 springboot 认为应用程序还在运行,从而没有执行关闭操作。

排查过程

执行脚本

shell 生成线程快照 jstack -l pid > threads.txt # 查询非守护进程(因为非守护线程会阻止 JVM 退出) -v 表示反向排除 grep -n '" ' threads2.txt | grep -v daemon
  • 所有线程信息
  • 非守护线程信息

在里面发现了一段 关于 "pool-X-thread-Y"的线程信息,这个 ThreadPoolExecutor 出来的线程,处于等待中,其他的都是额外框架的线程信息或者 jvm 的,只有"pool-X-thread-Y"属于额外的。

less "pool-4-thread-1" #230 prio=5 os_prio=31 cpu=0.21ms elapsed=252.08s tid=0x00000001642cf800 nid=0x9a07 waiting on condition [0x000000017aaf6000] java.lang.Thread.State: WAITING (parking) at jdk.internal.misc.Unsafe.park(java.base@17.0.13/Native Method) - parking to wait for <0x0000000701e8af30> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(java.base@17.0.13/LockSupport.java:341) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@17.0.13/AbstractQueuedSynchronizer.java:506) at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@17.0.13/ForkJoinPool.java:3465) at java.util.concurrent.ForkJoinPool.managedBlock(java.base@17.0.13/ForkJoinPool.java:3436) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@17.0.13/AbstractQueuedSynchronizer.java:1630) at java.util.concurrent.ArrayBlockingQueue.take(java.base@17.0.13/ArrayBlockingQueue.java:420) at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@17.0.13/ThreadPoolExecutor.java:1062) at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@17.0.13/ThreadPoolExecutor.java:1122) at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@17.0.13/ThreadPoolExecutor.java:635) at java.lang.Thread.run(java.base@17.0.13/Thread.java:840) Locked ownable synchronizers: - None
  • ThreadPoolExecutor 默认线程名称源码

有了这个排查方向,去项目里面查找关于ThreadPoolExecutor的代码。

最终发现一句关于线程池的声明代码。从代码来看,虽然 XxxConfig 类上加了 @Configuration 注解,受到 spring 管理,但是 XXX_EXECUTOR 这个线程池是静态变量, 并没有受到 spring 管理,所以 springboot 在执行 shutdown 的时候,并不会关闭这个线程池,导致应用程序没有被关闭。

java @Configuration public class XxxConfig { public static final ThreadPoolExecutor XXX_EXECUTOR = new ThreadPoolExecutor(20, 20, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10000), new ThreadPoolExecutor.CallerRunsPolicy()); }

最终解决方案

建议将 XXX_EXECUTOR 这个线程池改为 spring 管理的 bean,如下所示:

java @Configuration public class XxxConfig { @Bean("xxxExecutor") public ThreadPoolExecutor xxxExecutor() { //示例 demo return new ThreadPoolExecutor(20, 20, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10000), new ThreadPoolExecutor.CallerRunsPolicy()); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/5 1:10:00

全基因组重测序上游分析流程--随笔15

全基因组重测序上游分析流程&#xff5c;从软件部署到变异检测&#xff0c;超细致实操指南 作为科研新手&#xff0c;第一次上手全基因组重测序数据处理时&#xff0c;我踩过不少软件安装的坑、碰过参数设置的雷。如今整理出这份超详细流程&#xff0c;从前期准备到最终变异过…

作者头像 李华
网站建设 2026/9/5 7:03:25

中间件开发与生命周期管理

目录中间件开发与生命周期管理1. 引言&#xff1a;中间件的重要性 {#引言}2. 中间件的基本概念与原理 {#基本概念}2.1 中间件的定义与分类2.2 中间件的核心特征3. 中间件的生命周期模型 {#生命周期模型}3.1 生命周期的五个阶段3.2 状态转移矩阵3.3 生命周期时长模型4. 中间件开…

作者头像 李华
网站建设 2026/9/4 2:46:21

2026大专建筑工程必看!这些证书让你找工作不踩雷!

各位建工专业的同学们&#xff0c;2026年的建筑行业正在经历深刻转型。“大干快上”的时代过去了&#xff0c;现在是拼技术、拼管理、拼合规的时代。作为大专生&#xff0c;我们学历上不占优&#xff0c;但恰恰可以通过实操技能和专业证书&#xff0c;在施工现场打出一片天。今…

作者头像 李华
网站建设 2026/9/4 4:50:53

《UGC工具的能力梯度解锁指南》

很多产品陷入“功能越多越强大”的误区,却忽略了用户在碎片化场景下的核心诉求—当一位博主在通勤途中想用手机编辑图文时,过多的排版选项会成为认知负担,而过于简化的功能又无法满足专业表达需求。这就需要建立“感知负荷拆解模型”,将复杂功能拆解为“基础必选”“进阶可…

作者头像 李华
网站建设 2026/9/3 5:47:31

【算法题】滑动窗口(一)

滑动窗口是处理子串/子数组问题的经典双指针技巧&#xff0c;核心是通过维护一个“窗口”&#xff08;左右指针界定的区间&#xff09;&#xff0c;动态调整窗口范围来满足题目条件&#xff0c;从而高效求解问题。 一、无重复字符的最长子串 题目描述&#xff1a; 给定一个字符…

作者头像 李华
网站建设 2026/9/4 5:45:22

Office Tool Plus v10.29.50 office安装激活一条龙

&#x1f51e;简介:Office Tool Plus是一款相当牛逼的office安装工具&#xff0c;并且安装完了顺带激活&#xff0c;也可以很快捷的卸载office清除激活信息等等。下载最新的office2016免去那么多的麻烦&#xff0c;反方便~【下载地址】&#xff1a;链接&#xff1a;https://dri…

作者头像 李华