你的 VPN 网关是被 CPU 卡住了吗?先看每核负载
平均值会掩盖真正吃紧的那个线程。在受控传输下观察每核负载,先排除路径因素,然后每轮只改一项有文档的设置。
先判断你撞上的是三种瓶颈中的哪一种,再去买更大的实例。一个核心满载、其余空闲,说明是每个连接的加密工作。传输时所有核心都饱和,说明是总处理能力。CPU 不高而重传数在涨,说明问题在网络路径。三者的第一步完全不同,只有一种能靠更大的实例解决。
三种瓶颈,一张表,三种修法
| Limit | Reading during a transfer | First move |
|---|---|---|
| Single thread | one core near 100%, siblings idle | spread flows across workers |
| Aggregate CPU | every core busy, load average climbs | capacity, or less work per byte |
| Path or provider | low CPU, retransmits or steal time high | MTU, loss, host contention |
把表格的每一行当作诊断,而不是阶段。一个线程跑满 100%、其余线程空闲,是单个大隧道网关上最常见的结果,因为这条流的加密只在一个核心上跑。传输期间所有核心都忙,说明机器已经尽了全力。CPU 不高而重传持续上升,说明处理器在等一个不断丢包的链路。
按证据顺序修。把流量分散到多个工作线程,只对第一种情况有效,对第二种毫无作用。更大的实例能解决第二种,却在第一种上白花钱。调整 MTU 或处理丢包,是唯一能碰到第三种情况的做法。 在还不知道自己在哪一行时就买容量 是最贵的猜测方式。
把吃紧的线程和忙碌的主机分开看
先从每核利用率入手,避免某个被卡住的核对平均值隐身。传输过程中跑一次,能看出负载是平的还是带尖峰的。两种形态都有信息量,而带尖峰往往说明采样窗口抓到的是调度器活动,而不是加密本身。
mpstat -P ALL 1 5
先把忙的核心归到某个进程,再归到某个线程。下面这条命令会把父线程和子线程一起保留,这在守护进程按连接 fork 时很关键:
pidstat -u -t -p $(pgrep -f 'openvpn|wireguard|ipsec') 1 10
内核里的加密永远不会出现在用户态进程计数器里。单独采样线程,再把这个视角和进程的账目对照:
top -H -b -n 1 | head -20
套接字计数器放在最后看,因为它决定加 CPU 到底有没有用。CPU 平稳而重传上升,不是处理器的问题。采样时让传输保持运行,否则这些数字描述的是一台空机器:
ss -ti | grep -E 'retrans|cwnd|rtt'
做一次受控传输,并且跑两遍
空闲计数器什么都证明不了,拿随机对端做基准测试也几乎证明不了什么。选一个客户端、一个目标、一次有代表性的传输,然后在同一时间窗口里记录吞吐和交互延迟。网关可能已经饱和,而大文件拷贝仍能跑完;真正让用户有感觉的是延迟曲线。把这次传输、客户端数量和守护进程版本写在数字旁边。
用多条并行流重复一次。增加流数后吞吐上升,说明瓶颈在每流的窗口;只有一个核心卡住而吞吐不变,说明瓶颈在处理。
然后把可选的负载停掉,再跑一次。同一台主机上的备份、日志转发或数据库,会让平均值看起来很忙,却和隧道毫无关系。如果主机其他方面都很安静、CPU 依旧被卡住,证据就指向 VPN 进程。如果 CPU 下来了,说明你一直在测邻居,网关根本不是问题。
在买硬件之前先排除路径
重传上升、拥塞窗口缩小、往返时延变大,这些都在把矛头从处理器上挪开。比较隧道 MTU 和路径 MTU,检查底层链路的丢包,确认客户端自己的上行不是瓶颈。更大的网关修不好一条丢包的链路,而用户会用同样的词描述这两种故障。重传计数器几分钟内就能把它们分开。
在虚拟服务器上,要把服务商的指标和客户机自己的指标放在一起看。被偷走的时间,就是超卖在客户机内部显现的方式,客户机里任何调优都去不掉它。客户机的计数器看不到宿主机,所以客户机图表干净,并不等于宿主机健康。
一次只改一项,只测一次
选择证据支持的那个假设,然后只改一项有文档支持的设置:工作线程数、有文档的卸载选项,或者实例规格。OpenVPN 发布了性能排障指南,讲的是同一套处理与传输的分界: OpenVPN 性能排障。
先确认卸载选项真的生效,而不是相信那个开关,然后用同样的传输复测、做同类比较。这是把真实改善和安静下午区分开的唯一办法。留一个能回滚的检查点,因为第二次改动往往就是人们记不清哪次起作用的时候。每轮只动一个变量,慢的是一天,快的是一个月。
不要为了图表好看去削弱认证或加密套件。如果 CPU 依旧不跟着症状走,就回到路径和应用层检查,而不是凭猜测升级硬件。