引言:延迟卡在哪一层?
“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)→ 跨洲/跨运营商,考虑就近节点 + CDNping延迟抖动剧烈(±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 |
总结
网络延迟排障的唯一正确姿势是自底向上逐层定位,而不是上来就加带宽:
- 第 0 层先分清楚"是用户慢还是 VPS 慢",排除 80% 误判
- DNS 经常是隐形大头,CDN 是性价比最高的解
- TCP 丢包重传是"延迟不稳"的最常见真凶,BBR + fq 队列是免费药
- BGP 出口 AS 匹配决定"哪类用户卡",多线 BGP 或就近机房是唯一根治
- 内核调优脚本一键下发,长期生效
💰 最终省钱公式:就近建站 + CDN 兜静态 + BBR 调优 + 对象存储分流 = 体验提升 3 倍、带宽账单下降 50% 以上。先诊断再花钱,永远比直接升级 VPS 划算。
