核心是丢哪些、何时丢、怎么兜底:log4j2需显式配置discardingasyncqueuefullpolicy和审计日志独立通道(discardthreshold="0"),logback启用neverblock=true与discardingthreshold=80,配合immediateflush、限流降级和丢弃监控三重兜底。

高并发下配置异步日志丢弃策略,核心不是“要不要丢”,而是“丢哪些、何时丢、怎么兜底”。关键在于让业务线程不卡住,同时守住 ERROR/WARN 和审计类日志不丢失。
Log4j2:用 DiscardingAsyncQueueFullPolicy + 分级通道
默认策略会阻塞业务线程,必须显式切换为丢弃模式:
- 在
log4j2.xml的AsyncAppender或AsyncLogger中添加:<discardingasyncqueuefullpolicy></discardingasyncqueuefullpolicy> - 或通过 JVM 参数统一启用:
-Dlog4j2.AsyncQueueFullPolicy=DiscardingAsyncQueueFullPolicy - 审计日志必须走独立
AsyncLogger(如name="audit"),并设discardThreshold="0",确保它永不被丢 - 普通日志(INFO/DEBUG)可共用另一个 AsyncLogger,保留默认丢弃逻辑
Logback:neverBlock + discardingThreshold 精控丢弃水位
Logback 的 AsyncAppender 默认使用阻塞式 put(),需主动关闭:
- 配置
<neverblock>true</neverblock>,使队列满时调用非阻塞offer() - 设置
<discardingthreshold>80</discardingthreshold>:当队列剩余容量低于 20% 时,开始丢弃 TRACE/DEBUG/INFO 日志 - WARN 及以上级别默认不参与丢弃;如需保障,可配合自定义
Filter强制拦截低优先级日志 -
<queuesize></queuesize>建议设为 8192 或 32768(压测后定),256 太小,易频繁触发丢弃
丢弃之外的三重兜底
只靠丢弃策略不够,极端场景仍可能积压:
-
强制落盘保审计:对 audit appender 启用
immediateFlush="true",并配置同步 fallback(如磁盘卡顿时临时切到 ConsoleAppender) - 限流+降级:在日志输出前加简单计数器,单秒超阈值(如 1000 条)则跳过非 ERROR 日志
-
监控告警:通过 JMX(Log4j2)或 MBean(Logback)暴露
DiscardCount指标,接入 Prometheus 并设置丢弃率 > 0.1% 时告警
别忽略的性能细节
丢弃策略生效的前提是底层不拖后腿:
- 关闭
includeCallerData(避免每次取堆栈)、禁用%ex全量异常(改用%ex{short}) - 日志格式中不用
%class%method等动态字段,否则即使neverBlock=true也会因格式化卡主线程 - 确保磁盘 I/O 已优化:SSD、合理滚动策略(如按大小+时间双触发)、避免单文件过大导致 rename 卡顿
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











