用夜莺监控 Tomcat
读取 Manager 应用的 /manager/status/all 接口,采集 JVM 内存、各连接器的线程与请求、流量和错误,需要 manager-gui 角色。
最后校对于
Tomcat 插件访问 Manager 应用的 /manager/status/all 接口,解析出 JVM 堆与各内存池的使用、每个连接器(HTTP、AJP)的线程池大小与忙碌数、请求数、处理时间、错误数、收发字节。
这个接口需要鉴权:在 tomcat-users.xml 里添加 manager-gui 角色的用户,并放开 webapps/manager/META-INF/context.xml 里的 RemoteAddrValve 限制(默认只允许本机访问),否则会收到 403。规则覆盖线程池耗尽、堆内存逼近上限、错误率升高和实例不可达。
模板里有什么
- 1 张仪表盘,共 12 个面板
- 6 条告警规则,每条附处置步骤
- Categraf 采集配置:
input.tomcat
怎么接入
-
安装 Categraf,把下面的配置放到
conf/input.tomcat/tomcat.toml,按实际地址和凭据改好后重启 Categraf。启动日志里出现input: local.tomcat started就说明插件已加载。# # collect interval# interval = 15# Gather metrics from the Tomcat server status page.[[instances]]## URL of the Tomcat server status# url = "http://127.0.0.1:8080/manager/status/all?XML=true"url = ""## HTTP Basic Auth Credentials# username = "tomcat"# password = "s3cret"## Request timeout# timeout = "5s"# # interval = global.interval * interval_times# interval_times = 1# important! use global unique string to specify instance# labels = { instance="192.168.1.2:8080", url="-" }## Optional TLS Config# use_tls = false# tls_min_version = "1.2"# tls_ca = "/etc/categraf/ca.pem"# tls_cert = "/etc/categraf/cert.pem"# tls_key = "/etc/categraf/key.pem"## Use TLS but skip chain & host verification# insecure_skip_verify = true -
在夜莺「集成中心」里找到 Tomcat,把仪表盘和告警规则导入到业务组。
-
导入的告警规则默认是停用的。先确认指标已经入库,再按自己环境的阈值逐条启用。
内置仪表盘
| 仪表盘 | 面板数 |
|---|---|
| Tomcat - categraf | 12 |
内置告警规则
共 6 条。每条给出触发条件(PromQL)和告警后的处置步骤,导入后可以直接改阈值。
Tomcat 实例不可达
S1 紧急 · 持续 1 分钟 · 触发条件:
tomcat_up == 0
处置步骤:
- 登录主机执行 ps -ef | grep catalina 与 ss -lntp | grep 8080 确认进程与端口;
- 进程存活则执行 curl -u <user>:<pass> 'http://127.0.0.1:8080/manager/status?XML=true' 验证,401/403 说明 manager 账号或 RemoteAddrValve 限制了采集端 IP;
- 进程不在则查看 logs/catalina.out 尾部定位退出原因(端口占用、内存不足、应用启动异常);
- 确认上游负载均衡已摘除该节点后再重启,避免流量继续打进来。
Tomcat 线程池接近打满
S1 紧急 · 持续 3 分钟 · 触发条件:
tomcat_connector_current_threads_busy / (tomcat_connector_max_threads > 0) * 100 > 85
处置步骤:
- 从告警标签取 name(Connector 名),用 jstack <pid> 抓线程栈,统计 http-nio-* 线程卡在哪个方法上;
- 大量线程卡在数据库或外部 HTTP 调用,说明是下游拖慢,先修下游并给调用加超时;
- 应急可调大 server.xml 中该 Connector 的 maxThreads,但要同步评估内存与下游承载能力;
- 长期建议给外部依赖加熔断(如 Resilience4j),避免下游抖动直接打满 Tomcat 线程池。
Tomcat 请求错误率过高
S2 警告 · 持续 5 分钟 · 触发条件:
rate(tomcat_connector_error_count[5m]) / (rate(tomcat_connector_request_count[5m]) > 0) * 100 > 5
处置步骤:
- 执行 grep -E ' (5[0-9]{2}|4[0-9]{2}) ' logs/localhost_access_log.*.txt | awk '{print $7}' | sort | uniq -c | sort -rn | head 找出报错集中的 URL;
- 5xx 去 logs/catalina.out 与应用日志里找对应时间点的异常栈;
- 4xx 集中在个别接口通常是上游传参或鉴权变更,联系调用方确认;
- 若错误由依赖超时引起,先给依赖调用加超时与降级,避免错误持续放大。
Tomcat 平均请求处理耗时过长
S2 警告 · 持续 5 分钟 · 触发条件:
rate(tomcat_connector_processing_time[5m]) / (rate(tomcat_connector_request_count[5m]) > 0) > 1000
处置步骤:
- 在 access log 的 pattern 里确认已带 %D,执行 awk '{print $NF, $7}' localhost_access_log.*.txt | sort -rn | head -20 找出最慢的 URL;
- 连续 jstack <pid> 抓 3 次线程栈做对比,定位长期停留的方法;
- 卡在数据库的去查慢查询与连接池等待(连接池打满时线程会阻塞在 getConnection);
- 卡在 GC 的用 jstat -gcutil <pid> 1s 确认 Full GC 频率,再按堆使用情况调整堆大小或排查内存泄漏。
Tomcat JVM 堆内存使用率过高
S2 警告 · 持续 5 分钟 · 触发条件:
(tomcat_jvm_memory_total - tomcat_jvm_memory_free) / (tomcat_jvm_memory_max > 0) * 100 > 85
处置步骤:
- 执行 jstat -gcutil <pid> 1s 10 观察 Full GC 频率与回收后老年代占用,回收后仍居高不下说明存在泄漏;
- 执行 jmap -histo:live <pid> | head -30 看对象排行,定位异常增长的类;
- 怀疑泄漏时用 jmap -dump:live,format=b,file=/tmp/heap.hprof <pid> 导出堆并用 MAT 分析引用链;
- 确认只是容量不足则调大 -Xmx 并同步评估物理内存,注意留出堆外内存空间。
Tomcat 老年代内存使用率过高
S2 警告 · 持续 5 分钟 · 触发条件:
tomcat_jvm_memorypool_used{name=~".*Old Gen|Tenured Gen"} / (tomcat_jvm_memorypool_max{name=~".*Old Gen|Tenured Gen"} > 0) * 100 > 90
处置步骤:
- 执行 jstat -gcold <pid> 1s 10 观察每次 Full GC 后老年代是否能降下来;
- 降不下来则执行 jmap -histo:live <pid> | head -30 找出占用最大的对象类型;
- 常见泄漏点是静态集合、ThreadLocal 未清理、类加载器泄漏(反复热部署导致),可用 jcmd <pid> GC.class_stats 辅助确认;
- 确认无泄漏后再考虑调大 -Xmx 或改用 G1 并调整 -XX:MaxGCPauseMillis。
相关链接
- [Tomcat 模板源文件](https://github.com/ccfos/nightingale/tree/main/integrations/Tomcat):仪表盘、规则和采集配置的 JSON 原文,欢迎提 PR。
- Categraf
tomcat插件文档:完整配置项和指标列表。 - 实践:监控 Java 应用
- 导入仪表盘和告警规则
- 核对指标是否入库
- 全部集成目录