一、总览

服务发生异常,大概分为应用程序错误和系统资源错误。应用错误主要包括进程资源问题,应用依赖调用问题以及应用内部程序逻辑问题。系统错误包括CPU、内存、文件系统、磁盘IO和网络。接下来我们依次分析一下。

二、程序问题

2.1 进程系统资源

查看进程资源问题,可以参考下面的系统资源问题分析。

2.2 依赖服务

可以通过调用链和相关的拨测告警,查看依赖调用服务(如其他微服务,数据库,Redis,消息队列服务)是否出现问题,如果发生异常,则修复依赖服务。

2.3 应用内部逻辑问题

查看报错的具体接口,并定位到对应的代码块,分析代码并解决。

三、系统资源问题

3.1 CPU

首先介绍一下CPU根据运行的任务不同,由以下几个分类,以top输出为例,包块sys(系统态),user(用户态),nice(调整优先级用户进程),wa(IO等待),hi(硬中断),si(软中断)等。

我们排查思路是先通过top查看系统总的CPU使用情况,查看资源主要消耗在哪个类型?

如果是sys高,则内核态占用比较多资源,常见的是频繁的上下文切换。先通过vmstat查看系统的上下文切换和中断,再使用pidstat查看进程的自愿上下文切换和非自愿上下文切换,如果是非自愿上下文切换,进一步分析进程或线程是否大于CPU个数。如果是自愿上下文切换,可能是等待自愿自动切换,常见的等待IO,等待内存分配。

如果是user,那就是用户态使用CPU高,可以利用strace和perf分析使用率高的函数,并优化。

如果是wa高,是因为等待IO时间长,参考下文的IO分析。

如果是hi,si高。分析对应的文件/proc/interrupts、/proc/softirqs文件,找到变化最快的类型,然后进行分析。常见的如DDoS攻击导致的大量网络接收软中断。

3.2 内存

首先介绍内存的类型

系统内存使用率,已使用内存、剩余内存和可用内存。

进程的虚拟内存,实际内存和共享内存

cache缓存主要是文件系统的缓存,包括文件的读写。

buffer缓存区主要是磁盘的缓存,包括磁盘的读写。

swap是用磁盘替换内存,扩大内存的总量。主要关注内存的换入和换出。

最后要关注缺页异常,包括主缺页异常(SWAP介入)和次缺页异常(从物理内存分配)

排查思路我们先可以使用free,top查看内存的总体情况,如果swap有使用可以用vmstat查看swap的换入和换出。如果是用户进程使用高,可以使用pmap查看内存的分配,进一步使用memleak查看内存泄露。如果是缓存高,先通过vmstat查看缓存的趋势,如果一直升高再通过/proc/meminfo查看是可回收还是不可回收的,可回收的利用slabtop查看。也可以利用cachetop,cachestat查看缓存具体使用在哪些地方。

3.3 文件系统和磁盘

首先介绍文件系统类型,磁盘使用率,inode使用率,使用df -h,df-i查看。

各种缓存,页缓存(不可回收),目录缓存(slabtop),inode缓存(slabtop),文件系统的缓存。

其次介绍磁盘的类型,包括IOPS,使用率,吞吐率,IOPS和延迟。

排查问题先看IO使用率,使用iostat,sar,dstat查看IO的使用率,然后使用pidtsta和iotop查看使用率最高的进程,进一步使用strace + lsof 对应的文件;

其次使用vmstat查看缓存、缓存区和SWAP的使用。

最后使用smartctl查看是否磁盘坏分区。

四、网络

4.1 网络使用率

使用sar查看带宽使用率,使用iftop查看IP的带宽使用率,使用nethogs查看进程的带宽使用率。

4.2 TCP/IP协议

接下来,按照网络收发步骤一步一步分析:

链路层

链路层主要处理MAC寻址(ARP RARP),错误帧测,网络帧的传输。

首先查看中断的配置,中断有没有配置CPU亲和性(smp_affinity)或开启irqbalance

其次查看是否使用traffic control流量控制,为不同的网络流量配置Qos。使用tc命令。

最后查看网卡是否丢包,使用netstat -i命令。

IP层

从路由和转发的角度,查看一下内核参数

net.ipv4.ip-forward=1 # 开启IP转发
net.ipv4.ip_default_ttl=64 # 生存周期TTL
net.ipv4.conf.eth0.rp_filter=1 # 地址方向校验,防止IP欺骗

其次查看mtu大小,以太网默认是1500

ifconfig

TCP层

如果timeout比较多,可以优化以下参数

net.ipv4.tcp_max_tw_buckets
net.netfilter.nf_conntrack_max
net.ipv4.tcp_fin_timeout
net.netfilter.nf_conntrack_tcp_timeout_time_wait 
net.ipv4.tcp_tw_reuse
net.ipv4.ip_local_port_range 
fs.nr_open 
fs.file-max 

为了缓解 SYN FLOOD,优化以下参数

net.ipv4.tcp_max_syn_backlog 
net.ipv4.tcp_syncookies
net.ipv4.tcp_synack_retries

长连接场景中,优化以下参数

net.ipv4.tcp_keepalive_time
net.ipv4.tcp_keepalive_intvl
net.ipv4.tcp_keepalive_probes

可以使用netstat -s 统计TCP/IP 网络包的情况,使用ss -s 查看当前的连接数状态

套接字

net.core.optmem_max
net.core.rmem_max
net.core.wmem_max
net.ipv4.tcp_rmem
net.ipv4.tcp_wmem
net.ipv4.udp_mem
net.core.somaxconn

应用程序

查看应用启用的连接数大小

IPTABLE

首先查看有没有拦截策略,其次查看连接跟踪参数的大小

net.netfilter.nf_conntrack_max

DNS

使用dig 和nslookup解析查看域名的信息