iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Tomcat 9.0.26高并发场景下DeadLock问题怎么处理
  • 655
分享到

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

2023-06-04 15:06:22 655人浏览 独家记忆
摘要

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

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

一、Tomcat容器 9.0.26 版本 Deadlock 问题

1.1 问题现象

1.1.1  发生 Deadlock 的背景

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

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

1.1.2  Tomcat服务器出现大量的CLOSE_WAIT

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

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

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反馈。

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

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

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

1.4 问题原因分析

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

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

要比较好的理解上图,需要对于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版本。

沟通中的详情见下图。

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

1.4.2  Github上修复的验证

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

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

1.5 结果验证

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

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

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

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

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

--结束END--

本文标题: Tomcat 9.0.26高并发场景下DeadLock问题怎么处理

本文链接: https://www.lsjlt.com/news/238447.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Tomcat 9.0.26高并发场景下DeadLock问题怎么处理
    这篇文章给大家分享的是有关Tomcat 9.0.26高并发场景下DeadLock问题怎么处理的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、Tomcat容器 9.0.26 版本 Deadlock 问题1.1 问...
    99+
    2023-06-04
  • Redis怎么处理高并发场景
    Redis可以处理高并发场景的方法包括: 使用Redis的持久化功能,将数据存储在内存中,并定期将数据同步到磁盘上,确保数据的安...
    99+
    2024-05-07
    Redis
  • Golang的高并发场景中如何处理死锁和饥饿问题?
    死锁与饥饿在 go 并发编程中的成因和解决方法:死锁:由递归锁引起,避免方法是采用死锁避免算法。饥饿:由优先级反转引起,解决方法是使用优先级继承机制,让低优先级线程暂时获取高优先级线程的...
    99+
    2024-05-10
    死锁 饥饿 golang
  • Java高并发场景下的缓存常见的问题有哪些
    这篇文章主要讲解了“Java高并发场景下的缓存常见的问题有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java高并发场景下的缓存常见的问题有哪些”吧!一、缓存一致性问题当数据时效性要求...
    99+
    2023-06-05
  • tomcat高并发阻塞问题怎么解决
    要解决Tomcat高并发阻塞问题,可以考虑以下几个方面:1. 调整Tomcat配置:增加Tomcat的线程池大小、调整连接超时时间等...
    99+
    2023-10-12
    tomcat
  • Apache Tomcat怎么高并发处理请求
    这篇文章给大家分享的是有关Apache Tomcat怎么高并发处理请求的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。介绍作为常用的http协议服务器,tomcat应用非常广泛。tomcat也是遵循Ser...
    99+
    2023-06-29
  • 如何使用php函数解决高并发场景下的性能问题?
    高并发场景是指系统在同一时间段内接收到大量的请求。在这种情况下,系统的性能会受到很大的挑战,因为处理大量请求可能会导致服务器响应时间过长,甚至造成系统崩溃。为了解决高并发场景下的性能问题,PHP提供了一些函数和技巧。下面将介绍一些常见的方法...
    99+
    2023-10-21
    PHP性能优化 并发处理 函数调用
  • Python 框架在大数据场景下如何实现高效并发处理?
    随着大数据时代的到来,数据的处理需求越来越多,数据量也越来越大。在这样的背景下,如何实现高效并发处理成为了一个非常重要的问题。Python 作为一种高效、易学的编程语言,拥有丰富的框架和库,可以帮助我们实现高效并发处理。本文将介绍 Pyt...
    99+
    2023-08-20
    框架 大数据 并发
  • MySQL在并发场景下的问题及解决思路是怎样的
    本篇文章为大家展示了MySQL在并发场景下的问题及解决思路是怎样的,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1、背景对于数据库系统来说在多用户并发条件下提高并发...
    99+
    2024-04-02
  • PHP 防抖技术:解决高并发场景下的数据重复提交问题
    导言:在高并发场景中,用户可能会频繁点击按钮或提交表单,这就导致服务器收到多次相同的请求,从而可能造成数据的重复提交。针对这一问题,我们可以采取一种被称为“防抖”的技术来解决。本文将介绍PHP中的防抖技术以及具体的代码示例,旨在帮助开发者们...
    99+
    2023-10-21
    高并发 防抖技术 数据重复提交
  • Java Semaphore怎么实现高并发场景下的流量控制
    这篇文章主要介绍“Java Semaphore怎么实现高并发场景下的流量控制”,在日常操作中,相信很多人在Java Semaphore怎么实现高并发场景下的流量控制问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作...
    99+
    2023-06-22
  • Golang 技术性能优化中如何处理高并发场景?
    golang 高并发性能优化技巧:同步和互斥:使用互斥锁 (mutex) 和等待组 (waitgroup) 同步共享资源,确保并发访问的安全。通道:利用无缓冲通道在 goroutine ...
    99+
    2024-05-12
    golang 高并发 并发访问 同步机制
  • java高并发下脏读问题怎么解决
    在Java高并发下解决脏读问题可以通过使用锁机制或者使用线程安全的数据结构来实现。1. 使用锁机制:可以使用synchronized...
    99+
    2023-08-23
    java
  • 高并发怎么处理
    高并发的处理:尽可能使网站上的页面采方法用静态页面。图片是最消耗资源的,将图片与页面进行分离。缓存、镜像、负载均衡。需要使用数据库集群或者库表散列。...
    99+
    2024-04-02
  • Golang如何在高并发场景中实现任务调度和并行处理?
    在 go 语言中,任务调度可以使用 sync/cond 和 sync/waitgroup,而并行处理则通过 goroutine 实现。sync/cond 提供条件变量,用于等待条件满足再...
    99+
    2024-05-11
    golang 并发处理
  • Golang高并发场景中的锁管理策略是什么?
    锁管理策略提升 golang 高并发性能锁类型: 互斥锁(mutex),读写锁(rwmutex),原子操作最佳实践:最小化锁的粒度避免死锁使用读写锁使用原子操作实战案例: 使用互斥锁保护...
    99+
    2024-05-10
    golang 并发 go语言
  • Go语言如何通过容器技术扩展高并发场景下的处理能力?
    使用go语言扩展高并发处理能力:使用docker容器化应用程序,提供轻量级、可移植的环境。通过kubernetes部署和编排容器,实现自动扩展。利用水平自动扩缩功能(hpa)根据资源使用...
    99+
    2024-05-10
    高并发 容器技术 docker golang go语言 容器化应用
  • 在Golang高并发场景中如何进行限流和熔断处理?
    在 golang 高并发场景中,限流和熔断可保护系统免遭过载:限流通过限制请求数量,防止系统超负荷,例如使用令牌桶算法。熔断在服务故障或负荷过高时关闭访问,例如使用熔断器模式,当失败请求...
    99+
    2024-05-10
    限流 熔断 git golang
  • C++高并发场景下读多写少的优化方案是什么
    这期内容当中小编将会给大家带来有关C++高并发场景下读多写少的优化方案是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。概述一谈到高并发的优化方案,往往能想到模块水平拆分、数据库读写分离、分库分表,加缓...
    99+
    2023-06-26
  • java怎么处理高并发
    在处理高并发时,可以使用以下几种方法来提高Java应用程序的性能和并发处理能力:1. 使用线程池:通过使用线程池可以减少线程的创建和...
    99+
    2023-08-23
    java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作