关键词
- linux、centos
- cpu load、netstat、strace
- 阻塞、卡顿
There are many things that can not be broken!
如果觉得本文对你有帮助,欢迎点赞、收藏、评论!
在一次线上业务的阻塞故障中,发现罪魁祸首是执行了大量netstat的命令导致,进而对这次事件做了一次剖析,发现我们经常使用的netstat居然会有如此大的影响。
一、问题现象
某一天某应用反馈无法访问postgresql数据库,数据库活动连接数突增,数据库主机CPU使用率高,并且出现严重卡顿情况,主机性能各项指标飙升。数据库切换后,另一个节点同样出现相同一样故障情况。后定位发现主机有异常监控程序每分钟定时批量发起netstat查询命令,导致系统资源耗尽引发负载升高,系统卡顿现象。
二、问题分析
当发现有这么多netstat命令时,开始追踪netstat的源头,原来是监控的进程发起。再询问监控维护人员得知,故障发生前,监控维护人员批量修改了采集脚本,修改后的程序1分钟采集一次,且每次并发执行16次netstat命令,故障同一时间点应用操作数据库并发量大,导致主机负载瞬间增长很大,主机响应慢触发一系列问题。问题的矛头指向了netstat命令,那么为何会造成如此大影响?接下来好好剖析一下:
首先了解下netstat这个工具的原理
netstat是在net-tools工具包下面的一个工具集,用来查询网络情况,同时支持很多参数扩展查询。本次案例中,程序代码主要是批量执行了netstat -antlp命令。
通过strace追踪这条命令:
简单概括,netstat程序实际做了以下操作
1、加载一些链接库, 例如 libselinux.so.1, libc.so.6, libdl.so.2 等
2、读取 /proc/XXX/fd 文件夹下面的信息
3、读取 /proc/net/ 下的信息
4、向 kernel 发送 PF_NETLINK 类型的 socket 查询一些信息
通过查看源码:
netstat的源码是在net-tools中,可从https://www.linuxfromscratch.org/blfs/view/6.3/basicnet/net-tools.html找到下载链接
netstat命令行的入口在 netstat.c 中
代码的逻辑简单的可以概括为: 解析参数->根据参数查找显示数据。
以参数”r” 为例子(即 netstat -r 的执行方式)
读取 /proc/net/route内容,再根据文件内容格式读取数据, 格式化输出
命令最终调用的函数为 lib/inet_gr.c 中的 rprint_fib 函数。
netstat 不同的参数对应的读取方法有:
参数 | 读取方法 |
r | /proc/net/route |
i | socket |
t | /proc/net/tcp(6) |
u | /proc/net/udp(6) |
w | /proc/net/raw(6) |
g | /proc/net/igmp(6) |
p | 启动时遍历/proc/XXX/cmdline |
结论:
当netstat命令执行时,会根据执行所带的参数,依次调用函数,执行系统调用。函数执行的效率的直接会影响系统调用的时间。
本次案例中,使用了-p参数,系统会遍历/proc/目录来完成系统调用,当系统当前进程较多时,netstat -p的执行耗时会明显升高。此时如果使用了并发进程,cpu的非自愿切换升高,导致系统整体负载短时间飙升,系统同一时间其他进程无法获取cpu资源,从而出现卡顿现象。如果此时系统其他进程同时也有并发,就会造成cpu的进程严重争用情况,系统处理能力受阻。
三、测试验证
测试主机:华为物理机
测试配置:CPU 48C
初始任务数:502
1、无负载下,单独模拟并发执行1000条netstat命令
使用-an参数,执行耗时0.189s
使用-anp参数,执行耗时6.904s,同时系统负载飙升严重,sys使用率上升,进程的非自愿上下文切换增多,系统已有卡顿现象。
对并发的netstat数量做了压测对比,测试结果如下:
命令参数 | 并发数量 | |||||
100 | 300 | 500 | 800 | 1000 | 2000 | |
an | 0.014s | 0.054s | 0.099s | 0.154s | 0.189s | 0.407s |
anp | 0.015s | 1.002s | 2.541s | 4.654s | 6.904s | 19.468s |
2、模拟有负载情况下,并发netstat测试
先执行1000条ping命令,系统任务数增加到1500+。/proc下文件数1500+
此时执行100条并发netstat命令时,-an的参数命令耗时没变化,-anp的参数耗时有明显增加,最大耗时已超过1s。
对不同系统负载下,300并发netstat的测试对比
命令参数 | 系统进程数 | ||||
500 | 1500 | 3500 | 5500 | 7500 | |
an | 0.054s | 0.045s | 0.071s | 0.082s | 0.091s |
anp | 1.002s | 3.62s | 10.783s | 20.032s | 31.828s |
3、对比不同命令参数下的netstat系统调用耗时
在系统进程数7500条时,netstat -p参数的系统调用耗时增加到0.18s,不加p的系统调用耗时为0.03s。随着进程数的增加,添加-p参数的netstat消耗系统cpu时间更长。
4、测试结论
Netstat 使用-p参数时,确实会增加系统调用cpu消耗时间,系统调用的同时也会产生上下文切换,导致系统的瞬时负载上涨,进程间争用cpu明显。此时如有高并发应用,程序得不到资源会进一步恶化系统负载,cpu争用也会加剧,业务上表象就会“卡”的更久。