Tomcat Servlet高并发下默认日志无法打印全部内容问题咨询
问题根因分析
你当前遇到的高并发下日志丢失问题,核心是直接使用System.out.println输出日志导致的,和业务逻辑、数据入库逻辑无关:
System.out是JVM标准输出流,默认带有缓冲区,且全局只有一个实例、线程安全级别低,高并发下多线程同时写入时会出现激烈的锁竞争,极端情况下部分输出内容会被覆盖、或者缓冲区未及时刷新到磁盘,最终导致日志丢失。- 你代码中使用的
SimpleDateFormat是非线程安全类,多线程并发调用format方法时会出现格式化异常,甚至抛出运行时错误,也会导致对应请求的日志输出失败。 - 你并没有使用Tomcat自带的日志系统,Tomcat只是默认把应用的标准输出重定向到了
catalina.out文件,这个重定向流默认的缓冲区刷新策略是批量刷盘,高并发下很容易出现日志遗漏。
具体疑问解答
1. Tomcat默认日志系统是否不支持高并发场景?
Tomcat默认自带的JULI日志框架(基于java.util.logging封装)本身是支持高并发场景的,它内部做了线程安全、异步写入、自动刷盘的适配,正常情况下哪怕每秒几千请求都不会出现日志丢失的问题。你当前的问题是没有使用该日志框架,直接用了标准输出导致的,和Tomcat日志系统本身能力无关。
2. 是否应该改用Log4J作为日志框架?
优先建议你改用专业的日志框架,可选择Log4j2、Logback或者保留Tomcat自带的JULI,都比直接使用System.out更可靠:
- 专业日志框架都做了线程安全适配,支持配置同步/异步写入模式、缓冲区大小、刷盘策略,高并发下不会出现日志丢失的问题。
- 支持日志级别控制、滚动归档、自定义输出格式,后续检索排查问题也更方便。
- Log4j2的异步日志性能远高于Log4j 1.x版本,高并发场景下更推荐使用Log4j2。
优化建议
- 替换代码中所有
System.out.println、e.printStackTrace()的写法,统一使用日志框架的API输出日志。 - 把非线程安全的
SimpleDateFormat替换为Java 8+提供的DateTimeFormatter,避免多线程下格式化异常。 - 高并发场景下建议开启日志框架的异步写入功能,合理配置缓冲区大小和刷盘策略,平衡性能和日志可靠性。
- 若业务逻辑
SaveXML执行耗时长,建议改为异步线程池执行,避免占用Tomcat工作线程导致请求堆积。
内容的提问来源于stack exchange,提问作者willberthos
相关产品推荐
相关产品推荐

