漫话:应用程序被拖慢?罪魁祸首竟然是Log4j!

之前一段时间,为我们发现的一个SaaS应用程序会间歇性地卡顿、变慢,因为很长时间都没有定位到原因,所以解决的办法就只能是重启。

这个现象和之前我们遇到的程序变得卡顿不太一样,因为我们发现这个应用程序不仅在高流量期间时会变慢,有时在低流量时期也会变慢。所以这令大家都很奇怪。

这类应用程序的变慢,重新启动之后就可以维持一段时间,但是过段时间又有可能会再次出现。

故障排除

当我们准备排查这个问题的时候,我们在应用程序速度很慢的时候,尝试着捕获了这个应用程序的线程Dump。有很多种方式来捕获线程转Dump,我们选择了“jstack”工具来获取。

在问题发生时获得线程Dump是非常关键的!

然后我们将捕获的线程Dump上传到一个线上线程Dump分析工具(https://fastthread.io/)。该工具立即帮我们生成了一份报告。

报告立即找出了问题的根本原因。分析工具上显示“http-nio-8080-exec-121”线程阻塞了100多个线程。下面是传递依赖图,展示了阻塞线程:

从图中可以看到100多个线程被“http-nio-8080-exec-121”线程阻塞。当我们点击图中的“http-nio-8080-exec-121”超链接时,它会打印出线程的堆栈轨迹:

仔细观察图中被框出来的部分,你可以看到该线程已经获取到org.apache.log4j.Logger的锁,正在进行其他的操作。

接下来,我们随便找一个被"http-nio-8080-exec-121"阻塞的线程,看一下他的堆栈信息:

看一下上面堆栈跟踪中被框出来的部分。我们可以看到“http-nio-8080-exec-56”当前正处于阻塞(BLOCKED)状态,而阻塞的原因是它正在等待获取org.apache.log4j.Logger的锁。

前面我们刚刚分析过,“http-nio-8080-exec-121”获得了org.apache.log4j.Logger的锁,正在进行其他操作,而锁并没有被释放,所以其他线程想要获得锁就只能被阻塞。

其余的所有被阻塞的线程也在等待获取org.apache.log4j.Logger的锁。因此,每当任何应用程序线程试图记录日志时,它都会因为无法获取到锁而进入阻塞状态。

刚开始我们也没有太多的头绪,后来我们尝试借助Google的力量,然后我们用谷歌搜索了"org.apache.log4j.Logger 阻塞 线程"这样的关键字。

我们在Apache Log4j bug数据库中偶然发现了这个有趣的Bug,而且这个Bug早在2015年就被发现了。(https://bz.apache.org/bugzilla/show_bug.cgi?id=57714 )。

这是Log4J框架中已知的bug之一,也是开发新的Log4j2框架的主要原因之一。

由于这个bug,任何试图打印日志的线程都进入了阻塞状态。它导致整个应用程序嘎然而止。一旦应用程序从Log4j迁移到Log4j2框架,问题就解决了。

结论

Log4j已经在2015年8月开始就不再被维护了。如果您的应用程序仍在使用Log4J框架,强烈建议升级到Log4j2框架。Log4j2不仅仅是Log4j框架的下一个版本,它是一个从零开始编写的新框架,它有很多性能改进。

最后,如果网站遇到程序被拖慢的问题,那么也可以考虑一下这个因素。

文末福利:我整理了一份 280 多页的《JAVA核心面试知识整理.pdf》,包含了:Java 集合、Java 基础、JVM、并发编程、Spring 原理、Netty、网络、Kafka、Zookeeper、RabbitMQ、设计模式、数据库、数据结构和算法等面试题。

下载方式

1. 首先扫描下方二维码

2. 后台回复「面试」即可获取

注明:仅仅作为知识分享,切勿用于其它商业活动 。感谢所有技术分享者的付出。

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

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

相关文章

面试系列第2篇:回文字符串判断的3种方法!

作者 | 磊哥来源 | Java面试真题解析(ID:aimianshi666)转载请联系授权(微信ID:GG_Stone)回文字符串判断是面试和笔试中常见的面试题之一,同时也是 LeetCode 中一道经典的面试题,那么…

工程中多个不同类型线程池_软件工程中不同类型的设计策略

工程中多个不同类型线程池As we know that the designing phase is probably the second phase in the software development lifecycle, which comes after the feasibility testing and requirement analysis phase. As the name itself defines that in this phase, the sof…

vb检查磁盘类型

Option ExplicitPrivate Declare Function GetDriveType Lib "kernel32.dll" Alias "GetDriveTypeA" (ByVal nDrive As String) As LongPrivate Sub Command1_Click()Select Case GetDriveType("C:\")Case 0MsgBox "未知类型", vbExcl…

Activity具体解释(生命周期、以各种方式启动Activity、状态保存,全然退出等)...

一、什么是Activity&#xff1f; 简单的说&#xff1a;Activity就是布满整个窗体或者悬浮于其它窗体上的交互界面。在一个应用程序中通常由多个Activity构成&#xff0c;都会在Manifest.xml中指定一个主的Activity&#xff0c;例如以下设置 <actionandroid:name"androi…

将十进制转化为八进制的算法_十进制系统转换为八进制系统

将十进制转化为八进制的算法Converting a number from Decimal to Octal is almost similar to converting Decimal into Binary, although just one difference is that unlike Binary conversion, here in an integral part, we successively divide the number by 8 until t…

阿里为什么推荐使用LongAdder,而不是volatile?

这是我的第 87 篇原创文章作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;阿里《Java开发手册》最新嵩山版在 8.3 日发布&#xff0c;其中有一段内容引起了老王的注意&#…

VC函数中的延时操作

说到程序中的延时&#xff0c;你会想到怎么做&#xff0c;新开一个线程&#xff1f;如果我的程序只用单线程&#xff0c;却又想让函数等上10秒才返回值&#xff0c;而且还不能像使用Sleep函数那样不能处理其它消息呢&#xff1f;我在这里把论坛里能见到的几种延时方式总结一下。…

Eclipse中SVN的安装步骤(两种)和用法

一、给安装EclipseSVN&#xff0c;最常见的有两种方式&#xff1a;手动方式和使用安装向导方式。详细过程例如以下&#xff1a; 方式一&#xff1a;手动安装 1、从官网下载site-1.6.9.zip文件,网址是:subclipse.tigris.org2、从中解压出features与plugins目录&#xff0c;拷贝到…

c构造函数和析构函数_C ++构造函数和析构函数| 查找输出程序| 套装3

c构造函数和析构函数Program 1: 程序1&#xff1a; #include <iostream>using namespace std;class Sample {private:int X;public:Sample(){X 0;}void set(int x){X x;}void print(){cout << X << endl;}};int main(){Sample S[2] { Sample(), Sample()…

XP定时关机

&#xff08;1&#xff09;自己的电脑有时在整理或者下载东西&#xff0c;需要很长时间等待。但是自己因为要休息的原因&#xff0c;不能一直等在电脑弄完后关机。所以这时需要对XP设置定时关机。比如预计这个下载任务完毕后在23:50可以关机&#xff0c;那么点击开始&#xff0…

当当花160买400的书,确定不囤一波?

天空飘来五个字&#xff0c;快要开学啦快快让路 ║ 今天我要去上学喽新学期我决定一定要努力学习没有新书给我充电怎么行&#xff1f;每次买完新书&#xff0c;感觉都是在开一场私人签售会哈哈哈这感觉真不错当当网自营图书大促>> 每满100减50 <<满200减100满300减…

stl取出字符串中的字符_在C ++ STL中使用比较运算符比较两个字符串

stl取出字符串中的字符字符串作为数据类型 (String as datatype) In C, we know string basically a character array terminated by \0. Thus to operate with the string we define character array. But in C, the standard library gives us the facility to use the strin…

万字详解Lambda、Stream和日期

作者&#xff1a;虚无境来源&#xff1a;cnblogs.com/xuwujing/p/10145691.html前言本篇主要讲述是Java中JDK1.8的一些语法特性的使用&#xff0c;主要是Lambda、Stream和LocalDate日期的一些使用。Lambda“Lambda 表达式(lambda expression)是一个匿名函数&#xff0c;Lambda表…

Python 换行符

raw字符串与多行字符串如果一个字符串包含很多需要转义的字符&#xff0c;对每一个字符都进行转义会很麻烦。为了避免这种情况&#xff0c;我们可以在字符串前面加个前缀 r &#xff0c;表示这是一个 raw 字符串&#xff0c;里面的字符就不需要转义了。例如&#xff1a;r\(~_~)…

vb的一些搞怪的操作

VB代码之&#xff1a;鼠标锁option ExplicitPrivate Type RECT Left As Long Top As Long Right As Long Bottom As Long End TypePrivate Declare Function ClipCursor Lib "user32" (lpRect As Any) As LongPrivate Sub Command1_Click()锁定鼠标 Dim r As RECT r.…

给51单片机初学者的建议

凡是diy爱好者都应该知道单片机&#xff0c;用直白的话说他就是单片微型计算机&#xff0c;能进行编程而后实现简单的自动化&#xff0c;智能化。 刚入门的时候&#xff0c;看到一些专业名词简直不知道说的是什么&#xff0c;比如寄存器、定时器、计数器、中断等等&#xff0c…

ai推理_人工智能推理能力问答

ai推理1) Which of the following statements correctly define the concept of Inference in AI? It is the way in which facts and information are stored in the storage system of the agentWhen we conclude the facts and figures to reach a particular decision, th…

Java 中 10 大坑爹功能!

今天我们就来聊一下 Java 中的 10 大坑爹功能&#xff0c;它们分别是&#xff1a;1.switch必须加上break才结束2.逻辑运算符的“短路”现象3.数组下标从零开始4.ArrayList遍历删除时报错5.字符转成数字的坑6.while循环体的“障眼法”7.Integer类有缓存8.空方法体导致死循环9.神…

WinXP下变量方式表达对应路径说明

在一些批处理或者系统技巧操作教程文章中&#xff0c;我们常常会看到一些形如 %windir% 或者 %systemdrive% 的变量。这些变量都代表着什么含义呢&#xff1f;下面西部e网的icech为大家整理了在Windows XP下系统变量方式表达相对应的路径&#xff0c;大家可以看得更加清楚明白了…

js 添加事件 attachEvent 和 addEventListener 的区别

1、addEventListener 适用w3c标准方法addEventListener绑定事件&#xff0c;如下&#xff0c;事件的执行顺序和绑定顺序一致&#xff0c;执行顺序为method1->method2->method3 //element.addEventListener(type,listener,useCapture);btn1Obj.addEventListener("cli…