在线精品99_中国九九盗摄偷拍偷看_91免费版在线观看_91.app_91高清视频在线_99热最新网站

Tomcat 9.0.26高并发场景下DeadLock问题怎么处理

104次阅读
没有评论

共计 2697 个字符,预计需要花费 7 分钟才能阅读完成。

这篇文章给大家分享的是有关 Tomcat 9.0.26 高并发场景下 DeadLock 问题怎么处理的内容。丸趣 TV 小编觉得挺实用的,因此分享给大家做个参考,一起跟随丸趣 TV 小编过来看看吧。

一、Tomcat 容器 9.0.26 版本 Deadlock 问题 1.1 问题现象 1.1.1  发生 Deadlock 的背景

某接口 /get.do 压测,3 分钟后,成功事务数 TPS 由 1W 骤降至 0。

1.1.2  Tomcat 服务器出现大量的 CLOSE_WAIT

被压测服务器,出现 TCP CLOSE_WAIT 状态个数在 200~2W 左右。

1.2 初步定位:线程堆栈信息入手

通过 jstack 打印 Tomcat 堆栈信息,发现“Found 1 deadlock”

Found one Java-level deadlock:
=============================
 http-nio-8080-exec-409 :
waiting to lock monitor 0x00007f064805aa78 (object 0x00000006c0ebf148, a java.util.HashSet),
which is held by  http-nio-8080-ClientPoller 
 http-nio-8080-ClientPoller :
waiting to lock monitor 0x00007f05e8061058 (object 0x00000007bfe40a70, a java.lang.Object),
which is held by  http-nio-8080-exec-205 
 http-nio-8080-exec-205 :
waiting to lock monitor 0x00007f0614018448 (object 0x00000006c0e8e088, a java.util.HashSet),
which is held by  http-nio-8080-BlockPoller 
 http-nio-8080-BlockPoller :
waiting to lock monitor 0x0000000001ed06e8 (object 0x00000007bfe110f8, a java.lang.Object),
which is held by  http-nio-8080-exec-380 
 http-nio-8080-exec-380 :
waiting to lock monitor 0x00007f064805aa78 (object 0x00000006c0ebf148, a java.util.HashSet),
which is held by  http-nio-8080-ClientPoller [object Object]

1.2.1  快速修复方案

内部讨论后,认为当前 Tomcat 版本可能有 Bug。不影响项目进度,简单修改方案把 SpringBoot 使用的 Tomcat 9.0.26 降级到 Tomcat 8。降级后再次压测,没有发现问题。基本上可以确定 Tomcat 9.0.26 应该是存在 Deadlock 问题。

1.3  问题进一步跟踪 1.3.1  向 Apache 社区的反馈

为了确认问题,我们试着给 Tomcat 提交 Bug 反馈。

从堆栈信息来看,是 3 类线程 5 个线程由于加锁的顺序不致,从而相互等待发生了死锁。图形化上面加锁的过程如下图。

1.4 问题原因分析

明确了死锁的过程,但是哪个环节出了问题呢。这就需要深入到源码层去定位问题。首先需要下载 OpenJDK 源码,然后是 Tomcat 9.0.26 的源码。根据堆栈信息,定位到相应的代码位置。我们理出如下图 Tomcat 9.0.26 死锁流程说明。

要比较好的理解上图,需要对于 NIO 有一定的了解。在 Tomcat 中 NIO 主要是理解 NIO Endpoint。

Poller 是对于 Selector 的一个封装,而线程名为 exec-xx 的执行线程是 Channel 的封装。在 NIO 中 Channel 注册到 Selector 然后通过 SelectionKey 来记录对应关系。到此,主角都上场了。

Poller 的 run 方法作为后台线程一直在轮询(select)准备好的 SelectionKey,在轮询的时候也顺便需要把 cancelledKey 中的 SelectionKey 给反注册。执行线程 EXEC-XX 在处理时会先判断连接的状态,比如失败、异常等情况会调用 Channel 的 close 方法去关闭连接。

而 Channel 的 close 实际只是把 SelectionKey 加入到 cancelledKey。两者都需要先锁定,但锁定的顺序不一致,从而导致死锁。

1.4.1  与 Tomcat 开发者的交流

在提交 Bug 后,很快得到了 Remy Maucherat 的回复,首先他提到这个 NIO 内部的死锁。然后我们提到 NIO 内部的死锁是由于 Poller.run 和 Poller.canceledKey 在并发时导到的。

Remy Maucherat 很快就进行了修复,主要是把 Poller.canceledKey 中 close 移到了 finally 中去执行,也就是先让 Poller.run 获得锁。

在得到修复后,我们使用替换后的代码进行了再次压测,死锁问题没有出现了。Remy Maucherat 同时提到在最新的 OpenJDK 中相关问题的修复,但只会出现在 jdk 11 和 14 版本。

沟通中的详情见下图。

1.4.2  Github 上修复的验证

https://github.com/apache/tomcat/commit/9b1a8b67bffe462fc745b19e15ed59c37e2e1dcf

1.5 结果验证

使用  
https://github.com/apache/tomcat/commit/9b1a8b67bffe462fc745b19e15ed59c37e2e1dcf  提供修复后代码,重新打包 tomcat-embed-core.jar 替换 9.X.XX 的再次压测,TPS 平稳在 1.5W 左右。

到此问题基本是定位清楚,并得到了修复。Remy Maucherat 也回复到“The fix will be in Tomcat 9.0.31+”。

目前 Tomcat 最新版本是 Tomcat 9.0.30,还需要耐心等待 31 版本更新。建议使用 Tomcat 8 版本。

感谢各位的阅读!关于“Tomcat 9.0.26 高并发场景下 DeadLock 问题怎么处理”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计2697字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)
主站蜘蛛池模板: 精品国产三级a∨在线欧美 精品国产三级a在线观看 | 精品国产一区二区三区四区在线看 | 射黄视频 | 97久久综合亚洲色hezyo | 亚洲欧洲日产国码av系列天堂 | 五月丁香综合缴情六月小说 | 久久久窝窝午夜精品 | 国产 欧美 日产久久 | 国产精品原创永久在线观看 | 国产一级做a爰片在线看免费 | 色婷婷资源网 | 免费va国产高清大片在线 | 自拍一区在线观看 | 草草免费观看视频在线 | 一区二区三区免费看 | 欧美亚洲综合在线观看 | 欧美精彩狠狠色丁香婷婷 | 嫩草视频在线免费观看 | 久久综合色区 | 亚洲在线欧美 | 欧美日韩一区二区在线观看 | 男人天堂网av | 中文成人无码精品久久久 | 国产巨乳在线观看 | 日本一级在线播放线观看视频 | 久久精品网站2019精品 | 国产高清不卡一区二区 | 高清不卡视频 | www久久久久 | 亚洲a人| 国产成人无码专区 | 免费在线观看的毛片 | 四虎视频在线永久观看 | 国产亚洲精品无码成人 | 最近中文字幕完整版免费 | 日本一级一片免费 | 免费啪啪网 | 国产精品夜色视频一区二区 | 亚洲色图诱惑 | 2021国产精品成人免费视频 | 国产精品国产亚洲区艳妇糸列短篇 |