当前位置:   article > 正文

log4j与log4j2性能对比及log4j升级至log4j2方案_log4j log4j2 性能

log4j log4j2 性能

1.前言

  • 之前某个服务在压测环境中出现了问题,分析之后得知是log4jLogger对象争用厉害,很多线程阻塞在此。

  • 以上问题证明log4j在高并发高QPS情况下,是存在性能问题的。

  • 之后把log4j升级成了log4j2,并采取异步日志模式,解决了因日志造成的性能问题。

2.性能对比

关于log4j与log4j2的性能对比文章有很多,本文不过多描述,给出几张结论图及原文链接,作为参考。

  1. Log4j1、Logback 以及 Log4j2 性能测试对

    在这里插入图片描述
    上述图片由原文作者【ksfzhaohui】提供,特此感谢!

  2. logback log4j log4j2 性能实测

    在这里插入图片描述
    上述图片由原文作者【专注服务端】提供,特此感谢!

  3. 高性能队列——Disruptor

    在这里插入图片描述
    上述图片由原文作者【宫铭】提供,特此感谢!

3.相关知识

  • 和日志相关的概念有:log4j、log4j2、logback、commons-logging、slf4j
  • 其中,log4j、log4j2、logback、commons-logging都是日志的具体实现包。
  • 其中,slf4j是一个门面,一个适配器,所有的日志代码都可以用slf4j来写,它会根据项目具体依赖的日志实现包进行日志操作。
  • 通过slf4j写日志的好处是,当更换日志的实现方案时,无需修改日志代码,只需修改pom.xml即可。
  • 推荐:通过slf4j写日志。
  • 推荐:通过lombok的@Slf4j注解写日志。

4.log4j升级至log4j2

4.1.排除旧的日志实现包

  • 因为每个项目的pom.xml多种多样,所以无法总结统一的排除方案,这里只汇总需要排除的包。

  • 也就是说,如果你的项目里有以下包,应该排除。

<exclusions>
    <!-- log4j 相关包 -->
    <exclusion>
        <artifactId>log4j</artifactId>
        <groupId>log4j</groupId>
    </exclusion>
    <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>log4j</artifactId>
    </exclusion>
    <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
    </exclusion>
    <!-- log4j 的springboot starter -->
    <exclusion>
        <artifactId>spring-boot-starter-log4j</artifactId>
        <groupId>org.springframework.boot</groupId>
    </exclusion>
 
    <!-- logback 相关包 -->
    <exclusion>
        <artifactId>logback-classic</artifactId>
        <groupId>ch.qos.logback</groupId>
    </exclusion>
    <exclusion>
        <artifactId>logback-core</artifactId>
        <groupId>ch.qos.logback</groupId>
    </exclusion>
 
    <!-- slf4j 相关包 -->
    <exclusion>
        <artifactId>slf4j-log4j12</artifactId>
        <groupId>org.slf4j</groupId>
    </exclusion>
     <exclusion>
        <artifactId>log4j-to-slf4j</artifactId>
        <groupId>org.apache.logging.log4j</groupId>
    </exclusion>
    <exclusion>
        <artifactId>slf4j-api</artifactId>
        <groupId>org.slf4j</groupId>
    </exclusion>
</exclusions>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

4.2.增加log4j2的依赖包

<!-- log4j2的api、core和web包 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.11.1</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.11.1</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-web</artifactId>
    <version>2.11.1</version>
</dependency>
<!-- slf4j与log4j2的连接包 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.11.1</version>
</dependency>
<!-- log4j与log4j2的连接包 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-1.2-api</artifactId>
    <version>2.11.1</version>
</dependency>
<!-- log4j2支撑完全异步模式的关键api -->
<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.4.2</version>
</dependency>
<!-- slf4j本身的api -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

4.3.修复编译报错

  • 如果之前代码中日志都是直接通过log4j编写的,则可能需要修改import路径。
  • 在log4j版本,Logger的包路径是org.apache.log4j
  • 在log4j2版本,Logger的包路径是org.apache.logging.log4j

4.4.替换日志配置文件

  • 在log4j版本,配置文件为log4j.xml或者log4j.properties。

  • 在log4j2版本,配置文件为log4j2.xml。

  • 在log4j2版本,支持三种异步方式:Sync(同步)、Async Appender(混合异步)和Loggers All Async(全异步),其性能优势依次递增。

  • 下面给出一份全异步的参考配置。

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration status="error" monitorInterval="30">
        <Properties>
            <Property name="baseDir">log</Property>
        </Properties>
        <!--先定义所有的appender-->
        <appenders>
            <!--这个输出控制台的配置-->
            <Console name="Console" target="SYSTEM_OUT">
                <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
                <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
                <PatternLayout pattern="%d %5p %c:%L - %m %throwable{}%n"/>
            </Console>
            <!--异步日志配置,指向配置引用AppenderRef-->
            <Async name="ASYNC" bufferSize="262144" includeLocation="true">
                <AppenderRef ref="RollingFile"/>
            </Async>
            <!--日志文件配置,filePattern为日志文件名称的格式-->
            <RollingFile name="RollingFile" fileName="${baseDir}/info.log" filePattern="${baseDir}/info.log.%d{yyyy-MM-dd}">
                <!--日志内容格式-->
                <PatternLayout pattern="%d %5p %c:%L - %m %throwable{separator( --> )}%n"/>
                <!--依据时间创建新的日志文件:1d-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <DefaultRolloverStrategy>
                    <!-- 在轮转时,删除7天之前的,命名符合规则的文件 -->
                    <Delete basePath="${baseDir}">
                        <IfFileName glob="info.log.*"/>
                        <IfLastModified age="7d"/>
                    </Delete>
                </DefaultRolloverStrategy>
            </RollingFile>
        </appenders>
        <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
        <loggers>
            <root level="INFO">
                <appender-ref ref="Console"/>
                <appender-ref ref="RollingFile"/>
            </root>
            <!--这里配置 过滤日志 -->
            <logger name="org.hibernate.validator" level="ERROR"/>
        </loggers>
    </configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/547997
推荐阅读
相关标签
  

闽ICP备14008679号