zoukankan      html  css  js  c++  java
  • Linux性能优化实战学习笔记:第十讲

    一、坏境准备

    1、拓扑图

    2、安装包

    在第9节的基础上

    在VM2上安装hping3依奈包

    wget http://www.tcpdump.org/release/libpcap-1.9.0.tar.gz
    tar xf libpcap-1.9.0.tar.gz
    cd libpcap-1.9.0/
    ./configure && make && make install
    [root@luoahong pcap]# pwd
    /root/libpcap-1.9.0/pcap
    [root@luoahong pcap]# cp -a bpf.h /usr/include/net/bpf.h

    在VM2上安装hping3的安装

    yum install gcc libpcap-devel   tcl-devel -y
    git clone https://github.com/antirez/hping.git
    cd hping
    ./configure && make
    

    3、实验环境准备

    1、运行案例终端一

    [root@luoahong ~]# docker run -itd --name=nginx -p 80:80 nginx
    docker: Error response from daemon: Conflict. The container name "/nginx" is already in use by container "f78d08880b62aa97fbbd8b3a545af4bcd849b05ecca7493874028fcaffaffc41". You have to remove (or rename) that container to be able to reuse that name.
    See 'docker run --help'.
    [root@luoahong ~]# docker ps -l
    CONTAINER ID        IMAGE                    COMMAND             CREATED             STATUS                     PORTS               NAMES
    cf7abb7672d9        feisky/app:iowait-fix2   "/app"              25 hours ago        Exited (255) 5 hours ago
    
    [root@luoahong ~]# docker rm -f app
    app
    [root@luoahong ~]# docker run -itd --name=nginx -p 80:80 nginx
    6545b4661b2f3c8ef0eba73706c2d1bf7a0b5469272b77ed172a4f4b92b068b9
    

    2、确认nginx正常启动(终端二)

    curl http://192.168.118.97/
    
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    

    3、运行 hping3 命令,来模拟 Nginx 的客户端请求(终端二)

    [root@nfs hping]# pwd
    /root/hping
    # -S 参数表示设置 TCP 协议的 SYN(同步序列号),-p 表示目的端口为 80
    # -i u100 表示每隔 100 微秒发送一个网络帧
    # 注:如果你在实践过程中现象不明显,可以尝试把 100 调小,比如调成 10 甚至 1
    [root@nfs hping]# ./hping3 -S -p 80 -i u100 192.168.118.97
    HPING 192.168.118.97 (eth0 192.168.118.97): S set, 40 headers + 0 data bytes
    len=46 ip=192.168.118.97 ttl=63 DF id=0 sport=80 flags=SA seq=0 win=29200 rtt=34.8 ms
    len=46 ip=192.168.118.97 ttl=63 DF id=0 sport=80 flags=SA seq=1 win=29200 rtt=37.4 ms
    len=46 ip=192.168.118.97 ttl=63 DF id=0 sport=80 flags=SA seq=2 win=29200 rtt=36.1 ms
    len=46 ip=192.168.118.97 ttl=63 DF id=0 sport=80 flags=SA seq=3 win=29200 rtt=35.5 ms
    len=46 ip=192.168.118.97 ttl=63 DF id=0 sport=80 flags=SA seq=4 win=29200 rtt=34.1 ms
    len=46 ip=192.168.118.97 ttl=63 DF id=0 sport=80 flags=SA seq=5 win=29200 rtt=32.2 ms
    len=46 ip=192.168.118.97 ttl=63 DF id=0 sport=80 flags=SA seq=6 win=29200 rtt=31.7 ms
    len=46 ip=192.168.118.97 ttl=63 DF id=0 sport=80 flags=SA seq=7 win=29200 rtt=30.6 ms
    len=46 ip=192.168.118.97 ttl=63 DF id=0 sport=80 flags=SA seq=8 win=29200 rtt=1027.6 ms
    ...

    二、分析过程

    1、查看系统整体的资源使用情况(终端一)

    # top 运行后按数字 1 切换到显示所有 CPU
    top - 16:51:32 up 4:54, 2 users, load average: 0.01, 0.03, 0.05
    Tasks: 103 total, 2 running, 101 sleeping, 0 stopped, 0 zombie
    %Cpu(s): 0.0 us, 0.2 sy, 0.0 ni, 78.7 id, 0.0 wa, 0.0 hi, 21.2 si, 0.0 st
    KiB Mem : 8056848 total, 7167580 free, 399752 used, 489516 buff/cache
    KiB Swap: 2097148 total, 2097148 free, 0 used. 7327620 avail Mem
    
    PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
    14 root 20 0 0 0 0 R 3.0 0.0 8:14.97 ksoftirqd/1
    9 root 20 0 0 0 0 S 1.0 0.0 2:10.35 rcu_sched
    9395 root 20 0 419132 32876 14612 S 1.0 0.4 5:19.33 containerd
    9753 mysql 20 0 1119708 182720 5796 S 0.7 2.3 1:25.85 mysqld
    7508 root 20 0 227036 6348 4944 S 0.3 0.1 1:09.48 vmtoolsd
    16355 root 20 0 0 0 0 S 0.3 0.0 0:00.39 kworker/0:1
    16358 root 20 0 161996 2224 1564 R 0.3 0.0 0:00.09 top
    1 root 20 0 43640 4024 2552 S 0.0 0.0 0:03.60 systemd
    2 root 20 0 0 0 0 S 0.0 0.0 0:00.04 kthreadd
    3 root 20 0 0 0 0 S 0.0 0.0 0:03.80 ksoftirqd/0
    ...
    

    根据上一期的内容,既然软中断可能有问题,那你先要知道究竟是哪类软中断的问题?

    1、是系统运行以来的累积中断次数

    不过,这里的各类软中断次数,又是什么时间段里的次数呢?它是系统运行以来的累积中断次数

    所以我们直接查看文件内容,得到的只是累积中断次数,对这里的问题并没有直接参考意义,因为这些中断次数的变化速率才是我们需要关注的

    2、观察各种软中断类型的次数(终端一)

    [root@luoahong ~]# watch -d cat /proc/softirqs		 
                        CPU0       CPU1      		 
              HI:          1          0      		 
           TIMER:     928050    4221133      		 
          NET_TX:       2670         12      		 
          NET_RX:        102   24694097      		 
           BLOCK:      13635          0      		 
    BLOCK_IOPOLL:          0          0      	
         TASKLET:         56       1535      
           SCHED:     477868    1155566      
         HRTIMER:          0          0      
             RCU:     747103    1976371  

    1、通过/proc/softirqs 文件内容的变化情况,你可以发现, TIMER(定时中断)、NET_RX(网络接收)、SCHED(内核调度)、RCU(RCU 锁)等这几个软中断都在不停变化。

    2、其中NET_RX,也就是网络数据包接收软中断的变化速率最快。而其他几种类型的软中断,是保证 Linux 调度、时钟和临界区保护这些正常工作所必需的,所以它们有一定的变化倒是正常的。

    那么接下来,我们就从网络接收的软中断着手,继续分析,既然是网络接收的软中断,第一步应该是观察系统的网络接收情况。这里你可能想起很多网络工具,不过我推荐今天的主人工sar

    3、观察系统的网络接收情况(终端一)

    sar可以用来查看系统的网络首发情况,还有一个好处,不可以观察网络收发的吞吐量(BPS,每秒收发的字节数),还可以观察网络收发的PPS,即每秒收发的网络帧数

    # -n DEV 表示显示网络收发的报告,间隔 1 秒输出一组数据
    [root@luoahong ~]# sar -n DEV 1
    Linux 3.10.0-957.5.1.el7.x86_64 (luoahong) 	05/06/2019 	_x86_64_	(2 CPU)
    
    03:39:02 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
    03:39:03 PM br-ad2616372f01      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
    03:39:03 PM      eth0   4456.00   2231.00    261.09    130.85      0.00      0.00      0.00      0.21
    03:39:03 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
    03:39:03 PM veth502c523   2227.00   4456.00    126.14    234.98      0.00      0.00      0.00      0.02
    03:39:03 PM   docker0   2227.00   4456.00     95.69    234.98      0.00      0.00      0.00      0.00
    
    03:39:03 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
    03:39:04 PM br-ad2616372f01      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
    03:39:04 PM      eth0   4392.00   2190.00    257.34    128.99      0.00      0.00      0.00      0.21
    03:39:04 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
    03:39:04 PM veth502c523   2190.00   4380.00    124.04    230.98      0.00      0.00      0.00      0.02
    03:39:04 PM   docker0   2190.00   4380.00     94.10    230.98      0.00      0.00      0.00      0.00

    sar命令图解

    我们具体来看输出的内容,你可以发现:每秒接收的网络帧数远大于发送的网络帧数

    既然怀疑是网络中断的问题,我们还是重点来看eth0接收的BPS很小,稍微计算一下,说明平均每个网络帧数只有54字节,这显然是很小的网络帧,这也就是我们通常所说的小包问题

    4、这是一个什么样的网络帧?从哪里发过来的呢?(终端一)

    那么,有没有办法知道这是一个什么样的网络帧,以及从哪里发过来的呢?

    # -i eth0 只抓取 eth0 网卡,-n 不解析协议名和主机名
    # tcp port 80 表示只抓取 tcp 协议并且端口号为 80 的网络帧
    $ tcpdump -i eth0 -n tcp port 80
    15:37:44.411911 IP 192.168.118.105.64379 > 192.168.118.97.http: Flags [R], seq 1503793557, win 0, length 0
    15:37:44.411919 IP 192.168.118.105.64380 > 192.168.118.97.http: Flags [R], seq 395003338, win 0, length 0
    15:37:44.413313 IP 192.168.118.105.64382 > 192.168.118.97.http: Flags [S], seq 1080244426, win 512, length 0
    15:37:44.413335 IP 192.168.118.105.64381 > 192.168.118.97.http: Flags [R], seq 176434656, win 0, length 0
    15:37:44.413340 IP 192.168.118.105.64383 > 192.168.118.97.http: Flags [S], seq 2026187932, win 512, length 0
    15:37:44.413347 IP 192.168.118.105.64384 > 192.168.118.97.http: Flags [S], seq 860129571, win 512, length 0
    15:37:44.413431 IP 192.168.118.97.http > 192.168.118.105.64382: Flags [S.], seq 2546910072, ack 1080244427, win 29200, options [mss 1460], length 0
    15:37:44.413547 IP 192.168.118.97.http > 192.168.118.105.64383: Flags [S.], seq 1083250845, ack 2026187933, win 29200, options [mss 1460], length 0
    15:37:44.413604 IP 192.168.118.97.http > 192.168.118.105.64384: Flags [S.], seq 3306737583, ack 860129572, win 29200, options [mss 1460], length 0
    15:37:44.417237 IP 192.168.118.105.64385 > 192.168.118.97.http: Flags [S], seq 311506147, win 512, length 0
    ...

    从tcpdump的输出中,你可以发现

    1、192.168.118.105.64382 > 192.168.118.97 表示网络帧从192.168.118.105的64382端口到192.168.118.97的80端口,也就是运行hping3 机器的 64379 端口发送网络帧,

    2、目的位Nginx所在机器的80端口

    3、Flags [S] 则表示这是一个 SYN 包

    再加上前面用 sar 发现的, PPS 超过 12000 的现象,现在我们可以确认,这就是从192.168.118.105 这个地址发送过来的SYN FLOOD 攻击

    三、小结

    到这里,我们已经做了全套的性能诊断和分析。

    1、从系统的软中断使用率高这个现象出发,

    2、通过观察/proc/softirqs 文件的变化情况,判断出软中断类型是网络接收中断

    3、再通过 sar 和 tcpdump ,确认这是一个 SYN FLOOD问题

    4、SYN FLOOD 问题最简单的解决方法,就是从交换机或者硬者硬件防火墙中封掉来源 IP,这样 SYN FLOOD 网络络帧就不会发送到服务器中

    软中断CPU使用率升高是一种很常见的性能问题,虽然软中断的类型很多,但实际生产中,我们遇到的性能瓶颈大多数是网络收发类型的软中断,特别是网络接收的软中

    在碰到这类问题时,你可以借用sar、tcpdump等工具,做进一步分析,不要害怕网络性能,后面我们会教你更多的分析方法

    四、思考题

    1、你所碰到的软中断问题。

    我的理解比较简单粗暴, 硬中断是硬件产生的,比如键盘、鼠标的输入,硬盘的写入读取、网卡有数据了;软中断是软件产生的,比如程序内的定时器、[文中提到的RCU锁]。
    再加上今天的上半部下半部,更好的理解了网卡的处理实际是有硬中断和软中断的。

    2、你所碰到的软中问题是哪种类型

    有,且是血淋淋的教训。
    之前的c程序用到了别人写的动态库[如:lib.a],在物理机上,进程的cpu利用率在0%;而切换到了云服务器,即使空载,单进程的cpu利用率都有30%+。
    以前没经验嘛,各种自查,无结果,但是自己的进程cpu利用率又那么高,总是不安心.
    后来才通过vmstat 检测到系统的软中断每秒有100W+次.
    最后各自百度,找人,才发现是那个动态库在处理网络收发消息时,使用了usleep(1)来休息,每次休息1纳秒,单次中断的耗时都不止1纳秒.

    3、是不是这个案例中的小包问题?

    如果是现在,我会如下分析:

    1.检测是哪个线程占用了

    cpu: top -H -p XX 1 / pidstat -wut -p XX 1

    2.在进程中打印各线程号. 找到是哪个线程.[ 此过程也可以省略 但可以快速定位线程]

    3.第一步应该可以判断出来中断数过高. 再使用 cat /proc/softirqs 查看是哪种类型的中断数过高.

    4.不知道perf report -g -p XX 是否可以定位到具体

    5.最终还是要查看源码,定位具体的位置,并加以验证.

    4、你又是怎么分析它们的来源并解决的呢?

    本期又学到新东西了:
    1.sar 原来可以这么方便的看各网卡流量,甚至是网络帧数.

    到目前为止,我都是用的最原始的方法:在网上找的一个脚本,分析ifconfig中的数据,来统计某个网卡的流量.一来需要指定某个网卡(默认eth0),二来显示的数据不太准确且不友好(sleep 1做差值).

    2.nping3 居然可以用来模拟SYN FLOOD. (不要用来做坏事哦)

    3.tcpdump 之前有所耳闻. 用的不多. 平常有解包需求,都是在windows下用wireshark,毕竟是图形界面.

  • 相关阅读:
    PAT 甲级 1132 Cut Integer (20 分)
    AcWing 7.混合背包问题
    AcWing 9. 分组背包问题
    AcWing 5. 多重背包问题 II
    AcWing 3. 完全背包问题
    AcWing 4. 多重背包问题
    AcWing 2. 01背包问题
    AcWing 875. 快速幂
    AcWing 874. 筛法求欧拉函数
    AcWing 873. 欧拉函数
  • 原文地址:https://www.cnblogs.com/luoahong/p/10820252.html
Copyright © 2011-2022 走看看