一台负载只有 0.4 的网关,仍可能让后面的每个用户都觉得慢。平均负载统计的是可运行任务,以及陷入不可中断睡眠的任务;在四核主机上,一个进程吃满就足以把数值推向 1.0,而另外三个核却闲着。把这个数字当成余量,是选择节点时最常见的错误。真正限制隧道的通常是四种情况之一:一个核太忙、上行带宽不足、它前面的队列,或者一条没人记录过的按会话策略。

平均负载统计的是任务,不是吞吐

内核按固定频率采样可运行队列和等待输入输出的任务数,再把两者分别做 一分钟、五分钟和十五分钟的平滑。这个定义里没有一个字提到字节、数据包或隧道。存储卡死的主机可能几乎没有流量却报出很高的负载,而靠内核数据路径推送千兆流量的主机也可能报出很舒服的负载。

因此,把负载和隧道性能对应起来,必须看每个核。如果有一个核被占满,仪表盘上的总体百分比依然会很好看:

cat /proc/loadavg
mpstat -P ALL 1 1
top -H -b -n 1 | head -n 20

第三条命令在 VPN 主机上最关键。OpenVPN 2.x 的用户态数据包处理在很大程度上是按进程串行的,所以一条繁忙线程就可能成为天花板,而仪表盘仍在报告充裕的空闲容量。在变慢的时段内,若一条线程占住了某个核的大部分,说明主机整体并不缺资源;它只是恰好卡在真正要紧的那个维度上。

还要注意时间点。十五分钟平均值会掩盖毁掉一通电话的突发,所以事后截的图是很弱的证据。要在问题发生时采样,并把时间戳和输出一起保存。

上行带宽和它前面的队列

网卡计数器能回答 CPU 数字答不了的带宽问题。它还能把容量和丢包区分开,这两者属于不同故障,修法也不同:

ip -s link show dev eth0
tc -s qdisc show dev eth0
nstat -az TcpRetransSegs TcpExtTCPLostRetransmit

如果测试期间链路接近它被分配的速率,那就是答案,再多的空闲 CPU 也改变不了。qdisc 那一行补充了对交互流量很关键的细节:积压和丢弃告诉你数据包在离开前是否在排队。大量上传时被填满的队列,恰好造成人们归咎于远端服务器的症状——在基准测试里仍然漂亮的连接上,通话却发涩。

重传计数器能抓住数据包发出却从未完整到达的情况。如果变慢的那段时间重传在上升,而接口离容量还差得很远,问题在路径上而不在主机上,换到同一城市的另一个节点也不会改善。

会话数说明的是需求,不是余量

每个公开目录都会显示某种已连接用户数,而几乎没有哪个会告诉你这些用户在做什么。二十个做交互工作的会话,和四个拉大文件的会话,在同一台硬件上的负载完全不同。后一种模式在用户数里看不出来,而恰恰是它毁掉一个晚上。所以会话数最好当作需求线索来读,绝不要当成空闲容量的说明。

Number on the pageWhat it is really measuringWhat it cannot tell you
Connected usersHow many sessions hold an addressHow much each one is transferring
Load or scoreWhatever the operator chose to publishWhether that definition matches your task
UptimeHow long since the process startedCurrent capacity, queue depth or packet loss
Distance or pingRound-trip time on a small probeThroughput under sustained transfer

在自己能控制的主机上,状态文件能补上缺失的那一维。OpenVPN 会定期写出快照,其中包含每个客户端的字节计数,足以看出是不是一个会话占满了整条上行带宽:

status /run/openvpn/server.status 10
# then, after at least one interval
grep -E "^CLIENT_LIST" /run/openvpn/server.status

相隔十秒的两次采样,就能把这些累计计数变成每个客户端的速率。这正是用户数所替代的那项测量,也正是靠它,你会发现某个配置错误的客户端每晚都在同一时间把链路占满。

按会话的限制藏在策略里

服务器可以闲着,却仍然拒绝给你带宽。限速、按客户端的带宽上限和流量整形,往往按通用名或按地址池生效,所以同一网关上的两个用户可能得到截然不同的结果。这套机制并不隐蔽,但从外面看不见,因为两种情况隧道都能正常建立。

要在隧道接口上找整形,而不是物理接口。检查限制跟随的是用户、证书还是地址池。如果你的测试账号落在不限速的池子里,你就会认定服务器没问题、抱怨的用户弄错了。这个结论比没有结论更糟,因为它把工单关掉了。

用一个固定任务比较两个节点

客户端侧的实验仍然值得做,但前提是把变量固定住。用同一台设备、同一个接入网络、同一种协议和同一个目标文件,然后对距离相近的第二个节点重复一遍。两次运行之间任何变化,包括一天中的时段,都会污染结果。

失败也要像成功一样认真记录。三个节点都通、一个超时的序列,比四个速度数字更有信息量,因为它指向路径或策略问题,而不是容量问题。每种情况至少跑两次;在共享网络上,单个偏慢的采样证明不了什么。

最后,把收集到的数字和它们支撑的结论放在一起。「这个节点在另一个卡住的同一时间窗口里完成了传输」是站得住脚的,而「这个节点更快」则会招来一场你没法用首页分数赢下的争论。如果需要主机侧的准确指令,OpenVPN 2.6 手册记录了状态文件和整形选项。

相关文章