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

1.前言

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

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

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

2.性能对比

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

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

    log4j与log4j2性能对比及log4j升级至log4j2方案_第1张图片
    上述图片由原文作者【ksfzhaohui】提供,特此感谢!

  2. logback log4j log4j2 性能实测

    log4j与log4j2性能对比及log4j升级至log4j2方案_第2张图片
    上述图片由原文作者【专注服务端】提供,特此感谢!

  3. 高性能队列——Disruptor

    log4j与log4j2性能对比及log4j升级至log4j2方案_第3张图片
    上述图片由原文作者【宫铭】提供,特此感谢!

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>
    
    <exclusion>
        <artifactId>log4jartifactId>
        <groupId>log4jgroupId>
    exclusion>
    <exclusion>
        <groupId>org.slf4jgroupId>
        <artifactId>log4jartifactId>
    exclusion>
    <exclusion>
        <groupId>org.slf4jgroupId>
        <artifactId>slf4j-log4j12artifactId>
    exclusion>
    
    <exclusion>
        <artifactId>spring-boot-starter-log4jartifactId>
        <groupId>org.springframework.bootgroupId>
    exclusion>
 
    
    <exclusion>
        <artifactId>logback-classicartifactId>
        <groupId>ch.qos.logbackgroupId>
    exclusion>
    <exclusion>
        <artifactId>logback-coreartifactId>
        <groupId>ch.qos.logbackgroupId>
    exclusion>
 
    
    <exclusion>
        <artifactId>slf4j-log4j12artifactId>
        <groupId>org.slf4jgroupId>
    exclusion>
     <exclusion>
        <artifactId>log4j-to-slf4jartifactId>
        <groupId>org.apache.logging.log4jgroupId>
    exclusion>
    <exclusion>
        <artifactId>slf4j-apiartifactId>
        <groupId>org.slf4jgroupId>
    exclusion>
exclusions>

4.2.增加log4j2的依赖包


<dependency>
    <groupId>org.apache.logging.log4jgroupId>
    <artifactId>log4j-apiartifactId>
    <version>2.11.1version>
dependency>
<dependency>
    <groupId>org.apache.logging.log4jgroupId>
    <artifactId>log4j-coreartifactId>
    <version>2.11.1version>
dependency>
<dependency>
    <groupId>org.apache.logging.log4jgroupId>
    <artifactId>log4j-webartifactId>
    <version>2.11.1version>
dependency>

<dependency>
    <groupId>org.apache.logging.log4jgroupId>
    <artifactId>log4j-slf4j-implartifactId>
    <version>2.11.1version>
dependency>

<dependency>
    <groupId>org.apache.logging.log4jgroupId>
    <artifactId>log4j-1.2-apiartifactId>
    <version>2.11.1version>
dependency>

<dependency>
    <groupId>com.lmaxgroupId>
    <artifactId>disruptorartifactId>
    <version>3.4.2version>
dependency>

<dependency>
    <groupId>org.slf4jgroupId>
    <artifactId>slf4j-apiartifactId>
dependency>

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(全异步),其性能优势依次递增。

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

    
    <configuration status="error" monitorInterval="30">
        <Properties>
            <Property name="baseDir">logProperty>
        Properties>
        
        <appenders>
            
            <Console name="Console" target="SYSTEM_OUT">
                
                <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
                <PatternLayout pattern="%d %5p %c:%L - %m %throwable{}%n"/>
            Console>
            
            <Async name="ASYNC" bufferSize="262144" includeLocation="true">
                <AppenderRef ref="RollingFile"/>
            Async>
            
            <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"/>
                
                <TimeBasedTriggeringPolicy interval="1"/>
                <DefaultRolloverStrategy>
                    
                    <Delete basePath="${baseDir}">
                        <IfFileName glob="info.log.*"/>
                        <IfLastModified age="7d"/>
                    Delete>
                DefaultRolloverStrategy>
            RollingFile>
        appenders>
        
        <loggers>
            <root level="INFO">
                <appender-ref ref="Console"/>
                <appender-ref ref="RollingFile"/>
            root>
            
            <logger name="org.hibernate.validator" level="ERROR"/>
        loggers>
    configuration>
    

你可能感兴趣的:(Log4j,技术方案)