jdk本身给我们提供了两种工具用于监控JVM运行情况,其中一个是Jconsole,还有一个是jvisualvm,这两个工具都安装在jdk的bin目录下:
本文我们使用jconsule来监控jvm的运行情况。
- 启动项目
首先我们看一下项目的tomcat基本配置信息: - 端口号为60021,tomcat最大线程数为200,最小线程数为10
现在我们启动项目: - 项目已经启动了,接下来我们去查看jconsole的运行情况
- 查看jconsole
在jdk的bin目录下,我们双击jconsole.exe就可以启动程序了
Jconsole支持本地进程查看,还可以连接远程进程,比如我们服务部署在linux上面,就可以远程连接linux,来查看服务的运行情况,现在我们点击我们的本地服务打开页面,就是打了马赛克的那个服务,选择不安全的连接
主页信息,展示一个综合信息,包括,堆内存使用量,线程数,加载的类的数量,cpu占用率
当然我们也可以点击左上角的按钮,选择对应的模块只查看该模块信息,现在我们点击线程模块,去查看线程的使用情况
在线程这个模块可以看到tomcat初始化的10个线程,如果你要问我怎么知道这个就是tomcat初始化的10个线程,从两个方面来分析:
一、 tomcat线程命名就是这样的,这是经验,当然大家也可以去程序里面打印获取当前线程的名称,然后运行程序,就知道线程名称了。
二、 我们进行服务调用验证一下喽。
- 服务调用
我们简单写一个服务调用的方法,进行循环调用
public class Test {
public static void main(String[] args) throws URISyntaxException, IOException {
while (true) {
// 声明URIBuilder
URIBuilder uriBuilder = new URIBuilder("http://127.0.0.1:60021/v1/api/label?pageSize=500");
// 2 创建httpGet对象,相当于设置url请求地址
HttpGet httpGet = new HttpGet(uriBuilder.build());
httpGet.addHeader("potato-tenant-id", "72");
httpGet.addHeader("potato-client-id", "72");
// 3 使用HttpClient执行httpGet,相当于按回车,发起请求
HttpClient httpClient = HttpClients.createDefault();
HttpResponse response = httpClient.execute(httpGet);
// 解析数据封装HttpResult
if (response.getEntity() != null) {
System.out.println(EntityUtils.toString(response.getEntity(), "UTF-8"));
} else {
System.out.println(response.getStatusLine().getStatusCode());
}
}
}
}
运行程序,我们再次查看jconsole情况
可以看到,线程数立即激增,同时cpu使用率,堆内存使用量都有明显变化
- 再次查看jconsole
当我们停止请求,可以看到,线程数又恢复之前的情况,而且只保留了10个线程,其余线程执行完任务,都被tomcat线程池给回收了。
cpu的使用率也慢慢趋于平缓了,当然堆内存使用量需要一段时间,等垃圾回收机制触发后才会慢慢下降
- 对比tomcat运行情况
我们重新修改程序tomcat配置参数,重新启动项目和jconsole - 可以看到初始化tomcat只有5个线程:
- 然后我们再次请求可以看到,线程数最大到30,不会再次增加了,因为我们设置了最大线程数为30,而上面的演示最大线程都到了四五十了,因为上面最大线程数为200
- 停掉请求可以看到,线程只剩下5个了:
- 总结
Jconsole可以帮助我们查看线程池的运行情况,堆内存使用情况以及cpu占用情况,在线上环境可以监控,内存溢出,线程池的线程数不足,cpu使用突然飙高的情况。
当然针对以上情况我们也应该在程序中控制,
内存溢出优化:
递归调用优化;
不用的对象应该置空,垃圾回收机制可以快速回收释放内存,硬件增加内存。
cpu使用率突然飙高:
将定时任务与业务代码拆开分开部署,因为定时任务底层是采用死循环的机制,会增加cpu开销;
cas在使用时应该设置循环次数或者时间,不要一直循环;
引入监控系统,当cpu使用率超过一定值,系统会提示,进行风险的预控;
采用多核cpu。
线程池线程数不足:
合理增加最大线程数;
采用多核多线程cpu。