Featured image of post VPS 网络延迟诊断实战:从 TCP/IP 到 BGP 的全链路排障手册

VPS 网络延迟诊断实战:从 TCP/IP 到 BGP 的全链路排障手册

VPS 访问卡顿、丢包、时延抖动,到底卡在哪一层?本手册从物理链路到 BGP 路由,逐层拆解网络延迟的成因,给出可落地的排查命令、调优参数与省钱方案,让自托管站点的网络又快又稳。

引言:延迟卡在哪一层?

“VPS 访问卡顿"是一个被过度简化的问题。用户看到的"慢”,背后可能是物理链路、丢包、拥塞、BGP 选路、甚至内核参数中任意一层的锅。盲目续费升级带宽,往往花了钱却没解决问题。

本手册的排查原则:从底层往上逐层定位,先确认"是谁慢",再谈"怎么调"。

用户浏览器
   │  1. 应用层:DNS 解析慢 / TLS 握手 / 服务端处理
   │  2. TCP 层:三次握手、丢包重传、拥塞窗口
   │  3. IP 层:路由跳数、MTU、分片
   │  4. 物理/链路层:丢包率、延迟抖动、运营商 BGP
   ▼
   VPS 云主机

全文按这套分层顺序展开,每层给出一条 30 秒出结果的命令和一个省钱动作。


第 0 层:先确认"到底是哪一端慢"

很多"卡顿"根本不是 VPS 的问题,而是用户本地网络或 DNS。先跑这一组命令,30 秒排除大半误判:

# 1. DNS 解析耗时(>500ms 基本是本地/运营商 DNS 的锅)
time nslookup your-vps.com 8.8.8.8
time nslookup your-vps.com 223.5.5.5   # 阿里 DNS(国内)

# 2. 到 VPS 的 ICMP 延迟与丢包(30 个样本)
ping -c 30 your-vps.com

# 3. 从 VPS 侧反查(登录 VPS 执行)
ping -c 30 1.1.1.1
ping -c 30 8.8.8.8

# 4. 路由跳数,看中间在哪一跳卡住
traceroute your-vps.com        # Linux/macOS
tracert your-vps.com           # Windows

判读要点:

  • ping 延迟稳定但大(>100ms)→ 跨洲/跨运营商,考虑就近节点 + CDN
  • ping 延迟抖动剧烈(±50ms 以上)→ 拥塞或 BGP 选路不稳
  • traceroute 在中间某跳延迟突增→ 问题在那个中间 AS,绕不过去就换链路
  • VPS 侧 ping 外部快,用户侧慢 → 大概率用户本地网络,别急着升级 VPS

💡 省钱动作:如果你发现主要用户在国内,而 VPS 选在海外机房,就近换机房比加带宽省钱得多。一张国内小 VPS + 海外源站的"双节点"架构,体验远好于单一大带宽。


第 1 层:DNS 是隐形的大头

DNS 解析经常占掉"首字节时间(TTFB)“的 20-40%,但最容易被忽略。

# 数字段:DNS 查询、TCP 握手、TLS 握手、首字节各自耗时
curl -w "dns: %{time_namelookup}s  tcp: %{time_connect}s  tls: %{time_appconnect}s  ttfb: %{time_starttransfer}s\n" \
     -o /dev/null https://your-vps.com

# 看当前解析到哪个 IP(多次执行,看是否多 IP 轮询 / 是否跨海)
dig +short your-vps.com
dig your-vps.com | grep -A3 ANSWER

优化动作:

  • 用权威 DNS(如 Cloudflare 1.1.1.1 / 阿里 223.5.5.5)解析,把"最近 IP"给用户;如果你的服务部署在多家云,做地理 DNS 分发
  • CDN 兜底:静态资源走 CDN,TTFB 和 DNS 同时受益,且 CDN 的免费额度对中小站点足够
  • 检查 NS 记录是否还在旧服务商(换服务商没换 NS 是"假慢"高发区)
# 域名侧:加 CNAME 到 CDN,静态资源直接加速
static-your-vps.com.  CNAME   @your-domain.cdn.cloudflare.com.

💡 省钱动作:CDN 免费档(Cloudflare Free)能省掉你 70% 的"被投诉卡顿”,比买专用带宽便宜一个数量级。


第 2 层:TCP 层 —— 丢包与重传是延迟杀手

丢 1% 的包,TCP 的"超时重传"会让单次请求延迟放大 200ms+(默认 RTO 200ms)。这是"延迟大但不稳定"的最常见真凶。

# 1. 丢包 + 重传统计(最直接的证据)
cat /proc/net/snmp | grep -E '^(Tcp|Retrans)' 
# 关注 RetransSegs / OutSegs 比值,>1% 就有问题

# 2. 实时看每个连接的拥塞状态(需要安装:apt install iproute2)
ss -ti
# 输出里的 retrans、cwnd(拥塞窗口)、rtt 是关键

# 3. 抓包验证:确认重传是否发生在你的 VPS 网卡上
sudo tcpdump -i eth0 -nn 'tcp[tcpflags] & (tcp-retrans|tcp-ack) != 0' -c 20

内核调优(/etc/sysctl.d/99-vps-tuning.conf,针对低延迟场景):

# 启用 TCP 早期重传,减少重传等待
net.ipv4.tcp_sack = 1
net.ipv4.tcp_tw_reuse = 1

# 高 BDP(带宽-时延乘积)场景,调大拥塞窗口上限
# 默认 10MB(Linux 5.x 默认 65536 * MSS),跨洲链路建议提到 64MB
net.ipv4.tcp_rmem = 4096 262144 67108864
net.ipv4.tcp_wmem = 4096 262144 67108864

# 启用拥塞控制算法(默认 cubic;高延迟链路 bbr 显著更优)
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

# 网卡队列:多核 VPS 提升收发包吞吐
net.core.netdev_max_backlog = 16384
net.core.rps_cpus = 01   # 按核数改,4 核 = 0F
# 生效并验证
sudo sysctl --system
sysctl net.ipv4.tcp_congestion_control   # 应输出 bbr

⚠️ BBR 前提:内核 ≥ 4.9 才自带 bbr。老内核 VPS 需要手动装内核或换用 cubic。用 uname -r 先确认。

💡 省钱动作:fq 队列 + BBR 让单条 100Mbps 链路在多用户并发时不再"队头阻塞",等价于省掉你升级带宽的冲动。


第 3 层:IP 层 —— MTU 与路由跳数

两个高频但冷门的问题:

3.1 MTU 分片(PMtuD)

某些链路 MTU 不是 1500(隧道/VPN 常见 1420/1400),大包会被分片,丢一片就整包重传。

# 探测到目标的最大可不分片 MTU(-d 禁止分片)
ping -d -M do -s 1472 your-vps.com   # 1472 = 1500 - 28(icmp+ip 头)
ping -d -M do -s 1400 your-vps.com   # 逐步降,找到能通过的最大值

# 若某 MTU 能过而更大的不行 → 设 VPS 网卡 MTU
sudo ip link set eth0 mtu 1400

3.2 路由跳数异常

# 看当前路由表:默认走哪个网关、经过几个 AS
ip route
# traceroute 数跳数:>20 跳通常说明路径绕远(BGP 选路异常)
traceroute your-vps.com | wc -l

跳数多不一定是问题(跳数 ≠ 延迟),但跳数突然增多通常是上游 BGP 发生了路由变更(某运营商把流量甩到了远端)。

💡 省钱动作:如果你发现 BGP 路径绕行导致延迟升高,优先联系上游换 AS 出口,而不是在用户侧加带宽。


第 4 层:BGP 与运营商 —— “我连的是哪家”

这是自托管 VPS 最容易被忽视的一层。同一台 VPS,不同用户访问体验可能差 3 倍,差异主要来自"用户所在运营商到 VPS 出口 AS 的 BGP 路径"。

4.1 识别你的 VPS 出口 AS

# 登录 VPS 查自己的 ASN
whois 你的VPS_IP | grep -iE '^(OrgName|descr|as-number)'
# 或用在线工具:ipinfo.io / bgp.tools / whois 反查

# 查某 AS 的所有 IP 段(判断同 AS 互访是否内网化)
whois -h whois.radb.net '-i origin AS4837' | head -20

4.2 判断用户到 VPS 的 BGP 路径

# 从 VPS 侧看"到用户 AS 的路径"(需用户 IP 段)
# 用 bgp.he.net(在线)看两个 AS 间跳数:
# https://bgp.he.net/

典型坑:

  • 电信/联通/移动三网互通差:国内 VPS 若只有一线 AS 出口,移动用户访问电信资源会绕行 → 延迟翻倍
  • BGP 多线 vs 单线:国内机房"单线 BGP"(如只接电信)+ 目标用户跨网 = 必卡;要"全 BGP 多线"或 CN2 线路
  • 跨海光缆拥塞:晚高峰(20-23 点)跨海链路延迟普遍 +50ms,这是物理规律,只能就近建站,无法调参解决

4.3 自托管省钱的 BGP 策略

场景推荐月成本量级
主要用户在国内国内全 BGP / CN2 小 VPS¥50-150
国内+海外双用户群国内源站 + Cloudflare CDN 兜海外¥50 + CDN Free
纯海外用户离用户最近 AS 的 VPS按需
高并发突发VPS + 对象存储静态分流降低带宽峰值计费

💡 最省钱的一招:把大文件/静态资源丢对象存储(COS/S3/OSS 的公网读取有免费额度),VPS 只跑动态 API,带宽账单直接砍半。


第 5 层:VPS 内核网络栈最终调优清单

把前几层的"该调的都调了"汇总成一份可直接下发的脚本:

#!/usr/bin/env bash
# vps-net-tune.sh — VPS 低延迟网络调优(含前置检查)
set -euo pipefail

echo "==> 内核版本:" ; uname -r
echo "==> 当前拥塞算法:" ; sysctl net.ipv4.tcp_congestion_control

cat > /etc/sysctl.d/99-vps-net.conf <<'EOF'
# --- 拥塞控制 & 队列 ---
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# --- 缓冲区(高 BDP)---
net.ipv4.tcp_rmem = 4096 262144 67108864
net.ipv4.tcp_wmem = 4096 262144 67108864
# --- 连接与 TIME_WAIT ---
net.ipv4.tcp_tw_reuse = 1
net.netfilter.nf_conntrack_max = 262144
# --- UDP 收包(视频/实时场景)---
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.optmem_max = 65536
# --- 网卡 RPS 多核(按实际核数改 rps_cpus)---
net.core.netdev_max_backlog = 16384
EOF

sudo sysctl --system

# 验证
echo "==> 应用后:"
sysctl net.ipv4.tcp_congestion_control net.core.default_qdisc
echo "✅ 完成。重启或长期生效(写在 sysctl.d 里开机自动加载)。"

排障速查表

现象最可能卡在哪第一手命令
TTFB 大但 ping 正常DNS / 应用处理慢curl -w 'dns: %{time_namelookup}s'
延迟稳定大(>150ms)跨洲/跨海物理延迟ping -c 30 + 换就近节点
延迟剧烈抖动拥塞 / BGP 选路不稳ss -ti 看 cwnd 突变 + traceroute
间歇性大卡顿丢包重传cat /proc/net/snmp 看 RetransSegs
特定地区用户卡BGP 出口 AS 不匹配查 AS 号 + bgp.he.net
晚高峰才卡跨海光缆拥塞物理规律,就近建站
大包传输卡小包不卡MTU 分片ping -d -M do -s 1472

总结

网络延迟排障的唯一正确姿势是自底向上逐层定位,而不是上来就加带宽:

  1. 第 0 层先分清楚"是用户慢还是 VPS 慢",排除 80% 误判
  2. DNS 经常是隐形大头,CDN 是性价比最高的解
  3. TCP 丢包重传是"延迟不稳"的最常见真凶,BBR + fq 队列是免费药
  4. BGP 出口 AS 匹配决定"哪类用户卡",多线 BGP 或就近机房是唯一根治
  5. 内核调优脚本一键下发,长期生效

💰 最终省钱公式:就近建站 + CDN 兜静态 + BBR 调优 + 对象存储分流 = 体验提升 3 倍、带宽账单下降 50% 以上。先诊断再花钱,永远比直接升级 VPS 划算。

📺 看视频版教程 → DuckDB Lab YouTube

Subscribe for more DuckDB & AI automation tutorials