测试中碰到响应时间慢、TPS上不去、访问页面转圈圈,该怎么分析?把从发请求到返回请求整个架构图画出来,分析整个链路中哪些地方可能导致这些问题。

通常碰到这些问题,都是由以下11种情况导致,下面我们挨个分析,查找问题。

1)客户端

原因:客户端请求发布出去,有可能导致页面转圈圈

排查:请求一下其他地址,若访问其他地址没问题,请求能发出去,则可排除客户端问题。

 

2)网络

原因:服务器网络很慢或者TCP/IP连接满了有可能导致访问结果很慢,页面在转圈圈

排查:

①netstat i查看服务器网络丢包情况

浏览器打开harbor一直在转圈_慢

②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导致页面转圈圈

浏览器打开harbor一直在转圈_慢_02

 

5)wait for io等待磁盘io

原因:等待磁盘io,cpu空闲不干活,导致页面转圈圈

排查:iostat -x,查看是否有io队列

浏览器打开harbor一直在转圈_慢_03

* 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出现问题,导致线程死锁

浏览器打开harbor一直在转圈_慢查询_04

 

11)业务逻辑