网盘资源

frp 内网穿透实测:关掉多路复用反而快 44%

🦄折腾不止 LV1 · 1 次浏览 · 0 条回复

家里放片子的小主机没有公网 IP,出门在外想拿个文件、看一眼下载还剩多少,全靠 frp 这条隧道撑着。用了大半年,我发现网上教程基本都停在「服务端起起来、客户端连上去、页面能打开」这一步,至于它到底吃掉多少速度、几种传输方式该怎么选,几乎没人讲。这次把能开的模式全开了一遍,数据摆在这里,配的时候心里有底。

frp 内网穿透实测:关掉多路复用反而快 44%

测试怎么搭的

frps 和 frpc 都用官方 0.71.1 的 Windows 版,压缩包 13.5MB,解开后 frps.exe 19.9MB、frpc.exe 16.3MB,没有运行时依赖,拷过去双击就能跑。配置是 TOML,不再是老教程里那种 ini 写法。

服务端监听 7000,客户端把本机 8099 上的一个静态文件服务映射到 7100,然后分别测两件事:一个 256MB 的随机数据文件走一遍,看吞吐;再连续发 200 个 1KB 请求,看延迟分位。机器是一台 8 线程的老锐龙笔记本,全流程都在本机回环上跑。

这里要先说清一个前提:回环没有真实网络,所以绝对数值会比公网好看很多,能看的只有相对差距——frp 自己加了多少开销、不同模式之间差多远。真跑在公网上,两头还要各自加上一段物理延迟,百分比会变,但排序不会变。

五种模式的实际数字

| 传输方式 | 256MB 耗时 | 吞吐 | p50 | p95 |
| --- | --- | --- | --- | --- |
| 直连,不经 frp | 1.88s | 136.1 MB/s | 3.40ms | 5.20ms |
| tcp + 多路复用(默认) | 2.39~3.06s | 84~107 MB/s | 4.37ms | 6.29ms |
| tcp,关闭多路复用 | 1.66s | 154.1 MB/s | 4.58ms | 7.46ms |
| websocket | 4.48s | 57.2 MB/s | 5.17ms | 7.85ms |
| quic | 10.77s | 23.8 MB/s | 4.24ms | 5.85ms |
| kcp | 32.45s | 7.9 MB/s | 20.38ms | 21.47ms |

延迟那一栏是最有意思的:直连 3.4ms,套上 frp 变 4.4ms 左右,也就是说隧道本身只加了 1ms 上下,这个开销几乎可以忽略。但吞吐掉得比想象中多,默认配置下 256MB 文件要 2.4 到 3 秒,同一份数据直连只要 1.88 秒。

默认的多路复用不是最快的

frp 客户端默认开着 tcpMux,也就是把多个用户连接塞进一条和服务端之间的 TCP 里。好处是省握手、省端口,坏处是大流量时全都挤在一条连接上排队。我把它关掉之后,256MB 的耗时从 2.39 秒掉到 1.66 秒,吞吐从 107 涨到 154 MB/s,比默认配置高四成,甚至比直连那次测出来的还高一点——这部分是回环下的抖动,别当真。

代价在延迟尾部:p95 从 6.29ms 涨到 7.46ms,因为每来一个用户请求,客户端都要重新和 frps 建一条 TCP。二十路小请求并发那次,默认 96ms 完成,关掉复用后并没有更快。所以结论很清楚:整块传大文件(备份、拉片源、传镜像),关多路复用划算;日常开网页、看列表这种碎请求多的场景,留着默认更省事。

kcp 和 quic 慢得有点离谱

kcp 那一行不是笔误,256MB 走了 32 秒,只有 7.9 MB/s,延迟 p50 也从 4ms 涨到 20ms。KCP 这类协议本来就是拿带宽换延迟的,丢包多、延迟高的链路上它能救命,但在一条没有丢包的回环上,它的代价暴露得干干净净。frp 里 kcp 还要在服务端单独开 kcpBindPort,很多人照着教程加了这一行,然后发现速度只有几百 KB,回头怪服务器带宽——其实协议本身就这个量级。

quic 是 23.8 MB/s,比 kcp 好得多,但延迟 p50 4.24ms 反而是所有隧道里最低的,抖动也最小(p95 5.85ms)。所以它适合的是「请求多、每次数据量小」的场景,拿它传大文件纯属为难自己。websocket 落在 57.2 MB/s,中规中矩,它的价值在于能穿过只放行 80/443 的代理,速度不是它的卖点。

三个真踩过的坑

第一,多路复用要两端一起改。 我只在客户端写了 transport.tcpMux = false,服务端没动,结果日志里一行 login to the server failed: EOF,反复重试、没有任何提示说明是配置不一致。两边都改成 false 之后立刻正常。这个报错太容易让人以为是 token 写错了。

第二,kcp 和 quic 抢同一个 UDP 端口。 frpc 连 kcp 或 quic 时,用的都是配置里的 serverPort,不是单独填的端口。我在服务端同时写了 kcpBindPort = 7000 和 quicBindPort = 7000,启动直接报 bind: Only one usage of each socket address;把 quic 改成 7001 之后,客户端又连不上,timeout: no recent network activity。结论是这两种 UDP 传输只能二选一,服务端的 UDP 监听端口必须和 bindPort 保持一致。

第三,Web 面板默认是关的。 想知道当前几条连接、跑了多少流量,得自己在 frps 里加 webServer.port,然后访问 /api/serverinfo 才有 curConns 和 totalTrafficIn。这一步不写进配置,你就只能靠猜。

资源占用比想象中低

跑 256MB 传输的时候我顺手看了内存:frps 空闲 24.7MB,传完涨到 27.1MB;frpc 空闲 15.6MB,传完 16.7MB。全程几乎没波动,256MB 数据是边读边转的,不在内存里攒。所以一台 1 核 1G 的小机器同时带几十条隧道完全撑得住,瓶颈永远在带宽和协议开销上,不在 CPU 和内存。另外客户端被强杀之后再启动,275 毫秒就重新连上并恢复了映射,没有出现残留代理占着端口的情况。

我的选择

家宽上行本来就窄,隧道再吃掉一两成也无所谓,所以服务端保持默认 tcp,客户端也是默认的多路复用——省心,碎请求多的时候更稳。只有在整块往外搬片子、或者给另一台机器做整盘备份时,我才会临时切到关闭多路复用,多一点握手换那四成速度。kcp 留着备用,等哪天出门在外连的是那种丢包严重的网络再开。

你们那边的隧道是怎么配的,有没有在真实公网上量过吞吐?

回复

还没有回复,抢个沙发

登录后即可参与讨论

去登录 注册账号

相关帖子