本篇文章小编给大家分享一下log4j2异步打印性能提升方式代码示例,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。
压测结果发现,log4j升级成log4j2之后对系统性能影响并不大,更改打印日志方式(同步修改成异步打印)
压测结果发现TPS在开始阶段提升较快,当压力上来之后,TPS下降迅速,不如同步的数据(log4j2用的版本是2.3)
分析原因
获取压测是堆栈日志如下:
发现线程都在跑LockSupport.parkNanos也就是unsafe.park(false, 1);(private static final Unsafe unsafe = Unsafe.getUnsafe();)这行代码。
具体功能是:调用 park后,线程将一直阻塞直到超时或者中断等条件出现。unpark可以终止一个挂起的线程,使其恢复正常。
经过分析压测,发现当并发量打的时候该方法造成了大量的线程切换,也就是说明消费速度跟不上生产速度。线程被频繁的休眠/唤醒导致 cpu使用率高,且性能较低。
解决方案
上边原因分析到了,查询下解决方案,发现了log4j的bug,已经在2.7版本修复,所以替换log4j2的版本为2.7(JDK版本需要1.7以上,否则回报(unsupported major.minor version 51.0))
个人推荐JDK版本使用1.8。
具体代码变动如下:
没有了unsafe.park(false, 1); 被block的线程没有一直被调度
log4j2性能提升点
1、log4j1写日志多线程情况是阻塞的,log4j2不会阻塞,生产者只负责生产,通过无锁队列ringbuffer的无阻塞内存队列作为缓冲(即使用Disruptor),多生产者多线程的竞争是通过CAS实现,性能较高,至于最后落地,虽然两者都会调用synchronized方法写入日志,log4j2的asynclogger支持多个消费者,每个消费者取一批待处理的日志,类似于分段,用于提高性能
2、Disruptor简介
log4j2之所以能在异步写日志时性能提高这么多,离不开优秀的mq组件disruptor。
disruptor的主要设计思想是无锁的高并发,在设计上采用内存屏障的机制和CAS操作实现此思想。主流的并发程序
都离不开锁对资源的管控,或者尽量避开锁的使用。
理解为以下三点
1、有一个基于数组的循环数据结构(环装缓冲区)。这个循环数据结构,它是个拥有多个可用元素引用的数组。预先分配了对象内存空间。生产者与消费者通过这个循环数据结构进行读写操作,并不会有锁或资源竞争。
2、在Disruptor中,采用消费者-生产者模型进行读写的分离,所有事件(events)以组播的方式被发布给所有消费者,以便下游队列通过并行的方式进行消费。因为消费者的并行消费,需要协调消费者间的依赖关系。
3、生产者和消费者中有个序列计数器,指示缓冲区中当前正在被它所处理的元素。所有生产者或消费者都只可以修改它自己的序列计数器,但同时可以读取其他的序列计数器,内存屏障加序列号的方式实现了无锁的并发机制。
忍者必须死34399账号登录版 最新版v1.0.138v2.0.72
下载勇者秘境oppo版 安卓版v1.0.5
下载忍者必须死3一加版 最新版v1.0.138v2.0.72
下载绝世仙王官方正版 最新安卓版v1.0.49
下载Goat Simulator 3手机版 安卓版v1.0.8.2
Goat Simulator 3手机版是一个非常有趣的模拟游
Goat Simulator 3国际服 安卓版v1.0.8.2
Goat Simulator 3国际版是一个非常有趣的山羊模
烟花燃放模拟器中文版 2025最新版v1.0
烟花燃放模拟器是款仿真的烟花绽放模拟器类型单机小游戏,全方位
我的世界动漫世界 手机版v友y整合
我的世界动漫世界模组整合包是一款加入了动漫元素的素材整合包,
我的世界贝爷生存整合包 最新版v隔壁老王
我的世界MITE贝爷生存整合包是一款根据原版MC制作的魔改整