1、I/O问题一般排查步骤
1、使用top查看整体情况
2、iostat
- iostat -x -d 1 观察 I/O 的使用情况
3、pidstat
- pidstat -d 1 显示每个进程的 I/O 情况
4、strace
- strace -p 18940 分析进程系统调用
- strace -f -p 27458 查看线程的数据读取情况
- strace -p 12280 2>&1 | grep write 过滤write
- strace -f -T -tt -p 9085 -f表示跟踪子进程和子线程,-T表示显示系统调用的时长,-tt表示显示跟踪时间
- strace -f -p 9085 -T -tt -e fdatasync 通过 -e 选项观察系统调用的执行情况
5、lsof
- lsof -p 18940 进程 18940 都打开了哪些文件
6、ps
- ps -efT | grep 514 查找线程属于哪个进程
7、pstree
- pstree -a -p 27458 -a表示显示命令行参数
8、其他
- while true; do curl http://192.168.0.10:10000/products/geektime; sleep 5; done
2、Linux CPU问题一般排查步骤
1、uptime
- uptime
- watch -d uptime
2、stress
- stress --cpu 1 --timeout 600 模拟CPU 使用率 100% 的场景
- stress -i 1 --timeout 600 模拟 I/O 压力
- stress -c 8 --timeout 600 模拟 8 个进程
3、mpstat
- mpstat -P ALL 5 # -P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据
- mpstat -P ALL 5 1 显示所有CPU的指标,并在间隔5秒输出一组数据
4、pidstat
- pidstat -u 5 1 间隔5秒后输出一组CPU数据
- pidstat -w 5 每隔5秒输出1组数据 -w 查看进程的上下文切换情况
- cswch ,表示每秒自愿上下文切换(voluntary context switches)的次数
- nvcswch ,表示每秒非自愿上下文切换(non voluntary context switches)的次数
- pidstat -w -u 1 每隔1秒输出1组数据,-w参数表示输出进程切换指标,而-u参数则表示输出CPU使用指标
- pidstat -wt 1 -wt 参数表示输出线程的上下文切换指标
- pidstat 1 5 每隔1秒输出一组数据,共输出5组
- pidstat -p 24344
- pidstat -d -p 4344 1 3 -d 展示 I/O 统计数据,-p 指定进程号,间隔 1 秒输出 3 组数据
5、vmstat
- vmstat 5 每隔5秒输出1组数据
- cs(context switch)是每秒上下文切换的次数。
- in(interrupt)则是每秒中断的次数。
- r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数。
- b(Blocked)则是处于不可中断睡眠状态的进程数。
- vmstat 1 1 间隔1秒后输出1组数据
6、sysbench
- sysbench --threads=10 --max-time=300 threads run 以10个线程运行5分钟的基准测试,模拟多线程切换的问题
7、perf
- perf top 实时显示占用 CPU 时钟最多的函数或者指令
- 第一列 Overhead ,是该符号的性能事件在所有采样中的比例,用百分比来表示。
- 第二列 Shared ,是该函数或指令所在的动态共享对象(Dynamic Shared Object),如内核、进程名、动态链接库名、内核模块名等。
- 第三列 Object ,是动态共享对象的类型。比如 [.] 表示用户空间的可执行程序、或者动态链接库,而 [k] 则表示内核空间。
- 最后一列 Symbol 是符号名,也就是函数名。当函数名未知时,用十六进制的地址来表示。
- perf top -g -p 21515 -g开启调用关系分析,-p指定php-fpm的进程号21515
- perf record -g 记录性能事件
- perf report 查看报告
8、ab
- ab -c 10 -n 100 http://192.168.0.10:10000/
9、pstree
- pstree | grep stress
- pstree -aps 3084 -a 表示输出命令行选项,p表PID吗,s表示指定进程的父进
10、dstat
- dstat 1 10 间隔1秒输出10组数据
11、strace
- strace -p 6082 分析进程的内核调用
12、sar
- sar -n DEV 1 -n DEV 表示显示网络收发的报告,间隔1秒输出一组数据
- 第一列:表示报告的时间。
- 第二列:IFACE 表示网卡。
- 第三、四列:rxpck/s 和 txpck/s 分别表示每秒接收、发送的网络帧数,也就是 PPS。
- 第五、六列:rxkB/s 和 txkB/s 分别表示每秒接收、发送的千字节数,也就是 BPS。
13、其他
- watch -d cat /proc/interrupts
- 自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题;
- 非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU 的确成了瓶颈;
- 中断次数变多了,说明 CPU 被中断处理程序占用,还需要通过查看 /proc/interrupts 文件来分析具体的中断类型。
- hping3 -S -p 80 -i u100 192.168.0.30
- -S参数表示设置TCP协议的SYN(同步序列号),-p表示目的端口为80
- -i u100表示每隔100微秒发送一个网络帧
- 注:如果你在实践过程中现象不明显,可以尝试把100调小,比如调成10甚至1
3、Linux 内存问题排查
1、vmstat
- vmstat 1
- buff 和 cache 就是我们前面看到的 Buffers 和 Cache,单位是 KB。
- bi 和 bo 则分别表示块设备读取和写入的大小,单位为块 / 秒。因为 Linux 中块的大小是 1KB,所以这个单位也就等价于 KB/s。
2、dd
- /dev/null,是一个空设备,也称为位桶(bit bucket),外号叫无底洞,任何写入它的输出都会被丢弃。
- /dev/zero,是一个输入设备,你可你用它来初始化文件。该设备无穷尽地提供0,可以使用任何你需要的数目,设备提供的要多的多。他可以用于向设备或文件写入字符串0。
- dd if=/dev/urandom of=/tmp/file bs=1M count=500 通过读取随机设备,生成一个 500MB 大小的文件
- dd if=/dev/urandom of=/dev/sdb1 bs=1M count=2048 向磁盘分区/dev/sdb1写入2G数据
- dd if=/dev/sda1 of=/dev/null bs=1M count=1024 从磁盘分区 /dev/sda1 中读取数据,写入空设备
- dd if=/tmp/file of=/dev/null 读取文件数据
- dd if=/dev/sda1 of=file bs=1M count=512 生成一个512MB的临时文件
- dd if=file of=/dev/null bs=1M 测试文件的读取速度
3、Buffer 和 Cache
- 写文件时会用到 Cache 缓存数据
- 写磁盘则会用到 Buffer 来缓存数据
- Cache 是文件读的缓存,但实际上,Cache 也会缓存写文件时的数据。
- 读文件时数据会缓存到 Cache 中,而读磁盘时数据会缓存到 Buffer 中
- 简单来说,Buffer 是对磁盘数据的缓存,而 Cache 是文件数据的缓存,它们既会用在读请求中,也会用在写请求中。
4、pcstat
[root@localhost ~]# yum -y install go
[root@localhost ~]# export GOPATH=~/go
[root@localhost ~]# export PATH=~/go/bin:$PATH
[root@localhost ~]# go get golang.org/x/sys/unix
[root@localhost ~]# git clone https://github.com/tobert/pcstat.git
[root@localhost ~]# cd pcstat
[root@localhost ~]# go build
[root@localhost ~]# cp -a pcstat /usr/local/bin
# 验证
[root@localhost ~]# pcstat /usr/local/bin/pcstat
5、sar
- sar -r -S 1 间隔1秒输出一组数据,-r表示显示内存使用情况,-S表示显示Swap使用情况
6、其他
- echo 3 > /proc/sys/vm/drop_caches 清理缓存
- watch -d grep -A 15 ‘Normal’ /proc/zoneinfo -A 表示仅显示Normal行以及之后的15行输出,-d 表示高亮变化的字段
- 创建swap
- fallocate -l 8G /mnt/swapfile
- 修改权限只有根用户可以访问
- chmod 600 /mnt/swapfile
- 配置Swap文件$ mkswap /mnt/swapfile
- 开启Swap$ swapon /mnt/swapfile
- swapoff -a && swapon -a
4、Linux 网络问题排查
1、网络性能测试
TCP/UDP 性能
-s表示启动服务端,-i表示汇报间隔,-p表示监听端口
[root@localhost ~]# iperf3 -s -i 1 -p 10000
# -c表示启动客户端,192.168.0.30为目标服务器的IP
# -b表示目标带宽(单位是bits/s)
# -t表示测试时间
# -P表示并发数,-p表示目标服务器监听端口
[root@localhost ~]# iperf3 -c 192.168.192.110 -b 1G -t 15 -P 2 -p 10000
HTTP 性能
[root@localhost ~]# yum -y install httpd-tools
目标机上运行nginx
[root@localhost ~]# docker run -p 82:80 -itd nginx
另一台机器上,运行 ab 命令,测试 Nginx 的性能
# -c表示并发请求数为1000,-n表示总的请求数为10000
[root@localhost ~]# ab -c 1000 -n 10000 http://192.168.192.120:82/
ab输出说明:
- Requests per second 为 1074;
- 每个请求的延迟(Time per request)分为两行,第一行的 927 ms 表示平均延迟,包括了线程运行的调度时间和网络请求响应时间,而下一行的 0.927ms ,则表示实际请求的响应时间;
- Transfer rate 表示吞吐量(BPS)为 890 KB/s
应用负载性能
# -c表示并发连接数1000,-t表示线程数为2
[root@localhost ~]# wrk -c 1000 -t 2 http://192.168.192.120:82/
- Requests/sec:每秒请求数
- Transfer/sec:吞吐量
2、nslookup
- nslookup time.geekbang.org
- time nslookup time.geekbang.org
- nslookup -debug time.geekbang.org
3、dig
- dig +trace +nodnssec time.geekbang.org +trace表示开启跟踪查询,+nodnssec表示禁止DNS安全扩展
- dig +short example.com
4、ping
- ping -c3 114.114.114.114
- ping -n -c3 geektime.org
5、dnsmasq
- dns缓存 yum install -y dnsmasq;systemctl enable dnsmasq
6、tcpdump
- tcpdump -nn udp port 53 or host 35.190.27.188 -nn ,表示不解析抓包中的域名(即不反向解析)、协议以及端口号。
- tcpdump -i eth0 -n tcp port 80 -n不解析协议名和主机名
7、curl
- curl -s -w ‘Http code: %{http_code}\nTotal time:%{time_total}s\n’ -o /dev/null http://192.168.192.120
8、hping3
- hping3 -S -p 80 -i u10 192.168.0.30 -S参数表示设置TCP协议的SYN(同步序列号),-p表示目的端口为80,-i u10表示每隔10微秒发送一个网络帧
- hping3 -c 3 -S -p 80 baidu.com -c表示发送3次请求,-S表示设置TCP SYN,-p表示端口号为80,测试网络延迟
9、sar
- sar -n DEV 1
10、netstat
- netstat -n -p | grep SYN_REC
10、其他
- iptables -I INPUT -s 192.168.0.2 -p tcp -j REJECT
- iptables -A INPUT -p tcp --syn -m limit --limit 1/s -j ACCEPT 限制syn并发数为每秒1次
- iptables -I INPUT -p tcp --dport 80 --syn -m recent --name SYN_FLOOD --update --seconds 60 --hitcount 10 -j REJECT 限制单个IP在60秒新建立的连接数为10
- sysctl -w net.ipv4.tcp_syncookies=1 开启 TCP SYN Cookies
- sysctl -w net.ipv4.tcp_synack_retries=1 synack重试次数
- sysctl -w net.ipv4.tcp_max_syn_backlog=1024 增大半连接的容量