Tomcat的**访问日志(Access Log)**是识别慢速Servlet的关键工具,它会记录每个请求的响应时间(如%D或%T字段)。需先确保访问日志已启用,并配置包含响应时间的pattern。
server.xml的<Host>标签内添加以下配置(若未启用):<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="localhost_access_log."
suffix=".txt"
pattern="%h %l %u %t "%r" %s %b %D" <!-- %D表示响应时间(毫秒) -->
resolveHosts="false"/>
其中,%D是核心字段,记录请求从接收至完成的总时间(单位:毫秒);%r记录请求行(含URL、方法),%s记录状态码,%b记录响应大小。grep、awk)筛选响应时间超过阈值的记录。例如,筛选处理时间超过1秒(1000毫秒)的请求:grep -E '[0-9]{4}$' logs/localhost_access_log.*.txt | awk -F ' ' '$NF > 1000 {print $0}'
或使用更精准的正则匹配(针对%D字段):awk '/\[.*\]/ && $NF > 1000' logs/localhost_access_log.*.txt
输出结果会显示慢请求的IP、时间、URL、状态码及处理时间,从中可定位到对应的Servlet(通过URL路径推断,如/api/report/generate对应ReportServlet)。**Catalina日志(catalina.out)**记录了Servlet的调用栈和异常信息,若慢速请求伴随异常或长时间阻塞,可通过该日志进一步分析。
grep "15/Oct/2023:14:30:45" catalina.out | grep "ReportServlet"
输出示例:2023-10-15 14:30:45.678 INFO [http-nio-8080-exec-10] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [ReportServlet] in context with path [] threw exception [Servlet execution threw an exception] with root cause
此处[ReportServlet]即为处理慢请求的Servlet。OutOfMemoryError、SQLException或长时间阻塞(如线程等待),Catalina日志会记录相关异常。例如,数据库查询慢会导致SQLException,可通过异常堆栈定位到具体的SQL语句或数据库操作。对于大规模应用,手动分析日志效率低,可借助以下工具自动化识别慢速Servlet:
#!/bin/bash
LOG_FILE="logs/localhost_access_log.*.txt"
THRESHOLD=800
awk -F ' ' -v threshold=$THRESHOLD '
$NF > threshold {url[$7]++; time[$7]+=$NF}
END {for (u in url) print u, url[u], time[u]}' $LOG_FILE | sort -k3 -nr
输出结果会显示Top慢URL及总处理时间,帮助快速定位高频慢Servlet。识别慢速Servlet后,需结合以下方法优化:
service()方法中执行高延迟逻辑(如直接操作数据库)。EXPLAIN分析执行计划)、配置连接池(如HikariCP的slowQueryThresholdMillis参数,记录慢SQL)。@Async)、读写分离或缓存(如Redis)减少数据库压力。