启用异步日志可显著减轻主线程压力,核心是将日志写入移至后台线程批量处理;Log4j2推荐AsyncLogger全局异步模式并调优RingBufferSize与WaitStrategy,Logback则用AsyncAppender配合适当queueSize和neverBlock参数,再配合禁用实时刷盘、滚动策略、占位符及动态日志级别控制,方能真正降低I/O开销。

直接用异步日志能显著减轻主线程压力,核心是把日志写入从业务线程里摘出来,交给后台线程批量处理,避免每次打日志都卡住业务逻辑。
Log4j2 中启用 AsyncAppender
Log4j2 原生支持高性能异步日志,依赖 Disruptor 无锁队列,吞吐量比同步高数倍:
- 在 pom.xml 中引入 Disruptor 依赖(Log4j2 2.17+ 已内置,旧版本需显式添加)
- 配置文件(log4j2.xml)中使用 AsyncAppender 包裹 FileAppender 或 RollingFileAppender
- 推荐用 AsyncLogger 模式(全局异步),比单个 Appender 更高效,只需在 Configuration 标签加
status="warn" monitorInterval="30",再将 Root Logger 改为<AsyncRoot level="info"> - 关键参数:
RingBufferSize(默认 256KB,高并发建议设为 1MB)、WaitStrategy(如 SleepingWaitStrategy 更省 CPU)
Logback 中配置 AsyncAppender
Logback 的异步能力通过 AsyncAppender 实现,本质是阻塞队列 + 后台消费线程:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 在 logback.xml 中定义一个普通 FileAppender(比如叫
FILE),再用<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">包裹它 - 设置
<queueSize>8192</queueSize>(默认 256,建议 2048–8192,太小易丢日志,太大占内存) - 开启
<includeCallerData>false</includeCallerData>(避免每次取调用栈,节省 CPU) - 注意:队列满时默认丢弃 INFO/DEBUG 日志,保障 ERROR 不丢;如需阻塞而非丢弃,设
<neverBlock>false</neverBlock>
关键配套优化不能少
光开异步还不够,得配合其他设置才能真正压降 I/O 开销:
立即学习“Java免费学习笔记(深入)”;
-
禁用实时刷盘:FileAppender 中关闭
immediateFlush="false",让操作系统决定何时落盘 -
用滚动策略控文件体积:优先选
SizeAndTimeBasedRollingPolicy(大小+时间组合),避免单文件过大或碎片过多 -
精简日志内容:避免
logger.info("user="+user.toString())这种拼接;改用占位符logger.info("user={}", user),不输出时连 toString() 都不调用 - 生产环境关 DEBUG:通过配置动态控制级别,比如 Spring Profile 切换,杜绝无效日志生成
效果验证与常见陷阱
配置完别忘了验证是否真生效:
- 看日志输出里是否有
[main](同步) vs(异步)线程名 - 压测对比:QPS 提升通常达 2–3 倍,平均延迟下降 50%+(实测异步模式下延迟可压到 1ms 级)
- 陷阱提醒:Log4j1 不支持原生异步,必须升级;Logback 若没配 queueSize 或 size 太小,仍可能因队列满而退化为同步


















