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,毕竟是图形界面.
Linux性能优化实战学习笔记:第十讲的更多相关文章
- Linux性能优化实战学习笔记:第四十一讲
一.上节回顾 上一节,我们探究了网络延迟增大问题的分析方法,并通过一个案例,掌握了如何用hping3.tcpdump.Wireshark.strace 等工具,来排查和定位问题的根源. 简单回顾一下, ...
- Linux性能优化实战学习笔记:第九讲
一.中断的魅力 1.中断在生活的魅力 比如你订了一份外卖,但是不确定外卖什么时候送到,也没有别的方法了解外卖的进度,但是,配送员送外卖是不等人的,到了你这儿没人取的话,就直接走人了.所以你指能苦苦等着 ...
- Linux性能优化实战学习笔记:第四十五讲
一.上节回顾 专栏更新至今,四大基础模块的最后一个模块——网络篇,我们就已经学完了.很开心你还没有掉队,仍然在积极学习思考和实践操作,热情地留言和互动.还有不少同学分享了在实际生产环境中,碰到各种性能 ...
- Linux性能优化实战学习笔记:第三十二讲
一.上节总结 专栏更新至今,四大基础模块的第三个模块——文件系统和磁盘 I/O 篇,我们就已经学完了.很开心你还没有掉队,仍然在积极学习思考和实践操作,并且热情地留言与讨论. 今天是性能优化的第四期. ...
- Linux性能优化实战学习笔记:第三十六讲
一.上节总结回顾 上一节,我们回顾了经典的 C10K 和 C1000K 问题.简单回顾一下,C10K 是指如何单机同时处理 1 万个请求(并发连接 1 万)的问题,而 C1000K 则是单机支持处理 ...
- Linux性能优化实战学习笔记:第四十三讲
一.上节回顾 上一节,我们了解了 NAT(网络地址转换)的原理,学会了如何排查 NAT 带来的性能问题,最后还总结了 NAT 性能优化的基本思路.我先带你简单回顾一下. NAT 基于 Linux 内核 ...
- Linux性能优化实战学习笔记:第四十四讲
一.上节回顾 上一节,我们学了网络性能优化的几个思路,我先带你简单复习一下. 在优化网络的性能时,你可以结合 Linux 系统的网络协议栈和网络收发流程,然后从应用程序.套接字.传输层.网络层再到链路 ...
- Linux性能优化实战学习笔记:第五十二讲
一.上节回顾 上一节,我们一起学习了怎么使用动态追踪来观察应用程序和内核的行为.先简单来回顾一下.所谓动态追踪,就是在系统或者应用程序还在正常运行的时候,通过内核中提供的探针,来动态追踪它们的行为,从 ...
- Linux性能优化实战学习笔记:第五十五讲
一.上节回顾 上一节,我们一起学习了,应用程序监控的基本思路,先简单回顾一下.应用程序的监控,可以分为指标监控和日志监控两大块. 指标监控,主要是对一定时间段内的性能指标进行测量,然后再通过时间序列的 ...
- Linux性能优化实战学习笔记:第五十八讲
一.上节回顾 专栏更新至今,咱们专栏最后一部分——综合案例模块也要告一段落了.很高兴看到你没有掉队,仍然在积极学习思考.实践操作,并热情地分享你在实际环境中,遇到过的各种性能问题的分析思路以及优化方法 ...
随机推荐
- 为Azure DevOps Server (TFS) 配置安全访问(HTTPS with SSL)
Contents 1. 概述 2. HTTP和HTTS比较 支持HTTP和HTTPS两种方式 要求所有连接使用HTTPS 优点: 缺点: 3. 为Azure DevOps Server 配置安全访问 ...
- jQuery 源码分析(五) map函数 $.map和$.fn.map函数 详解
$.map() 函数用于使用指定函数处理数组中的每个元素(或对象的每个属性),并将处理结果封装为新的数组返回,该函数有三个参数,如下: elems Array/Object类型 指定的需要处理的数组或 ...
- 微服务通过feign.RequestInterceptor传递参数
Feign 支持请求拦截器,在发送请求前,可以对发送的模板进行操作,例如设置请求头等属性,自定请求拦截器需要实现 feign.RequestInterceptor 接口,该接口的方法 apply 有参 ...
- 【Maven】【IDEA】在idea中开发web项目,解决maven的jar包冲突的方法
在idea中开发web项目,解决maven的jar包冲突的方法 第一步: 先对项目进行 clean ,再进行install 第二步: 出现NoSuchMethodException,ClassNotF ...
- “金九银十”已过,总结我的天猫、蚂蚁、头条面试经历(Java岗)
跳槽时时刻刻都在发生,但是我建议大家跳槽之前,先想清楚为什么要跳槽.切不可跟风,看到同事一个个都走了,自己也盲目的开始面试起来(期间也没有准备充分),到底是因为技术原因(影响自己的发展,偏移自己规划的 ...
- AppSetting配置工具类
<?xml version="1.0" encoding="utf-8"?> <!-- 有关如何配置 ASP.NET 应用程序的详细信息,请访 ...
- 使用highcharts实现无其他信息纯趋势图实战实例
使用highcharts实现无其他信息纯趋势图实战实例 Highcharts去掉或者隐藏掉y轴的刻度线yAxis : { gridLineWidth: 0, labels:{ //enabled:fa ...
- Vue.js 源码分析(八) 基础篇 依赖注入 provide/inject组合详解
先来看看官网的介绍: 简单的说,当组件的引入层次过多,我们的子孙组件想要获取祖先组件的资源,那么怎么办呢,总不能一直取父级往上吧,而且这样代码结构容易混乱.这个就是这对选项要干的事情 provide和 ...
- maven 学习---Maven项目模板
Maven提供用户,使用原型的概念,不同类型的项目模板(以数字614)是一个非常大的列表. Maven帮助用户快速开始使用以下命令创建新的Java项目 mvn archetype:generate 什 ...
- 如何在unbuntu 16.04上离线部署openssh
背景:由于部署环境不能联网,为了方便文件传输,需要用到openssh.故实施步骤是,先在可以联网机器上下载离线包,然后用U盘拷贝到部署环境中. 第一步:下载离线包,下载网址:https://packa ...