bufferedlogs 是 tomcat 的 jul 日志缓冲配置,仅影响 catalina.out 等内部日志,需通过 jvm 参数 -djava.util.logging.filehandler.buffered=true 启用,可减少 i/o 但存在延迟丢失风险;不适用于 log4j/logback 等应用日志框架。

Apache HTTP Server 本身并不提供 BufferedLogs 指令,该指令属于 Apache Tomcat(Java 应用服务器),而非 Apache HTTP Server(通常简称 httpd)。混淆常源于两者同属 Apache 软件基金会且名称相近。在 Tomcat 中,BufferedLogs 是 java.util.logging(JUL)日志系统的一个底层配置选项,**仅影响 Tomcat 自身的内部日志(如 catalina.out、localhost.log 等),与 Java 应用中使用的 Log4j、Logback 等日志框架无关**。
BufferedLogs 的作用机制
Tomcat 启动时通过 java.util.logging.FileHandler 输出日志,默认情况下每条日志记录都会触发一次磁盘写入(即未启用缓冲)。当设置 BufferedLogs=true(需配合 JVM 参数或 logging.properties 配置),FileHandler 会在内存中累积日志内容,达到缓冲区大小(默认约 8KB)或显式 flush 时才批量写入文件。这减少了系统调用(write())和磁盘 I/O 次数,在高并发日志写入场景下可降低 CPU 和 I/O 开销。
如何启用 BufferedLogs
该选项不能通过 Tomcat 的 server.xml 或 logging.properties 直接开关,而是需在启动时通过 JVM 系统属性激活:
- 在
setenv.sh(Linux/macOS)或setenv.bat(Windows)中添加:
JAVA_OPTS="$JAVA_OPTS -Djava.util.logging.FileHandler.buffered=true" - 确保 Tomcat 使用的是标准 JUL FileHandler(默认即如此),不被自定义 Handler 替换
- 缓冲区大小可通过
-Djava.util.logging.FileHandler.bufferSize=16384调整(单位字节)
对高并发写入的实际效果与局限
BufferedLogs 在以下情况有明显收益:
- 大量短日志频繁输出(如每秒数千条 DEBUG 级别请求日志)
- 磁盘 I/O 成为瓶颈(尤其机械硬盘或低配云盘)
- 日志写入线程竞争激烈(多个 Container 组件同时打日志)
但需注意:
- 缓冲会带来最多几秒的日志延迟(断电或异常退出可能导致最后一批日志丢失)
- 无法缓解应用层日志框架(如 Log4j2 的 AsyncLogger)的性能问题
- 若已使用异步日志(如 Log4j2 RingBuffer + Disruptor)、日志聚合(Fluentd/Logstash)或写入 SSD,收益微乎其微
更推荐的高并发日志优化路径
针对 Java Web 应用的高并发日志场景,应优先考虑更现代、可控性更强的方式:
- 应用层统一使用异步日志框架:Log4j2(
AsyncLogger)、Logback(AsyncAppender)并调大队列容量 - 将日志输出重定向到高性能管道(如
syslog-ng、journalctl)或消息队列(Kafka) - 避免在业务关键路径中输出高频率日志(如每个 HTTP 请求都打 INFO 日志)
- 对 Tomcat 自身日志,可关闭冗余日志(如禁用
AccessLogValve或调整其格式/频率)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










