Ubuntu Tomcat日志定位性能瓶颈的实用方法
一 准备可观测性
- 启用并规范日志输出:在 $CATALINA_HOME/conf/logging.properties 使用异步日志处理器(AsyncFileHandler),为访问日志与业务日志设置合理保留天数,避免磁盘与I/O成为新瓶颈;必要时将 CoyoteAdapter 调为 FINE 以输出请求处理耗时。
- 打开访问日志并输出关键字段:在 conf/server.xml 的 AccessLogValve 中使用包含 %D(处理时间,毫秒)的格式,便于直接定位慢请求与高峰时段。
- 打开并轮转 GC 日志:在 catalina.sh/catalina.bat 的 CATALINA_OPTS 中加入 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/app/gc-%t.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=20 -XX:GCLogFileSize=10M,为后续 GC 瓶颈分析留痕。
- 日志目录与文件:Tomcat 日志通常在 $CATALINA_HOME/logs,核心文件包括 catalina.out/catalina..log、localhost..log、localhost_access_log.*.txt 等。
二 日志侧的关键信号与定位路径
- 连接器与线程池饱和:访问日志中大量 5xx/4xx 伴随 %D 明显增大,且 catalina.out 出现线程池相关异常(如无法创建新线程),常见于 server.xml Executor/maxThreads 配置不足或突发流量导致排队。
- 连接数/文件描述符瓶颈:出现 java.net.SocketException: Too many open files 或访问日志显示连接激增,需结合系统 ulimit -n 与 Tomcat 连接器 maxConnections、acceptCount 一并核查。
- 内存与 GC 压力:日志出现 OutOfMemoryError: Java heap space,GC 日志显示 Full GC 频繁/停顿时间长,说明堆配置或对象生命周期需要优化。
- 数据库与慢查询:若应用或框架将 SQL 执行时间写入日志(如某些 ORM/驱动会输出 QTime=xxx),可用关键字检索并筛选阈值以上的慢查询,进一步联动数据库执行计划与索引优化。
- 磁盘 I/O 与网络:访问日志写入缓慢、系统 iostat 显示 await/svctm 高,或 iftop/nload 显示带宽打满,需考虑异步日志、SSD、压缩与限流等手段。
三 命令行快速筛查命令
- 定位异常与错误:
- grep -i “ERROR|Exception|OutOfMemoryError” $CATALINA_HOME/logs/catalina.*.log
- 按时间窗提取日志:
- sed -n ‘/2025-03-07 10:00:00/,/2025-03-07 11:00:00/p’ $CATALINA_HOME/logs/catalina.out > hour.log
- 访问日志慢请求 TopN(按 %D 毫秒):
- awk -F’"’ ‘$NF ~ /^[0-9]+$/ && $NF > 1000 {print $0}’ $CATALINA_HOME/logs/localhost_access_log.*.txt | sort -kNF -nr | head
- 统计 5xx 比例与高峰分布:
- awk ‘{codes[$9]++} END {for(c in codes) print c, codes[c]}’ $CATALINA_HOME/logs/localhost_access_log.*.txt
- 检索慢查询关键字(如 QTime):
- grep -i “QTime” $CATALINA_HOME/logs/*.log
- 系统资源佐证(配合日志时段):
- top -H -p $(jps | grep Bootstrap | awk ‘{print $1}’)
- jstat -gcutil 1s
- iostat -x 1 10
- iftop -t -s 30
四 阈值参考与常见瓶颈对照表
| 维度 |
关键指标 |
常见阈值参考 |
日志侧信号 |
建议动作 |
| 连接器/线程池 |
活跃线程、队列长度 |
活跃线程 > 80% 核心线程数 |
5xx 增多、%D 增大、线程创建失败异常 |
调整 maxThreads/acceptCount,优化慢接口与阻塞操作 |
| JVM 内存 |
堆使用率、GC 频率 |
使用率 > 85% 或 Full GC > 5 次/分钟 |
OOM、GC 日志长停顿 |
调整 -Xms/-Xmx、选择更合适的 GC、排查泄漏 |
| 访问性能 |
P95/P99 响应时间 |
P95 > 1s |
大量请求 %D 超过 1s |
SQL/缓存/异步化优化,限流降级 |
| 系统资源 |
CPU/磁盘/网络 |
CPU > 80% 持续 5 分钟 |
系统监控告警、iostat/iftop 异常 |
扩容、异步日志、SSD、带宽与连接治理 |
五 从日志到根因的闭环
- 现象到指标:先用访问日志的 %D 与状态码锁定慢请求与高峰时段,再用系统命令(top/jstat/iostat/iftop)验证资源是否打满。
- 线程与连接:当活跃线程接近上限或队列堆积,结合 server.xml Executor 与连接器参数(如 maxThreads、maxConnections、acceptCount)评估是否需要扩容或优化阻塞点。
- 内存与 GC:出现 OOM 或 Full GC 频繁,先抓取 heapdump 与 thread dump,定位大对象与线程竞争,再调整堆大小与 GC 策略。
- 数据库与下游:若日志暴露 QTime 或慢查询,联动数据库执行计划、索引与连接池配置,必要时引入缓存或异步处理。
- 验证与回归:每次调优后对比 P95/P99、吞吐、错误率 与 GC 指标,确保瓶颈真正解除且未引入新风险。