性能监控工具选择
1.接口返回信息
使用jmeter插件的<聚合报告>统计接口的请求数、响应时间、平均响应时间、TPS、错误率等指标
2.服务器负载
使用jmeter插件<PerfMon Metrics Collector>统计服务器cpu、内存、硬盘IO、网络IO的趋势图
3.jvm性能指标
a.) jmap -heap pid 查看堆内存使用信息,用于查看新生代、老年代内存使用情况
b.) jmap -histo pid 查看java进程中class生成的对象占用的信息,压测中每隔2秒查看一次占用最大内存的class,可以用来定位内存溢出的原因
ps: jmap -histo 202190|grep “1:”|head -1
c.) jstat -gcutil pid 频率(毫秒) 总打印次数 查看gc情况,fullgc次数不能太频繁,每次fullgc时间不能太长,性能指标之一
制作监控脚本,在目标服务器启用websocket服务,打印以上信息,在静态网页上显示ws请求返回的信息,可以用来生成图表(主要用来集成到网站中,生成性能报告,其实jvisualvm结合jconsole.exe、jstat命令更详细好用)。
简单实现演示:
a.)启动websocket服务,连接之后会执行监控脚本
#!/bin/bash #一定要加/bin/bash,否则会报错 freightpid=`ps -ef|grep osp-financial-freight|grep -v \'grep\'|awk \'{print $2}\'` #jmap -histo $freightpid|head -20 #echo $freightpid for ((COUNT=1;COUNT<=10;COUNT++));do jmap -heap $freightpid|grep -E "used$"|awk \'{print $1}\'|tail -n 1 sleep 5 done
View Code
b.)js发起websocket请求,实时根据监控脚本的返回重新渲染图表。如图。
html代码如下:
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"><link rel="icon" href="https://static.jianshukeji.com/highcharts/images/favicon.ico"> 5 <meta name="viewport" content="width=device-width, initial-scale=1"> 6 <style> 7 /* css 代码 */ 8 </style> 9 <script src="https://img.hcharts.cn/highcharts/highcharts.js"></script> 10 <script src="https://img.hcharts.cn/highcharts/modules/exporting.js"></script> 11 <script src="https://img.hcharts.cn/highcharts-plugins/highcharts-zh_CN.js"></script> 12 </head> 13 <body> 14 <div id="container" style="min-width:400px;height:400px"></div> 15 <script> 16 Highcharts.setOptions({ 17 global: { 18 useUTC: false 19 } 20 }); 21 function activeLastPointToolip(chart) { 22 var points = chart.series[0].points; 23 chart.tooltip.refresh(points[points.length -1]); 24 } 25 var chart = Highcharts.chart(\'container\', { 26 chart: { 27 type: \'spline\', 28 marginRight: 10, 29 events: { 30 load: function () { 31 var temp =0; 32 var ws =new WebSocket(\'ws://172.31.52.18:8187\'); 33 ws.onopen = function(event){console.log("CONNECT")}; 34 ws.onmessage = function(event){console.log(event.data.split("%")[0]);temp=parseFloat(event.data.split("%")[0])}; 35 ws.onerror = function(event){console.log(event)}; 36 var series = this.series[0], 37 chart = this; 38 activeLastPointToolip(chart); 39 setInterval(function () { 40 var x = (new Date()).getTime(), // 当前时间 41 y = temp; // 随机值 42 series.addPoint([x, y], true, true); 43 activeLastPointToolip(chart); 44 }, 5000); 45 } 46 } 47 }, 48 title: { 49 text: \'新生代内存使用监控\' 50 }, 51 xAxis: { 52 type: \'datetime\', 53 tickPixelInterval: 150 54 }, 55 yAxis: { 56 title: { 57 text: null 58 } 59 }, 60 tooltip: { 61 formatter: function () { 62 return \'<b>\' + this.series.name + \'</b><br/>\' + 63 Highcharts.dateFormat(\'%Y-%m-%d %H:%M:%S\', this.x) + \'<br/>\' + 64 Highcharts.numberFormat(this.y, 6); 65 } 66 }, 67 legend: { 68 enabled: true 69 }, 70 series: [{ 71 name: \'新生代已用内存占比\', 72 data: (function () { 73 var temp =0; 74 var ws =new WebSocket(\'ws://172.31.52.18:8187\'); 75 ws.onopen = function(event){console.log("CONNECT")}; 76 ws.onmessage = function(event){temp=parseFloat(event.data.split("%")[0])}; 77 ws.onerror = function(event){console.log(event)}; 78 // 生成随机值 79 var data = [], 80 time = (new Date()).getTime(), 81 i; 82 for (i = -19; i <= 0; i += 1) { 83 data.push({ 84 x: time + i * 5000, 85 y: temp 86 }); 87 } 88 return data; 89 }()) 90 }] 91 }); 92 </script> 93 </body> 94 </html>
View Code
未完成之前,先使用jvisualvm.exe远程代替查看,或者直接命令行查看。
附jvisualvm.exe的远程使用教程:
在java程序的启动参数中增加:
-Djava.rmi.server.hostname=172.xx.xx.xx ////////本机地址
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=1099
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
启动之后如下图:
查看1099端口是否可用: lsof -i:1099,如下图即为可用,否则要在防火墙中添加
使用windows上的jvisualvm.exe,点击 远程-》右键-》rmi连接
进入之后可看到配有启动参数的java程序,点击监视,可查看该程序占用的cpu、堆内存占比、线程运行情况
jconsole.exe可以跟踪堆栈信息,连接方式rmi,同上
4.数据库性能查看语句
show global status like \’Thread%\’; //查看线程运行情况
innodb引擎查看死锁语句
select b.trx_mysql_thread_id AS \’被阻塞线程\’,
b.trx_query AS \’被阻塞SQL\’,
c.trx_mysql_thread_id AS \’阻塞线程\’,
(UNIX_TIMESTAMP()-UNIX_TIMESTAMP(c.trx_started)) AS \’阻塞时间\’
from information_schema.INNODB_LOCK_WAITS a
join information_schema.INNODB_TRX b on a.requesting_trx_id =b.trx_id
join information_schema.INNODB_TRX c on a.blocking_trx_id=c.trx_id
where (UNIX_TIMESTAMP()-UNIX_TIMESTAMP(c.trx_started))>60;