在性能测试中,特别是测试云计算相关产品时,网络是影响性能的关键的因素之一,此文主要介绍网络性能如何监控以及常见网络性能问题如何定位。
首先介绍一下网络交互的过程中,数据包是怎么走的。从发送到被接收,经过的路径大致如下,以一次网络交互为例,一个数据包自发送端从上往下经由用户态空间的应用、系统内核空间到达网卡驱动,然后通过数据链路传输到达接收端,再从下往上经过网卡驱动、系统内核空间最终到达用户态空间的应用中等待被处理。在整个过程中,涉及到多个队列,一系列的参数设定,其中任一部分的波动都可能导致终端表现出网络性能的抖动。
网络性能监控是网络性能测试的重要部分,也是定位网络性能问题的重要手段。监控结果能相对直观地显示出网络系统的运行状态,帮助我们分析和解决性能问题。在网络性能监控中,最常用的监控方式有两类:网卡性能监控和协议栈监控。
网卡性能监控是网络性能测试中最重要的监控方式之一,网卡承载了所有的网络流量,很多关键性能参数都能从网卡性能监控中获得。网卡性能监控工具有很多,其中以sar较为常用。
sar 全称为System Activity Report,是Unix/Linux 下流行的系统资源监控命令,Linux 下如果没有该命令,需要安装 sysstat 包。
sar -n 可以根据关键字以不同的角度报告实时的网络流量变化,其中DEV和ETCP关键字最为常用。
DEV关键字以设备为单位提供网络统计报告,方便快速观察各网卡性能:
ETCP关键字报告TCP层的错误统计,包括重试、断连、重传、错误、RST包等:
通常情况下可以将DEV和ETCP结合使用,如:sar -n DEV -n ETCP ,快速观察网络性能状况,结果如图2:
除了sar外,还有很多网卡性能监控工具,诸如:
具体详见附录中的参考链接。
除了网卡之外,协议栈状态也是影响网络性能的关键因素之一,网络性能出现异常时,往往能从协议栈状态中看出端倪。在Linux系统中,Netstat是最常用的协议栈监控命令。
Netstat是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息。Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。
在性能测试过程中,Netstat的常用用途有以下3种:
(1) 查看丢包
我们常说的丢包有三种:
不管哪种丢包,根据TCP协议的重传规则,我们都可以通过重传来估算系统的丢包情况:
由于Netstat中部分命令展示的是系统开机以来的累计值,直接查看可能结果不够直观,因此可以配合watch 来使用。在watch命令中使用-d参数让出现变化的指标高亮。当然也可以用上文中提到的sar 来看重传: sar -n ETCP 1,其中的retrans/s就是每秒重传数。
(2) 查看全连接队列配置情况
全连接队列的大小也是影响性能的关键因素,而 Linux 默认的大小才128,有时候忘了更改这个参数就会导致性能问题。针对全连接大小是否合理这个问题,可以查看netstat统计指标中相关事件的发生频率:
netstat -st |grep SYN
当这两行出现比较大的频率增长时,说明服务器的全连接队列过小。
(3) 查看接收buffer配置情况
接收缓冲区大小也是影响性能的关键因素之一,主要是受net.ipv4.tcp_rmem相关参数的影响,以及系统调用 SO_RVCBUF 参数的影响,通常我们可以通过查找 netstat -s 中 overrun、 collapse、pruned 等事件来观察,如果相关的统计项一直都在增长,那么说明应用的接收缓冲区需要调整了,如下图5:
除了Netstat外,还有很多协议栈监控工具,诸如:
具体详见附录中的参考链接。
在日常的网络性能测试中经常遇到各式各样的问题,接下来看两个典型的例子,从问题表象、分析原因到解决问题,从而更好地理解上文提到的网络性能监控手段在网络性能测试中的作用。
丢包重传是一种较为典型的网络性能问题现象,tcp层丢包后系统会在200毫秒后自动重传,虽然丢包并不会影响结果的正确性,但是200毫秒的延迟在有些时候会严重影响性能表现。
问题表象:
在一次测试LVS上传文件性能的过程中,发现整个系统负载非常低,但是TPS上不去。理论TPS应该在40000左右,但是实际TPS只有400左右。
分析过程:
在测试机和服务器上使用sar命令配合-n DEV -n ETCP参数,测试机上显示有大量重传(retrans/s):
使用ethtool命令查看LVS的网卡配置,发现 LVS网卡 的GRO(generic-receive-offload)/LRO(large-receive-offlod) 配置项处于开启状态:
LVS开启GRO/LRO时会在转发数据包的过程中自动组包至MTU大小。由于LVS采用IP-Tunl转发方式,在发往后端时会在数据包上再加上一个ip头,因此后端接收到的数据包将会大于MTU,会被网卡丢弃掉从而导致重传。
解决方法:
综上,解决方法有二,选一即可:
解决问题后,性能恢复正常,每秒重传数降为0。
TIME_WAIT数(关于TIME_WAIT的相关介绍,可以看附录中的参考资料)在网络性能问题中也是一个值得关注的重点。下面介绍一个使用Netstat定位TIME_WAIT的性能问题。
问题表象:
在一次对某个http接口进行性能压测的过程中,测试进行一段时间之后,开始陆续出现错误,性能波动如图9:
分析过程:
首先查看客户端错误信息,显示错误类型是经典的502 Cannot assign requested address:
重新进行测试,在测试过程中使用netstat配合awk实时查看协议栈情况,发现测试开始后TIME_WAIT数快速增长,直至28000左右,于此同时,client端开始报502错误:
而实际上系统可用端口数也只有约28000多个:
综合分析之后可以得出原因:一开始系统端口数是够用的,随着测试时间的推移,TIME_WAIT数增长,直至系统的可用端口都被TIME_WAIT状态的端口占满,新的请求无法请求地址,导致出现错误。
解决方法:
针对这种情况,开启keep-alive短连接复用就可以解决。(关于keep-alive的相关介绍,可以看附录中的参考资料)开启了keep-alive后,性能恢复正常:
【特别鸣谢】 赖冬林,原性能测试组QA,网络性能测试白皮书第一作者。
ifconfig http://www.computerhope.com/unix/uifconfi.htm
ethtool http://www.linuxcommand.org/man_pages/ethtool8.html
perf http://www.brendangregg.com/perf.html
dropwatch http://blog.yufeng.info/archives/2497
sysdig https://github.com/draios/sysdig/wiki/Sysdig-Examples
systemtap http://blog.csdn.net/linyt/article/details/5204841
GRO/LRO http://blog.csdn.net/yeasy/article/details/19204639
LVS三种转发模式 http://blog.csdn.net/pi9nc/article/details/23380589
TIME_WAIT状态原理 http://elf8848.iteye.com/blog/1739571
keep-alive http://www.cnblogs.com/huangfox/archive/2012/03/31/2426341.html
本文来自网易实践者社区,经作者陈颖授权发布。