写点什么

如何快速对应用系统做一个 360 度画像诊断?

用户头像
姜戈
关注
发布于: 2020 年 05 月 09 日
如何快速对应用系统做一个360度画像诊断?

如何快速对应用系统做一个 360 度的画像诊断?

1. 为什么要诊断?

2. 诊断的策略是什么?

3. 如何快速地完成诊断?

 

一、为什么要诊断?

企业应用开发过程中,肯定会遇到以下问题:

a.进程消耗 CPU 飙升、内存利用率暴增,如何定位代码?

b.数据库连接数被耗尽怎么办?

c.各类 OOM 如何预防?

d.线程死锁、锁争用、上下文切换太频繁怎么办?

 

无论多复杂的系统运行在 Linux 之上,其实它就是一个进程。任何东西在操作系统层面,都是以文件的形式来存储的。进程也不例外,所以从操作系统的层面,只需要关注进程和线程即可。

 

例如:ll  /proc/{pid}/    展示此进程(pid)的文件目录,其中包含日志输出位置、系统加载哪些 JAR 包,以及还可以知道系统跟哪些外部应用在交互(ll /proc/{pid}/fd |grep socket),包括使用的哪些中间件服务,都可以从 socket 找到。

 

proc 文件夹下包含所有的进程(Process)等信息。

 

二、诊断的策略是什么?

360 度画像包括以下指标:

a.  资源瓶颈

b.  连接

c.  TCP 状态

d.  业务日志

e.  OOM

f.   JVM

g.  CPU 飙升

h.  线程状态



业务系统从性能上看,系统性就关注两件事:一个是吞吐量,一个是系统的响应性。

 

先谈谈 CPU:

如果 CPU 的利用度不高,但是系统的吞吐量和响应性却不理想,这说明程序并没有忙于计算,可能问题出现在 IO 上。

 

再谈谈 IO:

IO 和 CPU 利用率一般是呈反比的,CPU 利用率高,则 IO 不大;IO 大,则 CPU 利用率就小。

关于 IO,磁盘 IO、驱动程序 IO 和内存换页率。

 

再检查网络带宽有没有问题。

 

如果 CPU、IO 和网络都看完了,并且 CPU 的利用率不高,IO 也不高,内存也不高,网络带宽使用也不高,但是系统性能还是上不去。那么这个程序一定是被阻塞了,可能是 CPU 在等待哪个锁,也可能是某个资源,比如接口返回,连接在等待等,包括上下文的切换。

 

影响系统性能的瓶颈有:磁盘 I/O、内存、CPU、网络 I/O

 

(1) IO 谁更快?

  L1>L2>>L3>>>....>>>Memory>>>>>>>...>>>>>Disk

  CPU  IO 内存 磁盘

 

(2)网络 IO

某些场景下,由于网络环境的不确定性,尤其是互联网上的数据读写,网络操作的速度可能比本地的 IO 要会更慢。

网络 IO 主要延时由: 服务器响应延时 + 带宽限制 + 网络延时 + 跳转路由延时 + 本地接收延时决定。(一般为几十到几千毫秒,受环境干扰极大)

(3)CPU

CPU 资源的争夺,将导致性能问题,主要是锁竞争,锁竞争会导致上下文切换频繁,带来严重的系统开销,表现就是内核态的 CPU 的利用率偏高

 

(4)内存

最可能是内存不足,对 JAVA 来说,关注 GC 就好

 

(5)连接

系统对外部依赖的中间件和接口

比如数据库连接,如果数据量过大或者连接超时,都是比较消耗性能的。

 

(6)异常

JAVA 异常的捕获和处理是非常消耗资源的,如果程序高频率的在异常处理,也会影响系统和性能。

 

三、如何快速地完成诊断?

(1) 资源诊断

CPU、IO、内存、磁盘、网络

方法:

##CPU 问题定位

先用 TOP 命令查看

其中 load average 最近 1, 5, 15 分钟的系统的平均负载。

系统的平均负载:在特定的时间间隔内,运行队列中,即 CPU 上运行,或者等待运行多少进程的平均进程数。

其中还有用户态的 CPU 和内核态的 CPU 使用占比等。

##再看看内存问题的定位,

pidstat -r -p {pid}  1  2  // 查看某个进程占用的物理内存和虚拟内存

pidstat -d -p {pid}  1  2  //查看某个进程 IO 使用情况

-r:  内存

-d:  IO

-u:  CPU

 

## IO 问题定位

vmstat 命令中 swpd 过高,通常是物理内存不够用了,swap 的消耗主要关注它的 IO。

 

##网络问题的定位

trace 命令可以用来跟踪进程的执行和系统的调用

strace  -T 之间的参数可以显示具体的进程系统调用的情况

网络的 IO 也可以通过 cat /proc/interrupts 来查看,网络 IO 消耗需要关注、网卡中断,是否不均衡分配到各个 CPU。JAVA 的程序一般不会引起网络的 IO 消耗严重问题。

 

##磁盘问题的定位

dstat

 

(2) 连接诊断

应用往往还需要和外部的服务交互,比如数据库、缓存、消息中间件等

通过 netstat 查看,netstat -anop |grep 3306 查看 mysql 连接

 

(3) 线程异常

关注两点:线程状态、线程连接数

应用设计的时候需要考虑资源的限制,才能避免在某些时候因为资源过度消耗而崩溃。

线程数的控制就非常重要,程序无限制创建,最终导致其不可控,特别是隐藏在代码中的创建线程的方法。

当系统的 SY 值过高时,表示 Linux 要花费更多的时间,来进行线程的切换。Java 造成这种现象的主要原因是,创建的线程比较多,这些线程都处于不断的阻塞、锁等待、IO 等待和执行状态的变化过程中,这就产生了大量的上下文切换。Java 应用程序在创建线程时会操作 JVM 堆外的物理内存,太多的线程也会使用过多的物理内存。



如上,线程数太多,导致内存不足,应用已无法在创建新线程。

那通过什么方法查看线程数呢?

cat /proc/{pid}/status

top -bH -d 3 -p {pid}

pstree -p {pid} | wc -l

pstack {pid} | head -l

 

JAVA 线程状态主要包括以下几种:

Blocked (阻塞状态)

Waiting (无限时等待)

Time_Waiting (有限时等待)

New (初始化状态)

Runnable/Running  (可运行 / 运行状态)

Terminated (终止状态)

其中我们最要关注的是 Blocked、Waiting 和 Time_Waiting 这三种状态,特别是 Blocked 状态,在获取不到 CPU 执行时间的时候,此时系统性能就会下降。

 

(4)CPU 飙升诊断:分析定位程序 CPU 问题和查看线程状态的问题



(5)TCP 状态诊断

重点关注 CLOSE-WAIT 和 TIME-WAIT 状态,CLOSE-WAIT 是被动关闭方,TIME-WAIT 是主动关闭方。

如果客户端的并发量持续很高, 就会出现 TIME-WAIT 很高,有可能是客户端的连接连不上,可以用 netstat 查询定位。



(6) CPU 过载

如何定位你的代码,是哪段导致 CPU 过载呢?

#步骤一:用 top 或者 pidstat 定位具体的进程号

#步骤二:top -p {pid}   Shift+H 查看具体线程

#步骤三:将线程号(十进制)转化成十六进制 printf "%x\n" {pid} (线程栈中的线程程序号是以十六进制存储的)

#步骤四:jstack -l  {pid }  | grep -A 20  {16 进制的线程程序号}

 

(7) OOM 诊断

a.资源不足:可能内存分配过小

b.申请的资源太多:某一个对象被频繁申请,却没有被释放,内存不断泄露

c.资源耗尽:某一个资源被频繁申请,系统的资源在耗尽,例如不停的创建线程,不断的发起网络连接等

定位方法:

步骤一: 确认内存是否真的分配过小,jmap heap {pid}

步骤二:找到最耗费资源的对象,jmap -histo:live {pid} | more

步骤三:再确认你的资源是否耗尽,通过 pstree 和 netstat 来查看进程创建的线程数以及网络连接数等资源是否被耗尽

内存分析的最简单方式是通过内存的 dump 命令来导出内存栈

(jmap -dump:live,format=b,file=heap001  {pid}),不过会导致一次 JVM 的 Full GC,导出的文件可通过 MAT VisualVM 来查看

 

(8)JVM GC 问题

GC 会导致系统应用的暂时停顿,如果频繁的 GC,就会产生系统的延迟响应。

开启 GC 日志,可以方便观察定位,应用的停顿原因;也可以通过 jstat 来收集信息

jstat -gccause {pid} 1000

 

(9)日志诊断

检查日志的异常,Error 等各种数据库异常等,前提是日志栈没被吃掉

比如说监控系统,awk 命令来分析


#Reference

每日一课-360 度的画像诊断

发布于: 2020 年 05 月 09 日阅读数: 180
用户头像

姜戈

关注

每天前进30哩!!! 2018.02.27 加入

还未添加个人简介

评论

发布
暂无评论
如何快速对应用系统做一个360度画像诊断?