震惊,程序运行一半就不运行了

news/2024/10/6 3:38:41/文章来源:https://www.cnblogs.com/hichanglong/p/18285588

近期,我们的项目在生产环境中运行时频繁出现一个难以理解的Bug。这个问题颇为有趣,因此我决定在此记录下整个排查过程。

首先,让我模拟一下出问题的代码:

XController.java

@Resource
private XService xService;@GetMapping("/method1")
public void method1(){
System.out.println("a");
xService.method2();
}

 

XService.java

@Async
public void method2() {
System.out.println("b");
}

  

如上代码所示,逻辑相当简单。在Controller中的`method1`里,我们首先打印一个“a”,然后调用Service的`method2`,在`method2`中打印一个“b”。按照常理,每次调用`method1`都应该依次打印“a”和“b”。大多数人可能都会这样认为,也确信结果必然如此。然而,事实却是有时只打印了“a”,而没有打印“b”,并且没有任何异常日志。

这个现象超出了我们的认知,一时间让人感到困惑。程序为何运行一半就停止了?难道多年的认知要被推翻,全世界都错了吗?

仔细思考后,作为一个拥有多年CRUD经验的程序员,我认为问题应该还是出在我自己身上。那么,问题究竟在哪里呢?

通过对比常规代码与这段代码的区别,我发现这段代码唯一特殊的地方在于使用了`@Async`注解。另外,这部分代码近期才开始显现出问题,难道是其他地方的改动影响到了这里?

有两个排查方向:一是调查`@Async`的使用情况;二是检查近期的代码更改。

众所周知,`@Async`的作用是让系统在新的线程中执行`method2`。但为什么有时不执行呢?难道是系统没有开启新线程?或者是线程不够用了?通常情况下,`@Async`使用的是Spring默认的线程池,而这个线程池的大小几乎是无限的。我们系统的访问量并未达到这个级别。

会不会是`@Async`使用了其他的线程池?为了核实这一点,我查看了日志文件,发现在打印“a”的那行日志前面有线程名“myThread-1”。这个线程名显然是自定义的,并非Spring自带的。

进一步在代码中全局搜索“myThread”关键字,果然发现了自定义线程池的地方。经过检查代码提交记录,确认是其他同事最近提交的代码引起的问题。

再来看自定义线程池的配置:

 

executor.setMaxPoolSize(1);
executor.setQueueCapacity(50);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());

  

线程池中只有一个线程,队列容量为50。这意味着同时只能有50个任务排队等待执行。拒绝策略采用了`DiscardPolicy`,该策略会在队列已满时直接抛弃新任务,且不抛出异常。

复盘系统实际运行过程:当`method1`执行到`method2`时,会使用自定义线程池中的唯一一个线程`myThread-1`来执行。如果`myThread-1`已有任务在执行,新任务会进入队列排队。若任务过多超过50个,新任务就会被抛弃,不再执行。

由于任务被抛弃,这就解释了为何没有打印“b”。同时,由于采用了`DiscardPolicy`策略,因此没有异常日志产生。

知道了问题的原因,解决方案就变得清晰了。有两种解决方法:
1. 移除自定义线程池,回归使用默认线程池(尽管默认线程池存在无限队列问题,但我们的项目负载不会那么大)。
2. 调整自定义线程池的配置,增加线程数至8,队列容量扩大到几千,并将拒绝策略改为抛出异常的策略。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/738716.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器忘记IP后找回IP地址

在工程现场,我们时常会遇到忘记BMC IP地址的情况,在忘记BMC IP后有两种方法可以帮助我们找回忘记的IP地址 1、外接显示器(在服务器开机过程中右下角会显示出IP地址)2、通过抓包软件(Wireshark)来抓取设备发到广播报 前提条件服务器先完全断电 电脑网口和IPMI口直连,确保…

【日记】今天好忙(316 字)

正文今天一整天都是疯忙的节奏。上午开户,一来来俩。从 9 点到 12 点,中间连轴转没停过。昨天睡得还可以,不过上午依旧很困。昨晚跟兄长打了一晚上的掳人少女人偶,没打过…… 宫崎英高!你罪该万死!搞这么难…….昨晚也因为去的时候在下雨,所以没什么人来练习。只有我和大…

KIM论文阅读笔记

Personalized News Recommendation with Knowledge-aware Interactive Matching论文阅读笔记 Abstract 现存的问题: ​ 现有的大多数新闻推荐方法都是从文本内容和用户点击的新闻中分别建立候选新闻模型和用户兴趣模型。然而,一篇新闻可能涉及多个方面和实体,而用户通常有不…

Docker 构建nginx镜像

步骤: (1)创建一个目录,把构建Nginx的Dockerfile文件保存到此目录。 创建一个名为nginxDockerfile的目录。mkdir nginxDockerfile(2)进入刚才创建好的目录。cd nginxDockerfile(3)创建Dockerfile文件。vim dockerfile 文件内容如下FROM centos MAINTAINER xpx RUN yum…

es库-连接工具-chrome插件:Elasticsearch-Head

Elasticsearch-Head如何连接es数据库呢: 1.下载Elasticsearch-Head插件压缩包 2.解压文件夹,是这样的: 3.打开chrome浏览器的 扩展程序管理 然后,点击“加载已解压的扩展程序”: 找到 并且选中 你压缩es-head文件夹的根目录-》点击“选择文件夹”: 到目前就加载上es-head…

《计算机组成与系统结构(第二版) 裘雪红 李伯成 西安电子科技大学出版社》课后习题答案(带解析)(五)

此系列答案配套《计算机组成与系统结构(第二版) 裘雪红 李伯成 西安电子科技大学出版社》一书相关内容。所有内容为博主个人编辑,仅作参考学习交流之用,转载请注明出处。如发现错误,请联系博主及时勘误。如有侵权行为,博主将立即下架全部内容。声明:此系列答案配套《计…

《计算机组成与系统结构(第二版) 裘雪红 李伯成 西安电子科技大学出版社》课后习题答案(带解析)(四)

此系列答案配套《计算机组成与系统结构(第二版) 裘雪红 李伯成 西安电子科技大学出版社》一书相关内容。所有内容为博主个人编辑,仅作参考学习交流之用,转载请注明出处。如发现错误,请联系博主及时勘误。如有侵权行为,博主将立即下架全部内容。声明:此系列答案配套《计…

数字经济时代:AI+引领企业数字化新高度

"AI+"指将人工智能技术与各行各业深度融合,从研发到场景应用再到产业打造,实现全链条赋能,是数字经济中创新应用的典型代表,也是传统企业转型升级的强大引擎——不仅是技术层面的创新,更是一种全新的思维方式和工作模式,要求企业在战略规划、组织结构、业务流程…

金蝶云苍穹追光者开发大赛,点燃高校AI应用创新之火

作为践行金蝶 “All in AI” 战略、推动 “订阅优先、AI 优先” 的核心开发者赛事,「第六届金蝶云・苍穹追光者开发大赛」正如火如荼地进行,吸引了众多高校开发者的热情参与,点燃高校 AI 应用创新之火。在 2024 年的政府工作报告中,"人工智能 +" 行动被提出,标志…

vue3 父子组件双向绑定

父组件 ParentComponent.vue<!-- ParentComponent.vue --> <template><div>子组件输入的数据<p>Parent Value: {{ parentValue }}</p>父输入框<input v-model="parentValue"><CustomInput v-model="parentValue" /…