VPN 变慢时,最常见的做法是换节点、换协议碰运气。更省时间的方式是先把延迟拆成几段分别测量,再看差值落在哪一段。本文用三组 RTT 完成切分,然后逐一说明每一段常见的原因和验证命令。

先测三组 RTT
第一组是客户端到 VPN 服务器公网地址的 RTT,反映线路本身;第二组是隧道内到对端地址的 RTT,应该只比第一组略高;第三组是在服务器上测到目标站点的 RTT。三组相加大致等于你感受到的总延迟,哪一组明显异常,就往那一段查。
ping -c 20 203.0.113.10 # 到服务器公网地址
ping -c 20 10.8.0.1 # 隧道内到对端
mtr -rwzc 50 203.0.113.10 # 逐跳观察丢包和绕行怎么区分是线路问题还是隧道问题
如果第一组已经很高,延迟在隧道之前就产生了,换协议没有帮助,要看路径是否绕行或换一个接入点。如果第一组正常、第二组明显更高,问题在隧道本身,重点查 MTU 分片、加解密开销和运行模式。
四类常见原因

路由绕行怎么确认
mtr 的输出里会列出每一跳的延迟和自治系统号。延迟在某一跳突然跳升且后续所有跳都保持在高位,说明路径在那里绕到了远处;只有某一跳显示丢包而后面正常,通常只是路由器对 ICMP 限速,不是真实丢包。
丢包为什么会让延迟变高
TCP 遇到丢包会触发重传和拥塞窗口收缩,用户感受到的是卡顿和带宽上不去,而不是 ping 值变高。用 iperf3 -c 10.8.0.1 -t 30 测吞吐,再加 -R 测反向,两个方向差距很大时,多半是某一侧的上行带宽或队列出了问题。
缓冲膨胀怎么识别和缓解
在上传或下载跑满带宽的同时另开一个终端持续 ping,延迟从几十毫秒涨到几百毫秒,就是缓冲膨胀。缓解的方式是给出口队列换成 fq_codel,例如 tc qdisc replace dev eth0 root fq_codel,在路由器上则开启 SQM。
现象与定位对照
| 现象 | 更可能的所在段 | 验证方法 |
|---|---|---|
| 到服务器的 RTT 本来就高 | 线路或接入点 | mtr 查绕行,尝试其他接入点 |
| 隧道内 RTT 明显高于公网 RTT | 隧道本身 | 检查 MTU 分片、CPU 占用 |
| 空闲时正常,跑满带宽后变高 | 缓冲膨胀 | 负载下持续 ping,换 fq_codel |
| 吞吐远低于线路带宽 | 丢包或 CPU 瓶颈 | iperf3 双向测试,查看 CPU 占用 |
CPU 瓶颈的判断
加解密都在 CPU 上完成。跑 iperf3 时用 top 观察,如果某个核心被单个进程占满(OpenVPN 的用户态实现尤其常见),吞吐就被这个核心限制住了,这时增加带宽没有用,应考虑启用硬件加速的算法、换内核态实现,或升级服务器。




