测试中碰到响应时间慢、TPS上不去、访问页面转圈圈,该怎么分析?把从发请求到返回请求整个架构图画出来,分析整个链路中哪些地方可能导致这些问题。
通常碰到这些问题,都是由以下11种情况导致,下面我们挨个分析,查找问题。
1)客户端
原因:客户端请求发布出去,有可能导致页面转圈圈
排查:请求一下其他地址,若访问其他地址没问题,请求能发出去,则可排除客户端问题。
2)网络
原因:服务器网络很慢或者TCP/IP连接满了有可能导致访问结果很慢,页面在转圈圈
排查:
①netstat i查看服务器网络丢包情况
②ping服务器,查看是否有丢包
3)CPU load
原因:cpu高、负载高,资源竞争,抢时间片,线程等待cpu去调度
排查:top看cpu,负载有没问题
4)内存泄漏、gc
原因:
排查:oom时发请求无法在eden去new对象,请求无法处理,gc时对象new完,请求暂停处理,页面转圈圈
ps -ef |grep java
Jstat -gcutil pid,查看老年代是否满,看是否在不停full gc,如下图老年代没满,说明没有oom;FGC数量也没有增加,说明不是gc导致页面转圈圈
5)wait for io等待磁盘io
原因:等待磁盘io,cpu空闲不干活,导致页面转圈圈
排查:iostat -x,查看是否有io队列
* rrqm/s:每秒进行 merge 的读操作次数,即 delta(rmerge)/s 。 Ø
* wrqm/s:每秒进行 merge 的写操作次数,即 delta(wmerge)/s 。 Ø
* r/s:每秒完成的读 I/O 设备次数,即 delta(rio)/s 。 Ø
* w/s: 每秒完成的写 I/O 设备次数,即 delta(wio)/s 。 Ø
* rsec/s:每秒读扇区数,即 delta(rsect)/s。 Ø
* wsec/s:每秒写扇区数,即 delta(wsect)/s Ø
* rkB/s:每秒读K字节数,是 rsect/s 的一半,因为每扇区大小为512字节。 Ø
* wkB/s:每秒写K字节数,是 wsect/s 的一半 Ø
* avgrq-sz:平均每次设备I/O操作的数据大小 (扇区),即delta(rsect+wsect)/delta(rio+wio)
* avgqu-sz:平均I/O队列长度,即 delta(aveq)/s/1000 (因为aveq的单位为毫秒)。
* Await:请求队列中等待时间+svctm(服务时间) 单位是毫秒,按照每次IO平均。 ,即 delta(ruse+wuse)/delta(rio+wio) 。 一般地系统IO响应时间应该低于5ms,如果大于10ms就比较大了。 这个时间包括了队列时间和服务时间,也就是说,一 般情况下,await大于svctm,它们的差值越小,则说明队列时间越短,反之差值越大,队列时间越长,说明系统出了问题。 Ø
* Svctm:平均每次设备I/O操作的服务时间 (毫秒),即 delta(use)/delta(rio+wio) 。
* %util:一秒中有百分之多少的时间用于 I/O 操作,或者说一秒中有多少时间 I/O 队列是非空的, 即 delta(use)/s/1000 (因为use的单位为毫秒) 。
6)web容器排队、连接池
tomcat监听怎么配置
7)数据库连接池排队 连接池不释放
排查:查看数据库连接池是否满了
①查看项目配置文件中配置的最大连接数,一般配置文件在../webapps/dangdang_dk/WEB-INFO/class下,maxActive=20,代表最大连接数为20
②执行语句show PROCESSLIST,查看数据库连接数,若当前连接数=20则数据库连接池满
附加:
①数据库连接池有2个,一个是mysql数据库对外提供的连接数(所有的数据库加起来对外提供的连接数),在my.cnf中配置,一个是当前项目的数据库连接数
②如果是root帐号,你能看到所有用户的当前连接。如果是其它普通帐号,只能看到自己占用的连接。 show processlist;只列出前100条,如果想全列出请使用show full processlist;
8)慢查询
排查:前提,已开启数据库慢查询,show variables like 'slow_query%';查看祝健康慢查询日志中是否有慢查询语句
附加:开启慢查询的两种方法
①将slow_query_log 全局变量设置为“ON”状态
set global slow_query_log='ON';
设置慢查询日志存放的位置
set global slow_query_log_file='/opt/slow.log';
查询超过1秒就记录
set global long_query_time=1;
②修改配置文件my.cnf,在[mysqld]下的下方加入
slow_query_log = ON
slow_query_log_file = /usr/local/mysql/data/slow.log
long_query_time = 1
9)数据库死锁
原因:语句执行不了
排查:
①show engine innodb status查看status
②SELECT * FROM information_schema.INNODB_TRX; (定位哪个线程导致死锁)
10)线程死锁
①ps -ef |grep java,查找pid
②jstack pid > aaa,将线程栈文件重定向到aaa中
③过滤http线程,查看里面的blocked(monitor)状态线程,或者大量的waitting线程,如下图则是DbUtil.java文件中getConnection出现问题,导致线程死锁
11)业务逻辑