系统线上问题排查

一、磁盘空间不足问题

1、先用 df -h 从总体查看磁盘状态

文件系统                 容量  已用  可用 已用% 挂载点
devtmpfs                 1.6G     0  1.6G    0% /dev
tmpfs                    1.7G     0  1.7G    0% /dev/shm
tmpfs                    1.7G  170M  1.5G   11% /run
tmpfs                    1.7G     0  1.7G    0% /sys/fs/cgroup
/dev/mapper/centos-root   50G   16G   35G   32% /
/dev/sda2               1014M  198M  817M   20% /boot
/dev/mapper/centos-home  877G   32G  846G    4% /home
tmpfs                    329M     0  329M    0% /run/user/0

 tmpfs 类型的是 linux 的内存型文件系统,里面的数据是放在内存中的

一般就是看挂载点为根目录的 / 的容量,这里我只用了 32%、20%、4%,显然还没有达到瓶颈,但如果这里太大了,还要进一步看看是哪个目录大了。

2、此时用 du -sh * 命令,查看 / 路径下的各个文件和目录的大小

7.6G    CentOS-7-aarch64-Everything-2009.iso
12K     construn
du: 无法访问"data/docker/overlay2/6a14da0db0e3802e98fb82e44ce6f66a93506ebfb195a7e8d2b72f33d2ab9353/merged": 没有那个文件或目录
8.9G    data
0       docker
28K     elk
337M    ESXi-6.7.0-集成网卡镜像.iso
0       ftp
16K     git
28K     install.sh
298M    jenkins
13G     ll
0       log
21M     node-v14.15.3-linux-x64.tar.xz
213M    Python
90M     Python-3.8.3
23M     Python-3.8.3.tgz
0       tomcat
4.5M    wget-log
4.5G    work
0       wukong_data
12K     www
496M    yapi

找到最大的那个目录,进去,再次执行这个命令,直到找到最终占地面积特别大的文件或目录为止。

如果里面全都是普通文件,也可以用 ls -lh 命令,它的输出会更丰满一些

二、CPU 与内存使用率过高问题

1、top命令

top - 09:33:23 up 47 days, 19:29,  1 user,  load average: 0.32, 0.21, 0.20
Tasks: 178 total,   1 running, 175 sleeping,   0 stopped,   2 zombie
%Cpu(s):  3.7 us,  0.7 sy,  0.0 ni, 95.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  3362012 total,   392352 free,  2012588 used,   957072 buff/cache
KiB Swap:  3538940 total,  2668284 free,   870656 used.   869176 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                         
  600 polkitd   20   0 1597308  40592   4704 S   1.0  1.2 254:39.36 mongod                                                                                          
  685 readonly  20   0 1505348 235176   5528 S   0.3  7.0  83:07.98 node                                                                                            
  842 readonly  20   0 4824484 398444   6252 S   0.3 11.9 258:15.66 java                                                                                            
  922 root      20   0 4407232 499548   6284 S   0.3 14.9  49:55.13 java                                                                                            
19070 root      20   0  878028   5812   2432 S   0.3  0.2  46:13.79 BT-Task                                                                                         
26451 root      20   0  162152   2304   1528 R   0.3  0.1   0:00.08 top                                                                                             

下面的列表表示不同进程(PID)所占用的资源情况

PID 表示容器ID

VIRT 表示使用的虚拟内存数量,RES 表示使用的物理内存数量,SHR 表示使用的共享内存数量,这三者可以从内存角度看该进程的资源占用情况。

S 表示进程的状态,下面的值 S 表示睡眠,D 表示不可中断睡眠,R 表示运行,基本知道这三个就够了。

%CPU 表示CPU使用率,%MEM 自然就是内存使用率,看这俩值可以一目了然看谁占用的资源过高了。

TIME 表示累计 cpu 使用时长,感觉没什么用。

COMMAND 表示启动进程使用的命令行,Java 程序的话,可以看看 JVM 启动参数,看是否配置的合理。

如果专门看 Java 进程的情况,可以先 jps 命令找到它的 PID

19063 jar
1575 Bootstrap
21263 Jps

然后再 top -p 19063 专门看这个 Java 进程的情况

如果再细化到线程,可以加个 -H 参数,top -p 19063 -H

当然,top 命令已经可以分析内存了,如果想单独分析下内存,可以用小而美的命令,free -h

              total        used        free      shared  buff/cache   available
Mem:           3.2G        1.9G        365M        189M        940M        836M
Swap:          3.4G        839M        2.6G

这些参数的含义是:

total:内存总数

used:已经使用内存数

free:完全空闲内存

shared:多个进程共享的内存

buffers:用于块设备数据缓冲,记录文件系统 metadata(目录,权限,属性等)

cached:用于文件内容的缓冲

available:真正剩余的可被程序应用的内存数

一共有两行,mem 和 swap,mem 就是内存大小,swap 是交换区,是在物理磁盘上的一块区域,当内存不够用时,可以用这部分区域当内存。

可以用 swapon 命令来看下交换区的使用情况。

NAME      TYPE      SIZE USED PRIO
/dev/dm-1 partition 3.4G 839M   -2

三、网络延迟

1、netstat -a 查看所有连接中的 socket。

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:ddi-tcp-1       0.0.0.0:*               LISTEN     
tcp        0      0 localhost:smtp          0.0.0.0:*               LISTEN     
tcp        0      0 localhos:opsession-prxy 0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN     
tcp        0      0 c1:ddi-tcp-1            192.168.0.196:6652      ESTABLISHED
tcp        0      0 c1:ddi-tcp-1            192.168.0.196:13867     ESTABLISHED
tcp        0      0 localhost:50356         localhos:opsession-prxy ESTABLISHED
tcp        0      0 localhos:opsession-prxy localhost:50356         ESTABLISHED
tcp        0    256 c1:ssh                  192.168.0.90:55549      ESTABLISHED
tcp        0      0 c1:ddi-tcp-1            192.168.0.196:2194      ESTABLISHED
tcp        0      0 c1:ddi-tcp-1            192.168.0.196:14426     ESTABLISHED
tcp        0      0 c1:ddi-tcp-1            192.168.0.196:scenidm   ESTABLISHED

2、用 netstat -tnpa 命令可以查看所有 tcp 连接的信息,包括进程号

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:8888            0.0.0.0:*               LISTEN      19085/python        
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      490/master          
tcp        0      0 127.0.0.1:3307          0.0.0.0:*               LISTEN      21686/mysqld        
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1057/sshd           
tcp        0      0 192.168.0.70:8888       192.168.0.196:6652      ESTABLISHED 19085/python        
tcp        0      0 127.0.0.1:50526         127.0.0.1:3307          TIME_WAIT   -                   
tcp        0      0 192.168.0.70:8888       192.168.0.196:13867     ESTABLISHED 19085/python        
tcp        0      0 127.0.0.1:50356         127.0.0.1:3307          ESTABLISHED 21347/httpd         
tcp        0      0 127.0.0.1:3307          127.0.0.1:50356         ESTABLISHED 21686/mysqld        
tcp        0    208 192.168.0.70:22         192.168.0.90:55549      ESTABLISHED 20707/sshd: root@pt 
tcp        0      0 192.168.0.70:8888       192.168.0.196:2194      ESTABLISHED 19085/python        
tcp        0      0 192.168.0.70:8888       192.168.0.196:14426     ESTABLISHED 19085/python        
tcp        0      0 192.168.0.70:8888       192.168.0.196:7128      ESTABLISHED 19085/python 

得到进程号后就好说了配合 top 命令,ps -ef 命令,查看相关进程信息。

不过这些自带的网络命令,都不太灵活,一般我们有直观查看实时流量,然后进行一波统计分析的需求,这里介绍一个酷酷的命令。

输入 iftop -P 会得到这样的一个实时数据。

图片

中间的 <= => 这两个左右箭头,表示的是流量的方向。

TX:发送流量

RX:接收流量

TOTAL:总流量

Cumm:运行 iftop 到目前时间的总流量

peak:流量峰值

rates:分别表示过去 2s 10s 40s 的平均流量

当然这些是从机器上的,如果是一个接口响应耗时过长,一方面可能是由于机器本身所在的网络有问题。

一般这种问题也就是运维同学去解决,或者我们单节点重启一下,换台机器,就搞定了。

还有可能是服务提供方业务耗时严重,这个就需要去排查服务提供方的日志,机器负载,连接池占用情况等,分析问题,这也是我们平时开发碰到的主要问题。

四、Java 程序的问题分析

1、用 jmap -dump 分析堆内存中的快照

2、用 jmap -heap 查看堆内存设置与当前使用情况

3、用 jstack 查看 jvm 线程运行信息,上传到 fastthread.io 这个网站,直观地看一下,

一个线程需要占用大约 1M 的空间吧,而且不是占用 jvm 的内存空间,而是会占用操作系统空闲的内存空间。

我们的机器内存是 8G,堆内存占了 6G,线程数这么多快超过 2G 了,再加上操作系统里其他程序占用的内存,内存告警很正常,甚至可能 OOM。

所以,一方面我们可以减少线程数,另一方面可以把堆内存配置得小一点,使得堆内存加上线程占用的操作系统内存,不要超过 8G。

五、一些无法本地 debug 的调试技巧

有的时候线上忘记在关键节点打日志了,会导致一些问题,比如不知道方法入参的值,不知道某方法中具体某一步的耗时。

我一般用阿里的一款贼牛逼的工具 arthas 来排查。

先申请个线上机器的接近 root 的权限,然后把 arthas 工具下载到机器上,可以直接机器上下载:

wget https://alibaba.github.io/arthas/arthas-boot.jar

使用 watch 命令可以实时观察一个方法的入参和出参。

使用 trace 命令可以跟踪某个方法的耗时,而且可以深入这个方法所调用的方法的各个耗时。

当然我就只用这俩功能,用作忘记打日志时的临时方案了,属于高射炮打蚊子。

实际上人家的功能超级强大,比如 dashboard 全局监控,thread 查看所有线程信息,包括状态和 CPU 使用率,thread -b 甚至可以直接定位到死锁信息,jad 命令进行反编译,ognl 命令查看某一个对象的具体值,大家可以去网上学习下。

这篇文章来源于转载,我觉得原文写的不错,可以去看看原文的排版及内容

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值