log4j2异步打印性能提升方式

 更新时间:2021年12月22日 15:01:30   作者:唐震宇  
这篇文章主要介绍了log4j2异步打印性能提升方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

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、生产者和消费者中有个序列计数器,指示缓冲区中当前正在被它所处理的元素。所有生产者或消费者都只可以修改它自己的序列计数器,但同时可以读取其他的序列计数器,内存屏障加序列号的方式实现了无锁的并发机制。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java 两种延时thread和timer详解及实例代码

    Java 两种延时thread和timer详解及实例代码

    这篇文章主要介绍了Java 两种延时thread和timer详解及实例代码的相关资料,需要的朋友可以参考下
    2017-02-02
  • springboot的logback配置源码解读

    springboot的logback配置源码解读

    这篇文章主要为大家介绍了springboot的logback配置,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • Spring如何更简单的读取和存储对象

    Spring如何更简单的读取和存储对象

    这篇文章主要给大家介绍了关于Spring如何更简单的读取和存储对象的相关资料,在Spring 中想要更简单的存储和读取对象的核⼼是使⽤注解,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-06-06
  • Elasticsearch学习之Terms set 查询

    Elasticsearch学习之Terms set 查询

    这篇文章主要为大家介绍了Elasticsearch学习Terms set 查询示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • Java多态性定义与用法实例详解

    Java多态性定义与用法实例详解

    这篇文章主要介绍了Java多态性定义与用法,较为详细的分析了多态的概念、功能以及java定义与实现面向对象多态性的相关操作技巧,需要的朋友可以参考下
    2017-09-09
  • Java网络通信基础编程(必看篇)

    Java网络通信基础编程(必看篇)

    下面小编就为大家带来一篇Java网络通信基础编程(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • 基于FLink实现实时安全检测的示例代码

    基于FLink实现实时安全检测的示例代码

    这篇文章主要为大家详细介绍了如何基于FLink实现实时安全检测的功能,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的可以了解一下
    2023-02-02
  • Java中方法的重载与重写举例比较

    Java中方法的重载与重写举例比较

    这篇文章主要给大家介绍了关于Java中方法的重载与重写的相关资料,Java中的方法重载和重写是面向对象编程中的两个重要概念,文中介绍的非常详细,需要的朋友可以参考下
    2023-07-07
  • Spring Boot集成MyBatis-Plus 自定义拦截器实现动态表名切换功能

    Spring Boot集成MyBatis-Plus 自定义拦截器实现动态表名切换功能

    本文介绍了如何在SpringBoot项目中集成MyBatis-Plus,并通过自定义拦截器实现动态表名切换,此外,还探讨了MyBatis拦截器在其他场景中的应用,如SQL日志记录、多租户数据隔离、数据权限控制等,感兴趣的朋友跟随小编一起看看吧
    2024-11-11
  • java高效实现大文件拷贝功能

    java高效实现大文件拷贝功能

    这篇文章主要为大家详细介绍了java高效实现大文件拷贝功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05

最新评论