赞
踩
之前某个服务在压测环境中出现了问题,分析之后得知是log4jLogger对象争用厉害,很多线程阻塞在此。
以上问题证明log4j在高并发高QPS情况下,是存在性能问题的。
之后把log4j升级成了log4j2,并采取异步日志模式,解决了因日志造成的性能问题。
关于log4j与log4j2的性能对比文章有很多,本文不过多描述,给出几张结论图及原文链接,作为参考。
Log4j1、Logback 以及 Log4j2 性能测试对
上述图片由原文作者【ksfzhaohui】提供,特此感谢!
上述图片由原文作者【专注服务端】提供,特此感谢!
上述图片由原文作者【宫铭】提供,特此感谢!
因为每个项目的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>
<!-- 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>
org.apache.log4j
org.apache.logging.log4j
在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>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。