一、总览
服务发生异常,大概分为应用程序错误和系统资源错误。应用错误主要包括进程资源问题,应用依赖调用问题以及应用内部程序逻辑问题。系统错误包括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解析查看域名的信息