内网穿透延迟高?先检查流量路径绕了多远
2026/9/14 15:40:12 网站建设 项目流程

最近好几个朋友都在问我同一个问题:内网穿透连上了,但延迟高得离谱,传输速度慢到想砸键盘,到底怎么优化?我问他们的第一句话永远是:先别急着优化,先搞清楚你的流量到底绕了多远。很多人一脸懵——流量还能绕多远?还真能。

在家访问公司内网的机子,延迟300ms,你以为是自己路由器不行,结果traceroute一跑,数据包从你家出发,绕了半个地图才到中转服务器,再兜一圈回来。这种场景下,优化的优先级根本不是换协议、加带宽,而是先让流量路径变短。这篇文章我就把“流量绕路”这件事彻底讲透,从测量手段到优化动作,全部捋一遍。适合三类人看:自己搭了frp、ngrok这类穿透服务的人,用第三方内网穿透工具连得不痛快的人,以及在公司或家里有远程访问需求、天天被卡顿折磨的运维和开发。

1. 先别急着优化,搞清楚流量绕了多远

1.1 内网穿透的两种路径:中转转发和P2P直连

内网穿透本质上解决的是“公网无法直接访问内网设备”的问题。常见的实现方式分两类,理解这两类的区别,是后面所有排查的基础。

第一类是中转转发,典型代表是 frp 的 tcp/udp 代理模式、ngrok、cpolar 这类托管服务。工作流程是:客户端主动连上公网服务器,目标端也主动连上同一台服务器,数据流就是“发起方 -> 中转服务器 -> 目标端”。这种模式最大的优点是实现简单、不挑网络环境,因为两端都是主动外连,NAT 类型的影响很小。但代价也很明显——所有流量都要经过服务器转发,服务器在哪、带宽多大、转发性能如何,直接决定你的体验上限。

第二类是 P2P 直连,典型代表是 frp 的 xtcp 模式以及各类 mesh 组网工具。信令服务器只负责帮两端交换元数据、协商打洞参数,真正打洞成功后,数据流在两端之间直接传输,不再经过服务器。这种模式的流量路径最短,延迟和速度最接近内网直连,但能不能打洞成功、直连质量如何,完全取决于两端的 NAT 类型和网络环境。

打个比方:中转转发就像你寄快递,包裹非得去趟华北中转站,再发回华南,路径绕一大圈;P2P 直连像你俩就住隔壁小区,中介只负责给你俩互换电话号码,见面直接谈,不经过中介。

1.2 延迟高、速度慢,到底卡在哪一环

很多人一遇到慢就怀疑“软件不行”,其实延迟和速度的瓶颈通常存在于五个环节,你得先判断自己卡在哪。

第一是物理距离。光在光纤里的传播速度只有每秒约20万公里,数据包从北京到广州,光速往返至少40ms起步,这是物理上限,谁也没办法。第二是转发跳数。每经过一台路由器或服务器,都会引入几毫秒到几十毫秒的处理时延,多一跳就多一分延迟。第三是运营商互通。家庭宽带、公司专线、云服务器往往属于不同运营商,跨网出口拥堵时,即便距离很近,延迟也能翻倍。第四是服务器负载。共享带宽的免费服务器在高峰期被跑满,你的流量只能排队。第五是隧道封装开销和协议处理。加密、解封装、粘包拆包都会消耗 CPU 和带宽。

这五条里,真正能被你优化的是二三四五,而第一条只能通过换节点解决。所以你必须先判断当前慢是慢在哪条,而不是盲目动刀。

1.3 为什么“先测路径”能少走弯路

我把结论放在前头:不同路径慢下来,优化手段完全相反。

如果你走的是中转,延迟高大概率是服务器选址问题,优化重点是换更近的节点。如果你的方案本来应该 P2P 直连,结果实际流量还在经过服务器中转,那优化重点是解决打洞失败的原因。如果路径已经很短了,速度还慢,那才轮到调 MTU、TCP 窗口、拥塞控制这类传输参数。

顺序搞反了,你会在错误环节上投入大量精力。我见过不止一个人,明明是 frp 打洞没成功、流量一直在走服务器,他却拼命在服务器上升带宽,最后带宽翻了三倍,延迟一点没降。这就是典型的没搞清楚“流量绕了多远”就盲目优化。

2. 三招实测流量路径:从 ping 到抓包

2.1 ping 和 traceroute:先把延迟分布摊开

测量路径的第一步是分段 ping。假设场景是家里访问公司内网,穿透链路是“家里客户端 -> 中转服务器 -> 公司客户端 -> 目标服务”。你分别测:家里到服务器的延迟、公司到服务器的延迟、以及通过穿透隧道后两端互访的延迟。

我一般这样操作,在家里终端执行:

ping -c 20 服务器IP

在公司内网那台机器上也执行同样的命令。如果家里到服务器 25ms、公司到服务器 30ms,但你在家里通过穿透访问公司目标机器,应用层看到的 RTT 却是 150ms,那中间这 95ms 就是隧道额外开销、转发排队和多次 NAT 转换吃掉的时间。

接下来用 traceroute 看路径细节。Linux 和 macOS:

traceroute -n 服务器IP

Windows:

tracert -d 服务器IP

重点关注三件事:一是是否经过了异常多的跳数,比如到同一个城市竟然有 20 多跳,大概率绕了路;二是是否有明显的跨运营商跳变,比如从电信跳到联通,这往往意味着跨网出口拥塞;三是中间某几跳延迟突然飙升,说明那台路由器本身很忙,或者线路质量差。

2.2 iperf3:测隧道里的真实吞吐量

ping 和 traceroute 只能反映“网络通不通、延迟多少”,并不代表“隧道能跑多快”。我强烈建议用 iperf3 做一次端到端的吞吐测试。

在目标端(公司内网机器)启动服务端:

iperf3 -s -p 5201

在家里的机器上跑客户端,先测 TCP:

iperf3 -c 目标穿透地址 -p 5201 -t 30

再测 UDP:

iperf3 -c 目标穿透地址 -p 5201 -u -b 50M -t 30

TCP 测试看的是实际能跑多少带宽,UDP 测试看的是在固定带宽下丢包和抖动情况。这里有个非常关键的经验:单线程慢、多线程快,说明是 TCP 窗口和延迟带宽积的问题;UDP 在低带宽下丢包率很高,说明路径本身有问题,比如跨运营商限速;所有线程都慢,大概率是穿透明文转发带宽或服务器出口带宽被卡死。

iperf3 的输出里,除了 Bandwidth,一定要看 Jitter 和 Lost/Total Datagrams。UDP 抖动的单位是 ms,如果超过 10ms,对实时类应用(远程桌面、串流、语音)来说已经很难受了。

2.3 netstat 和抓包:确认数据真的走了哪条路

命令行测完,还要从连接层面确认流量路径。最简单的方法是在家里客户端机器上查看活动连接:

ss -tnp | grep 目标穿透端口

如果看到连接的对端 IP 是中转服务器的公网 IP,说明数据流走的是中转模式。如果你用的是支持 P2P 的方案,正常情况下对端 IP 应该显示成目标的公网 IP 或 NAT 映射后的地址;如果显示的仍然是信令服务器或中转服务器的 IP,那说明打洞没成功,数据还在绕服务器。

更彻底的办法是抓包。在目标端机器上用 tcpdump 抓取 iperf3 测试流量:

tcpdump -i eth0 host 客户端穿透连接地址 -w /tmp/throughput.pcap

然后在 Wireshark 里打开,看 TCP 流的源地址和目的地址、每包间隔、重传率。如果看到大量 Dup ACK 和重传,说明路径上丢包严重,这时候调整 MTU 比升级带宽更有效。

这里我想特别提醒:不要把“连接 IP”和“业务流量路径”搞混。有些穿透方案的控制面走信令服务器,数据面走直连,你光看客户端连接了信令服务器就断定“走了中转”,会误判。要区分控制连接和数据连接,别只凭一个 IP 下结论。

2.4 看日志:NAT 类型和打洞结果

很多穿透工具在建立连接时会打印 NAT 检测结果和打洞状态。frp 客户端启动日志里有 get nat type 的记录,显示本端 NAT 是 Full Cone 还是 Symmetric;一些组网工具的状态页里也会有 direct(直连)还是 relay(中继)的标注。这些日志信息是判断“为什么流量绕路”的第一手资料。

Symmetric NAT(对称型 NAT)天生难打洞,因为每次对外通信都会使用不同的端口映射,P2P 打洞基本靠运气。遇到这种网络,要么在路由器上开启 UPnP、手动做端口映射,把网络类型往宽松方向调,要么干脆接受走中转的现实,优化中转节点质量。

我见过太多人死磕打洞,天天换工具、改配置,最后发现家里宽带是运营商级 CGNAT,端口映射都没办法做。这种环境下的 P2P 方案就是镜花水月,不如老老实实选个好的中转节点。

3. 案例复盘:家里访问公司 NAS 的绕路全记录

3.1 现象:传输速度低到发指,远程桌面卡顿

有次我帮一个朋友排查远程访问公司 NAS 的问题。他自建了 frp 服务,家里 PC 访问公司 NAS 下载文件,速度只有 400KB/s 左右,远程桌面操作延迟肉眼可见,鼠标点了半天才有反应。他的第一反应是服务器带宽不够,打算加钱升级。我拦住了他,先跑了前面说的那套测量流程。

3.2 实测数据:路径、延迟、吞吐三层拆解

先分段 ping:家里到 frp 服务器,平均延迟 23ms;公司到 frp 服务器,平均延迟 27ms。理论上两端通过隧道互访,RTT 应该在 50ms 上下。但实际穿透访问时,RTT 飙到 128ms,多了 78ms 的额外开销。

再用 traceroute 看路径,家里这条链路经过的跳点有 18 跳,中间出现了两次跨运营商跳变——家里是电信,公司是联通,frp 服务器放在一个移动机房里,等于数据要经过电信出口到移动、移动再到联通,三个网来回折腾。

之后用 iperf3 在隧道内测 TCP,单线程只有 3.2Mbps,开 8 个线程能到 11Mbps。这已经说明瓶颈不完全是带宽,还有 TCP 窗口和拥塞控制算法在高延迟链路下感知迟钝的问题。

最后看 frp 的日志,发现客户端连接状态虽然正常,但流量走的是普通 tcp 代理模式,不是 xtcp 打洞模式。原因很简单:公司那台机器所在网络是 CGNAT,公网 IP 都不唯一,打洞根本没机会成功。

3.3 判断结论:三个问题叠加,别只怪带宽

综合数据,这个案例里慢不是单一原因:第一,frp 服务器位置距离两端都远,物理路径绕路;第二,三个运营商跨网互访,出口拥塞加剧延迟;第三,打洞失败导致所有流量都在过服务器转发,而服务器本身是共享带宽的小机器。三个因素叠加,400KB/s 已经很给面子了。

最终的处理是:把 frp 服务器换到离两端更近、网络互通性更好的机房,同时开启了连接压缩;远程桌面这类交互型应用走的代理,单独设置了较小的 MTU;下载大文件改用多线程工具并发获取。

折腾完后,同样下载大文件,速度到了 2.5MB/s,远程桌面延迟降到 50ms 左右。虽然比不上纯内网,但已经可用了。这个案例给我的启发是:如果一开始就盲目升级服务器带宽,只会多花冤枉钱,问题一点没解决。

4. 按绕路结论做优化:从换节点到调参数

4.1 中转模式优化:节点选择和线路质量优先

如果实测确认流量必须走中转,那优化的第一优先级永远是服务器位置,不是带宽。服务器放在离两个客户端都比较近的地方,物理距离缩短,延迟和丢包都会改善。

怎么选节点?可以用 ping 命令对比几个候选机房的往返延迟,也可以用在线拨测工具,模拟你所在地区的网络到目标机房的质量。我实测下来的经验是:同城同运营商的机房,RTT 通常在 10ms 以内;同省跨运营商在 20~30ms;跨省经常 50ms 起。优先选择同运营商或 BGP 多线机房,能显著降低跨网互访的损失。

带宽方面,注意区分“服务器带宽”和“免费服务共享带宽”。自建 frp 选云服务器时,如果预算有限,宁可买低带宽但稳定的实例,也别买免费共享带宽——高峰期别人的流量会把出口塞爆。另外,frp 服务端可以针对不同代理设置带宽限制,避免某个大流量任务把整条隧道打满,影响其他业务。

4.2 让流量尽量直连:NAT 类型和 P2P 打洞

如果你的业务对延迟敏感(远程桌面、串流、实时交互应用),理想的路径是 P2P 直连。打洞成功率受 NAT 类型影响非常大,我整理了一张经验对照表:

NAT 类型打洞表现建议
Full Cone最容易打洞,几乎一次成功无特别要求
Restricted Cone较容易打洞确认源 IP 限制策略
Port Restricted Cone可以打洞,需要端口匹配固定端口、开启 UPnP
Symmetric极难打洞,成功率低手动映射或考虑中转方案
CGNAT基本无法从外部打洞只能依赖中转或端口转发

优化打洞有几件具体的事可以做:一是在路由器上开启 UPnP,让客户端主动做端口映射;二是在穿透工具里配置固定的本地端口,避免通信时端口频繁变化;三是尽量使用支持同时发起 UDP 打洞和 TCP 打洞的工具,提高成功率;四是保持 NAT 映射的存活性,定期发送心跳,防止映射超时被回收。

在 frp 里,如果确实打洞失败,可以配置 fallback 机制,让流量在打洞不成功时自动切换到服务器转发。这样既保留了直连的可能性,又不至于完全不可用。这里想强调一下:打洞失败不代表方案失败,一个好的工具应该同时支持直连和中转,并在两者之间自动切换。

4.3 传输层调优:MTU、TCP 窗口和拥塞控制

如果路径已经最短,速度还不理想,就要看传输参数了。

最常被忽视的是 MTU。隧道封装会额外增加协议头,默认 MTU 1500 可能超出隧道实际的承载能力,导致 IP 分片。分片包在传输中一旦丢失,重传代价非常高。经验做法是把隧道内部接口的 MTU 降到 1400 左右,比如在 Linux 上:

ip link set tun0 mtu 1400

或者调整 TCP MSS:

iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360

然后是 TCP 窗口。在高延迟高带宽场景下,默认窗口往往不够。Linux 上可以临时调整接收窗口缓冲:

sysctl -w net.core.rmem_max=16777216 sysctl -w net.core.wmem_max=16777216 sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216" sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"

这些参数的意思是:允许单个 TCP 连接使用更大的缓冲区,从而在长肥网络中填满管道。没有调大窗口时,延迟 100ms、带宽 100Mbps 的链路,理论上限会被窗口大小卡住,实际有效吞吐远低于带宽。

拥塞控制算法也很关键。默认的 cubic 在丢包环境下容易过度退避,如果两端都是 Linux,可以试试 BBR:

sysctl -w net.ipv4.tcp_congestion_control=bbr

很多内网穿透隧道在高延迟下用 BBR 后吞吐有明显提升,尤其是无线或有轻微丢包的场景。但我必须提醒一句:这些调优都是在路径已经合理的前提下才有意义,路径绕路一万公里,再怎么调窗口也是杯水车薪。

4.4 按场景选型:不同穿透方式适合不同需求

优化到最后,往往发现“工具选错了”。不同场景应该选不同的穿透方式,我根据自己的使用经验列一个选型倾向:

  • 临时给客户展示本地 Demo:用 ngrok 或 cpolar 这类托管服务,最快、免部署,延迟不重要,能通就行。
  • 长期固定访问家里 NAS、公司办公系统:自建 frp,选好中转节点,必要时配 xtcp 打洞。
  • 多台设备组网、需要局域网式体验:用 mesh 类组网工具,让设备间尽量直连。
  • 远程桌面、游戏串流这类对延迟极敏感的应用:优先 P2P 直连,没有直连就别指望穿透能媲美内网,尽量把路径压缩到最短。

比如 moonlight 串流,在局域网内延迟极低,但一旦走内网穿透,经过中转服务器转发,延迟可能从 2ms 飙到 50ms 以上,并且画质波动明显。这是因为串流数据量大、实时性要求高,中转服务器的转发延迟和带宽波动都会直接放大到画面卡顿上。这不是 moonlight 本身的问题,而是本该局域网用的东西被强行拖上了跨网路径。spacedesk 扩展屏也是同理,局域网内还能凑合用,跨网基本不可用——它的协议是为低延迟 LAN 设计的,不是为高延迟 WAN 设计的。

5. 常见问题与避坑实录

5.1 高发问题速查表

我把自己踩过、帮别人排查过的高频问题整理成一个速查表,遇到类似问题可以照着排查。

现象可能原因排查手段处理方向
延迟高但带宽正常路径绕路/服务器远traceroute、分段 ping更换更近节点、优化线路
单线程慢、多线程快TCP 窗口不足iperf3 单/多线程对比调大窗口、换拥塞控制
小文件快、大文件慢服务器出口带宽被占满查看服务器流量监控升级带宽、限制并发、压缩
时快时慢、周期性波动运营商晚高峰拥塞定时 ping 画延迟曲线避开高峰、换 BGP 线路
打洞成功但一段时间后失效NAT 映射超时观察连接状态变化缩短心跳间隔、固定本地端口
传输速度远低于预期且重传多MTU 分片/丢包tcpdump、iperf3 UDP 测丢包降低 MTU、调整 MSS
网页能开、大流量应用卡免费服务限速查服务商限制说明换自建或收费方案

5.2 三个容易被忽略的“隐形坑”

第一个坑是服务器端“上行带宽”被低估。很多云服务器标注的带宽是下行带宽或平均值,上行带宽可能只有标称的一半甚至更低。而内网穿透的流量方向恰恰是“两端上行到服务器,服务器下行给另一端”,两边上行带宽都紧张时,整条隧道都会卡。选服务器前一定要看清楚带宽规格,最好实测上传。

第二个坑是“测通了”不等于“测好了”。很多人看到穿透能连上、ping 通了,就宣布正常了。但 ping 通只代表 ICMP 往返正常,不代表 TCP 吞吐、UDP 丢包、大数据传输都正常。你必须在实际使用路径上跑一次 iperf3、传一次大文件,才算完成验收。我见过一个项目,穿透服务“ping 延迟看起来很漂亮”,但传几百 MB 的文件就断流,最后发现是 UDP 限速导致控制报文大量丢失,隧道频繁重建。

第三个坑是“免费服务不一定省心”。免费内网穿透服务为了控制成本,往往限制带宽、限制时长、高峰期排队,而且节点位置不可控。如果你对延迟和速度有明确要求,建议尽早迁移到自建或付费服务。免费方案只适合临时调试,不适合连续跑业务。我自己也用过免费的樱花 frp 之类的服务,临时演示没问题,但拿它当生产环境用,真的会疯。

5.3 排查过程中的小技巧

分享一个我一直在用的排查习惯:写一个简单的拨测脚本,每隔一分钟 ping 一次穿透服务器的公网 IP,记录延迟和丢包,持续跑一两天,然后画出延迟曲线。这样你能看到网络质量在一天内的变化:是全天都差,还是只在特定时段差;是稳定高延迟,还是时不时抖动。这份数据比任何临时测试都更能说明问题,也决定了你到底该换网络、换服务器,还是换个穿透方案。

另外一个技巧是,在做任何调优前,先记录当前的“基线数据”:隧道内 RTT、单线程 TCP 吞吐、UDP 丢包率、远程桌面体验评分。每改一个参数,重新测一遍同样脚本,对比基线看是否有改善。没有基线数据,你根本分不清改完是好是坏,很容易被网络本身的波动误导。这个习惯看起来简单,但真的能帮你省下大量试错时间。

说起来,这套“先测路径再优化”的流程,跟着我辗转了好几个项目和无数个深夜排查现场,已经成了我处理内网穿透问题的肌肉记忆。每次遇到延迟高、速度慢,我脑子里跳出来的第一句话永远是:先测流量绕了多远。很多人以为优化是拼参数、堆配置,其实更多时候只是让流量走一条更近的路。希望这篇文章能帮你把排查的顺序摆正,遇到类似问题先从“流量走了哪条路”开始,少走弯路,也少花冤枉钱。最后再啰嗦一句:任何优化动作的前提都是保留好基线数据,改一步测一步,别一口气把所有参数都动了,不然出了问题,你连回滚都不知道从哪里开始。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询