
很多人一说测网速,脑子里第一反应就是那个转圈圈的speedtest页面,上传多少下载多少。但在服务器运维场景里,"网速"这个词其实包含了好几个维度,不搞清楚的话,测出来的数据根本没法用。
带宽(Bandwidth):就是你买的那条线理论上能跑多快。比如你买了100Mbps的带宽,这是上限,是天花板。注意这里的单位是Mbps,是bit,不是Byte,换算关系是除以8,所以100Mbps的理论最大下载速度大概是12.5MB/s,很多人搞混这个。
吞吐量(Throughput):实际跑出来的速度。受到网络拥塞、丢包、协议开销等影响,永远比带宽小。这才是你真正关心的数字。
延迟(Latency):数据从A到B需要多少时间。这个跟带宽是两回事,带宽大不代表延迟低,就像高速公路宽不代表你开车快,路上堵车照样慢。
丢包率(Packet Loss):数据包在传输过程中丢失的比例。哪怕只有1%的丢包,对TCP连接的影响都是灾难性的,因为TCP会反复重传,速度直接掉下来。
所以你看,"网速慢"这个说法太笼统了。是带宽不够?还是丢包严重?还是延迟高?不同的问题,解决方案完全不一样。
如果你要测两台服务器之间的网络性能,iperf3是我用得最多的工具,没有之一。
它的工作原理很简单:一台机器跑服务端,另一台跑客户端,客户端向服务端发送数据,测量实际吞吐量。因为是点对点直接测,排除了外部因素干扰,测出来的数据非常准。
安装:
# CentOS/RHEL
yum install -y iperf3
# Ubuntu/Debian
apt install -y iperf3使用方式:
服务端先跑起来,监听5201端口:
iperf3 -s客户端连过去测试:
iperf3 -c 192.168.1.100默认跑10秒,输出大概长这样:
[ ID] Interval Transfer Bitrate
[ 5] 0.00-10.00 sec 1.09 GBytes 936 Mbits/sec sender
[ 5] 0.00-10.00 sec 1.09 GBytes 934 Mbits/sec receiver这里要注意,Bitrate就是吞吐量,单位是Mbits/sec。如果你的网卡是千兆的,理论上能跑到940Mbps左右(有协议开销),跑出来900+就算正常,要是只有500Mbps,那就得查原因了。
几个常用参数:
# 测试时间改成30秒,更准确
iperf3 -c 192.168.1.100 -t 30
# 开4个并行连接,模拟多线程场景
iperf3 -c 192.168.1.100 -P 4
# 测UDP,顺便看丢包率和抖动
iperf3 -c 192.168.1.100 -u -b 100M
# 反向测试,服务端向客户端发数据(测上行)
iperf3 -c 192.168.1.100 -RUDP测试这个很有用,特别是对实时业务,比如视频流、语音通话这类对丢包敏感的应用。-b 100M 是限制发送速率100Mbps,不加的话UDP会把带宽打满,可能影响其他业务。
我之前有次排查一个机房到机房之间的专线,运营商承诺是500Mbps,用iperf3一测,单线程只有200Mbps出头,开4个并行连接才到450Mbps。这说明线路延迟比较高,单个TCP连接的窗口大小限制了速度,但实际带宽是够的。这个细节如果不用iperf3测,根本发现不了。
iperf3适合测内网,公网带宽怎么测?speedtest-cli是个不错的选择。
安装:
# CentOS系列
yum install -y python3-pip
pip3 install speedtest-cli
# Ubuntu/Debian
apt install -y speedtest-cli
# 或者用pip
pip3 install speedtest-cli直接运行:
speedtest-cli它会自动找最近的测速服务器,然后输出延迟、下载速度、上传速度。
Ping: 5.234 ms
Download: 94.32 Mbit/s
Upload: 95.11 Mbit/s如果想指定测速服务器,先列出来选:
speedtest-cli --list | grep -i beijing然后用 --server 参数指定ID:
speedtest-cli --server 12345还可以输出JSON格式,方便写脚本采集:
speedtest-cli --json这个工具的局限性也很明显,它测的是你的服务器到某个公网测速节点的速度,受路由、节点质量影响很大。同一台服务器,选不同的测速节点,结果可能差一倍。所以我一般会选几个不同的节点多测几次,取个平均值,而不是只看一次结果。
有时候服务器环境比较受限,装不了额外的工具,或者就是想快速测一下,wget和curl就够用了。
# 用wget下载一个测速文件,输出到/dev/null(不占磁盘)
wget -O /dev/null http://speedtest.tele2.net/100MB.zip
# 用curl测,并显示详细速度信息
curl -o /dev/null -w "Speed: %{speed_download} bytes/sec\nTime: %{time_total}s\n" \
http://speedtest.tele2.net/100MB.zipcurl的 -w 参数可以输出很多有用的信息,比如:
curl -o /dev/null -w "DNS解析: %{time_namelookup}s\n连接时间: %{time_connect}s\n首字节时间: %{time_starttransfer}s\n总时间: %{time_total}s\n下载速度: %{speed_download} bytes/s\n" \
https://www.baidu.com这个其实不只是测速,还能帮你分析延迟在哪个阶段,DNS解析慢还是TCP握手慢还是服务器响应慢,对排查问题很有帮助。
注意curl输出的速度单位是bytes/s,换成Mbps要乘以8再除以1000000。
上面那几个工具是主动测试,还有一类工具是被动监控,看服务器当前的网络使用情况。
nload —— 最直观的实时流量图
# 安装
yum install -y nload # CentOS
apt install -y nload # Ubuntu
# 运行
nload eth0nload会用ASCII图形展示实时的入流量和出流量,非常直观。多个网卡的话用左右方向键切换。
iftop —— 看连接维度的流量
# 安装
yum install -y iftop
apt install -y iftop
# 运行(需要root)
iftop -i eth0iftop的界面有点像top命令,显示当前所有活跃连接的流量,能看到哪个IP在跟你通信,流量多少。排查"谁在占带宽"这类问题非常好用。
有次我们服务器带宽突然跑满了,业务受影响,用iftop一看,发现有个外部IP在疯狂请求,流量占了总带宽的70%,明显是爬虫或者攻击,直接加防火墙规则封掉,带宽立刻恢复正常。
nethogs —— 精确到进程的流量统计
# 安装
yum install -y nethogs
apt install -y nethogs
# 运行
nethogs eth0nethogs能告诉你每个进程的网络使用情况,包括进程名、PID、发送速率、接收速率。当你不知道是哪个进程在占用带宽的时候,nethogs直接给你答案。
这三个工具我一般是配合着用的,nload先看总体情况,流量异常的话用iftop看是哪个IP,再用nethogs确认是哪个进程,三步基本能定位到问题。
很多人觉得ping太简单,不屑于用。但其实ping给出的信息量挺大的。
# 基本用法
ping -c 100 目标IP
# 指定包大小(测试不同包大小下的延迟)
ping -c 50 -s 1400 目标IP
# 洪水ping,快速测丢包(需要root)
ping -f -c 1000 目标IPping 100个包,看平均延迟、最小最大延迟、丢包率。如果丢包率超过0.1%,就要重视了,TCP在这种情况下性能会严重下降。
traceroute/tracepath可以看数据包经过哪些节点,哪个节点延迟高:
traceroute 目标IP
# mtr是traceroute的增强版,实时显示每跳的丢包率和延迟
mtr 目标IPmtr这个工具特别好用,它把ping和traceroute结合起来,实时显示每一跳的延迟和丢包情况,能快速定位是哪段链路有问题。
工具会用了,但数据怎么看,这才是关键。
关于带宽利用率
如果你买的是100Mbps带宽,iperf3测出来80Mbps,这正常吗?正常。TCP有协议开销,加上网络本身的一些损耗,能达到理论值的85%-95%就算健康。如果只有50%,那就要查原因了。
关于延迟
同机房内的服务器之间延迟一般在0.1-1ms,同城跨机房5-20ms,跨省50-100ms,国际线路100-300ms。如果你的延迟远超这个范围,要么是路由绕远了,要么是中间某个节点有问题。
关于丢包
局域网内丢包率应该是0。公网允许有极小的丢包,但超过0.5%就需要关注,超过1%就是明显问题了。UDP测试看丢包率特别直观:
iperf3 -c 目标IP -u -b 50M -t 30输出里会有 0.00% 这样的丢包率数据。
关于单线程和多线程的差异
这个坑很多人踩过。iperf3单线程测试,如果延迟比较高,TCP窗口会限制速度,跑不满带宽。这不是带宽不够,是TCP拥塞控制的正常行为。
简单说,TCP发送速度受窗口大小和RTT(往返延迟)共同决定:
最大吞吐量 ≈ TCP窗口大小 / RTTRTT是100ms,TCP窗口是64KB(默认),最大吞吐量大概是640KB/s = 5Mbps。哪怕你有1Gbps的带宽,单线程也跑不快。这时候要么调大TCP窗口(调整内核参数),要么用多线程测试:
iperf3 -c 目标IP -P 8遇到网络问题,我一般按这个顺序来:
先用ping确认基本连通性和延迟,如果ping都不通,后面就不用测了,先查防火墙和路由。
ping通了,用mtr看每一跳,找出延迟突然增大或者丢包的节点。
如果是内网问题,用iperf3测两端之间的吞吐量,对比正常值。
如果是公网问题,用speedtest-cli测多个节点,看是某个方向的问题还是整体带宽不够。
如果带宽够但业务还是慢,用iftop和nethogs看是不是有其他进程占用了带宽,或者有异常流量。
最后检查内核网络参数,比如TCP缓冲区大小,有时候默认值在高延迟高带宽的场景下会成为瓶颈:
# 查看当前TCP缓冲区设置
sysctl net.core.rmem_max
sysctl net.core.wmem_max
sysctl net.ipv4.tcp_rmem
sysctl net.ipv4.tcp_wmem
# 临时调大(生产环境谨慎操作)
sysctl -w net.core.rmem_max=134217728
sysctl -w net.core.wmem_max=134217728说了这么多,核心就一句话:测网速不是目的,找到问题才是目的。
工具只是手段,关键是要理解你在测什么,测出来的数据意味着什么。带宽、延迟、丢包、抖动,这几个维度缺一不可,光看下载速度是不够的。
建议大家养成一个习惯,在服务器刚上线的时候就跑一遍基准测试,把数据记录下来。等以后出问题的时候,有历史数据对比,排查效率会高很多。
另外,测试要在业务低峰期做,也要在业务高峰期做,两个时段的数据差异本身就能说明很多问题。
如果这篇文章对你有帮助,麻烦点个赞转发一下,让更多人看到。你身边有遇到网络问题不知道怎么排查的同学,直接把这篇甩给他。
有什么问题或者补充,欢迎在评论区聊,我看到都会回复的。