一、背景

线上应用系统1300+多个线程,而且线程不会销毁,达到了1300个线程的UMP告警阈值;

容器情况:
JRE版本:1.8.0_20
CPU个数:4
web服务器:undertow 2.0.16.Final

二、分析

1、下载dump日志

jmap -dump:live,format=b,file=heap.hprof 进程号

2、 使用jvisualvm进行分析


分析发现1300多个线程大致分为如下几类:

  1. 守护线程400+ 个
  2. XNIO-1 I/O 线程96个,处于Running状态
  3. XNIO task 线程768,处于waiting状态
  4. 其他线程:几十个

通过查阅资料可知XNIO开头的都是undertow线程(undertow是基于xnio框架实现的)

XNIO-1 I/O 线程:是服务中的非阻塞线程,线程数默认等于CUP核数(其实是与2做比较取最大值)
XNIO task 线程:是阻塞线程,默认情况下该类线程对应的线程池的核心线程数和最大线程数是一致的,都是XNIO-1 I/O线程数的8倍;由于这些线程全是核心线程,所以这些线程都不会被销毁;

问题

我们的应用服务在部署的时候,容器一般都是4核或者8核,那为什么会创建这么多的96个非阻塞线程呢?

答案

应用服务使用的是docker容器创建的linux环境,在这个环境下,如果使用Java SE 8u131 (JRE 1.8.0_131-b11)以下的版本,通过Runtime.getRuntime().availableProcessors(),获取到的cpu核数是宿主机的核数,undertow就是这样获取的;

而我们的容器中JDK版本为1.8.0_20,就是上述版本之下,这样就能解释为什么默认情况下会创建XNIO-1 I/O 线程96个,XNIO task768线程个了;

附Jdk8版本号:https://www.java.com/zh-CN/download/help/release_changes.html

三、解决

方案1

在yml文件中指定undertow的线程数:

server.undertow.io-threads=4
server.undertow.worker-threads=40

方案2

使用Java SE 8u131 (JRE 1.8.0_131-b11)以上的版本,或者用JDK11;

四、思考

其实如果比较熟悉undertow,知道undertow中的线程的命名、以及线程数的关系的话,通过查看服务日志基本就能定位到问题
undertow配置的核心参数如下:

# 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程,XNIO建议设置默认值即可
server.undertow.io-threads=4# 阻塞任务线程池, 当执行类似servlet请求阻塞IO操作, undertow会从这个线程池中取得线程
# 它的值设置取决于系统线程执行任务的阻塞系数,默认值是IO线程数*8,一般情况下每个C大约10个线程即可
server.undertow.worker-threads=32# 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
# 每块buffer的空间大小,越小的空间被利用越充分,不要设置太大,以免影响其他应用,合适即可
server.undertow.buffers-per-region=1024# 是否分配的直接内存(NIO直接分配的堆外内存)
server.undertos-per-region
server.undertow.buffer-size=1024# 每个区分配的buffer数量 , 所以pool的大小是buffer-size * bufferw.direct-buffers=true

参考:https://undertow.io/undertow-docs/undertow-docs-2.1.0/index.html

undertow服务线程过多问题排查相关推荐

  1. 一文探讨 RPC 框架中的服务线程隔离

    Kirito 推荐语:最近秋招开始了,很多学生开始准备起了秋招,有很多人想知道进一些有名的互联网公司实习有什么要求,正好最近跟一位阿里春招的实习小伙子聊了一些 RPC 相关的知识点,于是我把这篇他的思 ...

  2. Spring Boot使用Undertow服务

    Spring Boot使用Undertow服务 Undertow Undertow 是红帽公司开发的一款基于 NIO 的高性能 Web 嵌入式服务器 Untertow 的特点: 轻量级:它是一个 We ...

  3. Redis 3.2.3 crashed by signal: 11 服务宕机问题排查

    Redis 3.2.3 crashed by signal: 11 服务宕机问题排查 现象 Redis执行bgsave .bgrewriteaof.全量scan等操作都会出现崩溃 === REDIS ...

  4. 为什么线程过多会损害性能

    线程太多 线程是从多核芯片中提取性能的当前选择方法.似乎如果有一点线程是好的,那么很多线程必须更好.实际上,线程太多会使程序陷入瘫痪.本文讨论了为什么以及如何基于任务的编程可以避免该问题.英特尔®线程 ...

  5. 服务不可用怎么排查?讲了100遍还是记不住?

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 下面是线上机器的cpu使用率,可以看到从4月8日开始,随着 ...

  6. 整理一下:遇到的Java服务故障问题及排查方案

    常见问题 1:CPU 利用率高问题 CPU 使用率是衡量系统繁忙程度的重要指标,一般情况下单纯的 CPU 高并没有问题,它代表系统正在不断的处理我们的任务,但是如果 CPU 过高,导致任务处理不过来, ...

  7. mysql运维-sleep线程过多_MySQL sleep过多解决方法

    现状: 睡眠连接过多,会对mysql服务器造成什么影响? 严重消耗mysql服务器资源(主要是cpu, 内存),并可能导致mysql崩溃. 原因分析: 造成睡眠连接过多的原因? 1. 使用了太多持久连 ...

  8. “服务不可用“怎么排查?

    下面是线上机器的cpu使用率,可以看到从4月8日开始,随着时间cpu使用率在逐步增高,最终使用率达到100%导致线上服务不可用,后面重启了机器后恢复. 1.排查思路 简单分析下可能出问题的地方,分为5 ...

  9. java - JVM 线上服务的FGC问题排查

    线上服务的GC问题,是Java程序非常典型的一类问题,非常考验工程师排查问题的能力.同时,几乎是面试必考题,但是能真正答好此题的人并不多,要么原理没吃透,要么缺乏实战经验. 过去半年时间里,我们的广告 ...

最新文章

  1. 2021.9.6 跑FICS【当时的经验】
  2. PHP 通过fsockopen函数获取远程网页源码
  3. linux 账号和密码文件 /etc/passwd和/etc/shadow 简介
  4. jQuery 属性操作——案例:购物车案例模块
  5. 在Spring事务管理下,Synchronized为啥还线程不安全?
  6. html改变输入框的值,一个Input框值改变,另一个显示内容也改变
  7. python_面向对象进阶之多继承
  8. 公交换乘系统c语言,公交换乘的简单实现(源码)
  9. 展示一个基本的正则用例
  10. 百度SEO工作室团队介绍HTML5源码
  11. adb shell 直接修改Settigns中设置项
  12. lvchange的available參数
  13. Atom: 安装版本过旧,会导致很多问题
  14. 关于rnn神经网络的loss函数的一些思考
  15. 乐高mindstormsev3_lego mindstorms ev3下载-乐高EV3机器人编程软件1.3.1 家庭版-东坡下载...
  16. python 贪吃蛇
  17. 详解Autosar Arxml中的CANFD报文及格式
  18. Excel如何冻结多行多列
  19. 电脑上传,如何查看电脑上传速度
  20. JS获取ul中li的值同步到搜索框

热门文章

  1. foxmail的邮局和端口_Foxmail的服务器设置
  2. 【iOS开发-59】LOL案例:单组tabView、alertView样式、实现监听,以及用reloadData数据刷新
  3. 国内很好的IT学习网站
  4. pdaf添加实例(2p7,type2)
  5. 教程 | 10分钟入门禅绕画 (上)
  6. Pattern和Matcher用法
  7. 孤傲苍狼 只为成功找方法,不为失败找借口! javaweb学习总结(三十九)——数据库连接池 一、应用程序直接获取数据库连接的缺点   用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要
  8. 接口签名中的三位小伙伴signature,nonce,timestamp
  9. 【动画展示】Focusky教程 | 自定义动画运动路径
  10. 抄底摸顶的高概率交易技巧