当前位置: 首页 > news >正文

SpringBoot项目启动失败进程不结束问题

目录

1. 问题背景

2.问题分析

3.排查

3.1.查看线程堆栈

3.2.查看阻塞线程信息

3.3.定位到异常线程

3.4.定位到具体业务代码

3.5.解决

4.疑问


1. 问题背景

一个spring boot开发的项目,spring boot版本是2.7.13。其他同事定义的bean冲突了,导致项目启动失败,进程也不退出。

我这边是因为线程池问题导致的。

2.问题分析

正常来说,项目启动失败后,进程会直接退出。所以问题大概率是死锁、长时间等待外部资源(例如数据库连接、I/O操作)、线程池未关闭。

3.排查

3.1.查看线程堆栈

IDEA内置了一个工具,可以直接查看当前所有线程的堆栈信息,相当于jstack <pid> 命令。

3.2.查看阻塞线程信息

一个一个点击红色图标的线程,查看线程的具体情况。

标识有daemon的线程不需要过多关注,daemon 是一个线程的属性,它表示该线程是 守护线程。守护线程与普通线程的区别在于,当所有非守护线程(即普通线程)结束时,守护线程会自动结束,无论它是否执行完任务。

3.3.定位到异常线程

通过一个一个点击,我这边除了pool-15-thread是普通线程,其他都是守护线程,重点关注这个。

通过堆栈记录,基本上可以确定是因为线程池一直在执行导致的启动失败进程没有结束问题。

然后我在idea里全局搜索线程池相关的类ThreadPoolExecutor,发现项目中还是挺多的,无法确定具体是那个。堆栈记录也没有更详细的信息。

没办法,只能通过打断点了。

outerTask是正在执行的实际任务,通过这个可以看到具体的业务代码。

3.4.定位到具体业务代码

在这里发现创建了一个定时执行的线程,所以,启动失败该线程也不会结束。

3.5.解决

添加一个销毁钩子,spring容器删除的时候,该钩子就会被调用。在这个方法里,我们来手动关闭一下线程池。

4.疑问

可能大家会有疑问,我们项目也是这样使用的,并没有出现这种问题。

springboot 加载bean是有顺序的,我这边是先创建的线程,然后在加载其他bean的时候报错了。如果你们是先报的错,后面就不会创建线程池了,自然就没有这种问题。

相关文章:

  • 【Linux】【网络】frp 如何准确将 客户端B 请求转发给 服务器A 的
  • 高性能内存对象缓存Memcached详细实验操作
  • 搭建Kubernetes (K8s) 集群----Centos系统
  • RK3588配置成为路由器
  • 京东广告基于 Apache Doris 的冷热数据分层实践
  • 如何清理cache-loader生成的缓存目录?
  • 命令执行漏洞 Command Execute
  • 数据结构——字符串匹配KMP
  • Linux(ubuntu) GPU CUDA 构建Docker镜像
  • 【PyQt5】python可视化开发:PyQt5介绍,开发环境搭建快速入门
  • Linux-C/C++《C/8、系统信息与系统资源》
  • 抓包工具是什么?
  • 深入解析浏览器渲染全流程:从URL输入到页面渲染的底层原理与性能优化(附实战代码)
  • Memcached和redis对比了解
  • Python—requests模块
  • excel导入Mysql中时间格式异常
  • 深度学习笔记—— GRU(Gated Recurrent Unit)
  • 【设计模式精讲】创建型模式之单例模式(饿汉式、懒汉式、双重校验、静态内部类、枚举)
  • Node IO操作
  • 【阮一峰】2.数组
  • 做男装比较好的网站/网络营销推广主要做什么?
  • 大连专业app开发设计/网站优化排名提升
  • wordpress 群组插件/百度seo教程视频
  • 自适应网站好建们/贵阳百度推广电话
  • 凡客优品官方网站/seo短期培训班
  • 什么公司做网站的多/广告电话