文档章节

记一次 thread.blocked.count 线程过多的问题排查

o
 osc_g8254g7s
发布于 2019/08/19 19:44
字数 366
阅读 0
收藏 0

精选30+云产品,助力企业轻松上云!>>>

问题现象:会经常出现block线程过多,但是瞬间又会恢复,因此较困难查询到现场堆栈。jvm.thread.blocked.count  >= 50

一、由于现场难以抓取,因此无法用 Jstack 登录机器查询堆栈信息。

二、因为经过调研采用代码的方式,抓取线上block时,线程堆栈信息。

private List<BlockThreadEntity> getBlockThreadList() {
        List<BlockThreadEntity> blockThreadInfoList = new ArrayList<>();
        final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
        ThreadInfo[] threadInfos = threadBean.dumpAllThreads(false, false);

        if (threadInfos != null) {
            for (ThreadInfo threadInfo : threadInfos) {
                BlockThreadEntity entity = null;
                if (Thread.State.BLOCKED.equals(threadInfo.getThreadState())) {
                    entity = new BlockThreadEntity();
                    StringBuilder sb = new StringBuilder();
                    StackTraceElement[] stack = threadInfo.getStackTrace();
                    LockInfo lockInfo = threadInfo.getLockInfo();
                    String lockInfoString = null != lockInfo ? lockInfo.getClassName() : "";
                    for (StackTraceElement stackTraceElement : stack) {
                        sb.append("\n" + stackTraceElement.toString());
                    }
                    //记录阻塞线程信息
                    entity.lockInfo = lockInfoString;
                    entity.stackTrace = sb.toString();
                    entity.threadId = String.valueOf(threadInfo.getThreadId());
                    entity.threadName = threadInfo.getThreadName();
                }
                if (entity != null) {
                    blockThreadInfoList.add(entity);
                }
            }
        }
        return blockThreadInfoList;
    }

二、经过一段时间的堆栈信息收集,找到关键的锁信息

stacktrace:[
ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:211)
ch.qos.logback.core.rolling.RollingFileAppender.subAppend(RollingFileAppender.java:175)
ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:103)
ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:88)
com.***.scribe.logback.***LogAppender.append(***LogAppender.java:41)
com.***.scribe.logback.***LogAppender.append(***LogAppender.java:15)
ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:88)
ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:48)
ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:272)
ch.qos.logback.classic.Logger.callAppenders(Logger.java:259)
ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:441)
ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:395)
ch.qos.logback.classic.Logger.info(Logger.java:599)

lockInfo:[ch.qos.logback.core.spi.LogbackLock]

  查看logbck的源码,发现的确是用了 synchronized 锁。

三、进一步源码追踪,发现使用的是同步日志,由于代码中有一个调用量较大的地方,再打印日志, 关闭该出日志,问题解决。

四、补充:异步日志。

      AsyncAppenderBase 类

       BlockingQueue<E> blockingQueue = new ArrayBlockingQueue<E> 使用的是一个队列。

       将日志时间放入队列, 另一个线程,循环处理。 如果队列满了,会丢弃日志。

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
记一次OOM异常排查过程

具体过程,某天现场按照人员打我电话,说我们系统很卡,我想着不可能啊,于是赶紧链上服务器发现服务器内存已经快用完了,因为是线上环境,有日志记录,先恢复系统系统再说,于是直接重启了,...

终极作者
2019/12/02
100
0
线上问题与排查

死锁 一文学会Java死锁和CPU 100% 问题的排查技巧 如何避免死锁,我们有什么套路可循?(举例说明,浅显生动,给出了死锁发生的Coffman条件,并从破坏条件角度讲如何避免死锁) MySQL锁总结-11.死...

KafkaPlus
05/29
5
0
记一次文件句柄泄漏导致的崩溃

最近项目上遇到好几个崩溃问题,解决过程有点曲折,在此记做个记录。 项目背景介绍:该项目为语音识别实时分析系统,整套系统架构如下:    接连几次崩溃的是中间的语音流接入系统,崩溃的...

osc_mfn168vg
04/16
2
0
记一次cpu指标异常的跟踪排查

问题描述: 最近在测试环境的服务器上,无意中发现cpu持续飙高。最高的时候达到了200%经过反复重启无效之后,决定挖掘深层次的原因 通过top命令打印出消耗cpu的pid,如图 通过ps -mp 24597 ...

飞天小子
2019/06/04
0
0
记一次cpu指标异常的跟踪排查

问题描述: 最近在测试环境的服务器上,无意中发现cpu持续飙高。最高的时候达到了200%经过反复重启无效之后,决定挖掘深层次的原因 通过top命令打印出消耗cpu的pid,如图 通过ps -mp 24597 ...

osc_i5nfw8fz
2019/06/04
2
0

没有更多内容

加载失败,请刷新页面

加载更多

面试必问之mysql基础

mysql存储引擎 如何选择mysql存储引擎 先得了解下各个存储引擎区别 功能 MylSAM MEMORY InnoDB Archive 功能 MylSAM MEMORY InnoDB Archive 存储限制 256TB RAM 64TB None 支持事务 No No Ye...

lipengxs
14分钟前
16
0
错误:将标头发送到客户端后无法设置标头 - Error: Can't set headers after they are sent to the client

问题: I'm fairly new to Node.js and I am having some issues. 我对Node.js相当陌生,遇到了一些问题。 I am using Node.js 4.10 and Express 2.4.3. 我正在使用Node.js 4.10和Express 2......

法国红酒甜
25分钟前
18
0
Spring中事务不生效的几种情况

数据库引擎不支持事务。 没有被Spring管理。 方法不是public的。 自身调用问题。 数据源没有配置事务管理器。 不支持事务。 异常被吃了。 异常类型错误。 事务失效类型: 数据库引擎不支持事...

九分石人
44分钟前
31
0
从Linux内核理解JAVA的NIO

前言 IO 可以简单分为磁盘 IO 和 网络 IO ,磁盘 IO 相对于网络 IO 速度会快一点,本文主要介绍 磁盘 IO ,网络 IO 下周写。 JAVA 对 NIO 抽象为 Channel , Channel 又可以分为 FileChannel ...

万古云霄
49分钟前
22
0
Material Design用在c#的wpf app中

官网:http://materialdesigninxaml.net/ 样式丰富 做网站和手机不粗 个人觉得不适合用在.net framework中,在.net core中应该大有作为。...

齐勇cn
50分钟前
28
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部