Log4j2引发应用CPU使用率过高问题求助
核心问题定位
从你的配置来看,CPU使用率过高主要源于三个核心问题:不必要的低级别日志生成、高开销的日志布局格式、冗余的路由配置。结合你"日志级别固定为info"的硬性要求,具体优化方案如下:
1. 强制统一日志级别为INFO,关闭低级别日志输出
当前配置里Root级别设为DEBUG,还有两个AsyncLogger分别用了DEBUG和ALL级别,这会导致大量低于INFO级别的日志被生成、处理,直接拉高CPU占用。按照要求把所有Logger级别统一改成INFO:
<AsyncLogger name="com.xyz.abc.rest" level="INFO"> <AppenderRef ref="RoutingMainLogFile" level="INFO" /> </AsyncLogger> <AsyncLogger name="com.xyz.abc.errorLogging" level="INFO"> <AppenderRef ref="RoutingDeviceErrorLogFile" level="INFO" /> </AsyncLogger> <Root level="INFO"> <AppenderRef ref="RoutingMainLogFile"/> </Root>
这一步能直接砍掉大量无意义的日志输出,是降低CPU消耗的最直接手段。
2. 替换高开销的%C{1.}布局参数
%C是通过堆栈跟踪获取调用类名,这个操作极其耗时,日志量越大,CPU占用越高。建议换成%c{1.}(使用Logger名称的短类名,性能开销小很多),如果业务不需要类名可以直接删除:
<!-- 原布局 --> <Pattern>%d %p %-40C{1.}[$${ctx:appIdUserId}] %m%n</Pattern> <!-- 修改后 --> <Pattern>%d %p %-40c{1.}[$${ctx:appIdUserId}] %m%n</Pattern>
这是日志场景下CPU优化的关键节点之一。
3. 移除冗余的Routing Appender
当前两个Routing Appender的pattern="$"没有任何实际路由逻辑,属于多余的包装,直接使用RollingRandomAccessFile即可,减少不必要的处理环节:
<!-- 替换原RoutingDeviceErrorLogFile配置 --> <RollingRandomAccessFile name="RoutingDeviceErrorLogFile" fileName="${loghome}/RoutingDeviceErrorLogFile.log" filePattern="${loghome}/%d{dd-MM-yyyy}-RoutingDeviceErrorLogFile-%i.log.gz" immediateFlush="false"> <PatternLayout> <Pattern>%d %p %-40c{1.} %m%n</Pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> <SizeBasedTriggeringPolicy size="20 MB" /> </Policies> <DefaultRolloverStrategy max="2000"/> </RollingRandomAccessFile> <!-- 替换原RoutingMainLogFile配置 --> <RollingRandomAccessFile name="MainLogFile" fileName="${loghome}/MainLogFile.log" filePattern="${loghome}/%d{dd-MM-yyyy}-MainLogFile-%i.log.gz" immediateFlush="false"> <PatternLayout> <Pattern>%d %p %-40c{1.}[$${ctx:appIdUserId}] %m%n</Pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> <SizeBasedTriggeringPolicy size="100 MB" /> <!-- 调大滚动阈值,减少滚动频率 --> </Policies> <DefaultRolloverStrategy max="500"/> <!-- 减少保留的旧日志文件数,降低文件管理开销 --> </RollingRandomAccessFile>
4. 优化日志滚动策略
原MainLogFile的滚动阈值是10MB,保留5000个文件,频繁的滚动和文件压缩会持续消耗CPU。建议把SizeBasedTriggeringPolicy的size调大到100MB,同时减少DefaultRolloverStrategy的max值,降低滚动频率和文件数量。
额外建议
如果做完以上优化后CPU还是偏高,可以检查线程dump中是否有大量日志相关线程(比如AsyncLogger的线程池线程)处于忙碌状态,此时可以调整AsyncLogger的线程池配置,增加队列容量或线程数,但优先解决前面的日志级别和布局问题,这才是最有效的优化手段。
内容的提问来源于stack exchange,提问作者Chinmaya Behura

