如何通过Jolokia REST API获取线程级CPU使用率?求更佳指标建议
解决Tomcat线程级CPU使用率监控及CPU过载排查问题
刚好之前排查过类似的Tomcat CPU过载问题,结合Jolokia的使用经验,给你梳理下具体的实现方法和有用的监控指标:
一、通过Jolokia REST API获取线程级CPU使用率
Jolokia本质是把JMX MBean的指标通过REST接口暴露出来,要拿线程CPU数据,我们需要调用java.lang:type=Threading这个核心MBean:
获取所有线程的CPU时间数据
发送GET请求到Jolokia接口,读取ThreadCpuTime(线程占用的总CPU时间,单位纳秒)、ThreadUserTime(用户态CPU时间)和AllThreadIds(所有线程ID):GET /jolokia/read/java.lang:type=Threading/ThreadCpuTime,ThreadUserTime,AllThreadIds返回结果里,
ThreadCpuTime是一个数组,下标对应AllThreadIds里的线程ID,你可以通过两次采样的差值来计算使用率:计算公式:线程CPU使用率 = ((第二次采样值 - 第一次采样值) / 1e9) / 采样间隔(秒) / CPU核心数 * 100%
(除以1e9是把纳秒转成秒,除以核心数是因为ThreadCpuTime是所有核心的总时间)定位高CPU线程的具体代码
拿到CPU时间最高的线程ID后,调用getThreadInfo方法获取线程的堆栈跟踪,方便定位到具体的业务代码:GET /jolokia/exec/java.lang:type=Threading/getThreadInfo/[<线程ID>]/true把
<线程ID>换成你筛选出的高占用线程ID,true表示返回完整的堆栈信息。
二、排查CPU过载的关键补充指标
除了线程CPU使用率,这些指标能帮你更快定位根因:
- Tomcat线程池状态:监控
Catalina:type=ThreadPool,name="http-nio-8080"(名字根据你的HTTP连接器调整)的currentThreadCount、currentThreadsBusy、maxThreads,如果currentThreadsBusy接近maxThreads,说明请求堆积导致线程打满。 - GC性能指标:查看
java.lang:type=GarbageCollector,name=*下的CollectionCount和CollectionTime,频繁的Full GC甚至Minor GC都会导致CPU飙升,特别是内存泄漏引发的GC风暴。 - 请求处理耗时:通过
Catalina:type=GlobalRequestProcessor,name="http-nio-8080"的requestCount、processingTime、errorCount,判断是不是某类请求的处理时间过长,拖垮了CPU。 - 堆内存使用:读取
java.lang:type=Memory的HeapMemoryUsage,如果堆内存持续接近上限,大概率是内存泄漏或配置不足引发的连锁CPU问题。
三、实操小技巧
- 用curl快速测试接口:
curl -X GET "http://<你的Tomcat服务地址>:8080/jolokia/read/java.lang:type=Threading/ThreadCpuTime" - 如果线程数量多,可以先通过
ThreadCpuTime排序,找出Top N的高占用线程,再查堆栈,避免无效排查。 - 结合K8s的监控工具(比如Prometheus),可以把Jolokia的指标导入做可视化趋势图,更容易发现用户操作和CPU飙升的关联。
内容的提问来源于stack exchange,提问作者Marcos J.C Kichel
相关产品推荐
相关产品推荐

