39
0
0

用 EdgeOne WSS 加速 FRP:双通道反向代理部署实录

2026-09-09
2026-09-09
用 EdgeOne WSS 加速 FRP:双通道反向代理部署实录

用 EdgeOne WSS 加速 FRP:双通道反向代理部署实录

家里的服务器没有公网入口,业务统一由香港节点上的 Nginx 对外提供 HTTPS,再通过内网穿透访问本地服务。原来的公网直连 FRP 能用,但跨境路径延迟和抖动较大。为了改善这一段链路,我把 FRP 的主连接改为原生 WSS,让它通过腾讯云 EdgeOne 中转,同时保留原来的直连 FRP 作为自动备用线路。

最终结构不是“让 CDN 直接反代每个本地应用”,而是让 CDN 承载 FRP 客户端到服务端之间的 WSS 隧道。用户访问的业务域名仍然由香港 Nginx 统一接入和分流。

FRP over EdgeOne WSS 双通道架构
FRP over EdgeOne WSS 双通道架构

改造目标

这次改造需要同时满足四点:

  1. 本地服务器仍然不开放公网端口;
  2. FRP 跨境链路尽量经过 EdgeOne 的优化网络;
  3. EdgeOne 或 WSS 短暂断线时,公网服务不能随之中断;
  4. Halo、面板、监控、Agent 等现有服务统一使用同一套主备逻辑。

仅把普通 FRP TCP 端口放到 CDN 后面通常不可行,因为常规 CDN 主要处理 HTTP、HTTPS 和 WebSocket。FRP 0.71.0 原生支持 wss 传输,因此可以把控制连接和数据连接封装成 WebSocket Secure,再通过 EdgeOne 的 443 入口到达香港节点。

两条并行隧道

生产环境同时运行两套 FRP。

WSS 主通道


本地 frpc-wss

  -> wss://ws.example.com:443

  -> 腾讯云 EdgeOne

  -> 香港 Nginx WebSocket 入口

  -> 回环 frps-wss:7100

  -> 香港回环业务端口 18190-18198

FRP 客户端的核心配置思路如下,域名和认证信息使用占位符:


serverAddr = "ws.example.com"

serverPort = 443



transport.protocol = "wss"

transport.tls.enable = true

transport.tls.serverName = "ws.example.com"



auth.method = "token"

auth.token = "<FRP_TOKEN>"

EdgeOne 在公网侧终止 TLS,并通过 HTTP/1.1 WebSocket 回源到香港 Nginx。Nginx 再把升级后的连接转发给仅监听回环地址的 frps-wss。这样 FRPS 不需要直接暴露第二个公网控制端口。

直连备用通道


本地 frpc-direct

  -> 香港公网 FRPS:7000

  -> 香港回环业务端口 18090-18098

这条线路不经过 EdgeOne,延迟较高,但路径简单、故障域不同。它不是临时测试线路,而是长期保留的生产备用通道。

端口规划

两套 FRP 映射同一批本地服务,香港侧使用不同的回环端口:

本地服务端口直连备用WSS 主通道用途
80901809018190Halo
54631809118191管理面板
61851809218192AstrBot
257741809318193Komari
80601809418194Certimate
52441809518195OpenList
801809618196网站
567891809718197温度接口
91191809818198Agent

这些端口都只在香港回环地址监听,不直接向公网开放。公网入口仍由 Nginx 按域名提供。

Nginx 自动回退

香港 Nginx 为每个业务配置两个上游:WSS 端口为主,直连端口标记为 backup


upstream app_backend {

    server 127.0.0.1:18190 max_fails=1 fail_timeout=5s;

    server 127.0.0.1:18090 backup;

}



location / {

    proxy_pass http://app_backend;

    proxy_connect_timeout 2s;

    proxy_read_timeout 60s;

    proxy_next_upstream error timeout invalid_header http_502 http_503 http_504;

    proxy_next_upstream_tries 2;

}

回退只在连接失败、超时、响应头无效或出现 502/503/504 时触发。业务正常返回的 302401 等状态不会导致误切换。

这层设计很重要。实测 EdgeOne 会周期性断开 WebSocket,FRPC 通常能很快重连,但偶尔会经历数秒恢复窗口。没有备用通道时,这个窗口会直接表现为公网 502;有 Nginx 主备后,请求会自动改走直连 FRP。

部署顺序

为了避免一次切换影响全部服务,部署按以下顺序推进:

  1. 在香港启动独立的 `frps-wss`,仅监听回环地址;
  2. 为 WSS 域名增加 Nginx WebSocket 入口,并让 EdgeOne 回源该入口;
  3. 本地启动独立的 `frpc-wss`,先只映射温度接口;
  4. 连续验证真实 HTTP 数据,而不只看 FRPC 是否显示登录成功;
  5. 扩展到全部本地服务,对比两条线路的状态码和响应大小;
  6. 将 Nginx 上游切换为 WSS 主、直连备用;
  7. 把两套 FRP 都纳入 systemd,并配置自动重启;
  8. 主动停止 WSS 客户端,验证公网请求能否经备用线路继续完成。

这里最容易忽略的一点是:控制连接成功不等于业务数据面成功。测试必须请求真实接口,并核对状态码、响应大小和耗时。

实测结果

温度接口通过 WSS 连续请求 30 次,结果为 30/30 成功,响应内容保持一致:


WSS 最低:0.246 秒

WSS 平均:0.304 秒

WSS 最高:0.571 秒

同一接口在直连 FRP 路径上的观测耗时约为:


直连 FRP:3.52-7.21 秒

EdgeOne WSS:0.09-0.57 秒(不同批次)

Agent 服务也进行了双路径对比:WSS 路径约 0.063 秒,直连路径约 1.23 秒。不同时间段的绝对值会变化,但在当前网络环境下,WSS 路径的改善很明显。

FRP 直连与 EdgeOne WSS 实测延迟范围
FRP 直连与 EdgeOne WSS 实测延迟范围

这些数据只代表本次网络、地区和运营商条件,不能简单外推到其他环境。EdgeOne 的实际路由也会动态变化,因此生产设计不能只追求一次测速结果,还要考虑线路失效时如何恢复。

2026-09-09 复测:20 轮交替请求

为了排除先测某条线路带来的顺序偏差,这次从香港中转机交替请求直连 FRP 与 EdgeOne WSS 两个端口。每条通道测试 20 轮,每次关闭缓存并读取完整约 180 KB 的温度接口响应体。

指标FRP 直连备用EdgeOne WSS 主通道
成功率20/2020/20
平均耗时4.9365 秒0.2378 秒
中位数4.1763 秒0.2560 秒
P959.1181 秒0.3462 秒
最低值2.1323 秒0.0967 秒
最高值11.1451 秒0.4267 秒
FRP 直连与 EdgeOne WSS 20 轮复测对比
FRP 直连与 EdgeOne WSS 20 轮复测对比

本轮两条线路均为 20/20 成功。WSS 的平均响应耗时约为直连 FRP 的 1/20.76,平均延迟降低 95.18%。共享纵轴用于呈现两条线路的数量级差异,图中数据均为原始观测值,没有进行平滑处理。

这组结果仍然只代表测试当时的网络条件,不构成固定性能保证。直连线路虽然慢,但故障域与 EdgeOne WSS 不同,继续保留它作为自动备用仍有必要。

补充测试:丢包、TCP 重传与最终失败率

仅有 20/20 请求成功不能说明网络层没有丢包。FRP 直连和 WSS 都使用 TCP,底层丢包通常会被 TCP 重传修复,因此这里分别测量三种不同口径:

  1. 本地服务器到入口节点的 ICMP 路径基线;
  2. 受控传输窗口内,FRPC 主数据连接新增 TCP 重传字节占比;
  3. 两条隧道各 50 次完整约 180 KB HTTP 响应的最终失败率。
指标FRP 直连 / 香港公网EdgeOne WSS / EdgeOne 节点
ICMP 包数100100
ICMP 丢包率7%3%
平均 RTT268.8 ms63.1 ms
TCP 重传字节占比3.5843%0.1186%
完整 HTTP 请求50/5050/50
应用最终失败率0%0%
50 轮平均耗时6.3904 秒0.2528 秒
50 轮 P959.6144 秒0.4779 秒
FRP 双通道丢包、重传与最终失败率
FRP 双通道丢包、重传与最终失败率

本轮直连路径的 TCP 重传字节占比约为 WSS 的 30.23 倍。两条 TCP 隧道最终都能完整交付请求,但直连路径较高的丢包与重传会被转化为明显的等待时间和抖动。

需要注意,ICMP 丢包率、TCP 重传占比和应用失败率不是同一个指标:ICMP 只描述到入口节点的路径基线;TCP 重传反映可靠传输为修复丢包或乱序付出的代价;应用失败率则表示在超时限制内是否拿到了完整响应。

故障演练

部署完成后,我主动停止了本地 frpc-wss。香港侧 WSS 映射端口随控制连接断开而消失,Nginx 随即尝试直连 FRP 备用端口。所有业务域名仍返回预期状态,随后恢复 frpc-wss,主端口重新注册并继续承载请求。

这次演练验证了三个层面:

  • WSS 线路确实是当前主通道;
  • 直连 FRP 不是纸面配置,而是可用的数据通道;
  • Nginx 的失败判定和重试条件能够覆盖 WSS 断线窗口。

这套方案解决了什么

EdgeOne 改善的是本地到香港之间的 FRP WSS 长连接路径,不是绕过香港 Nginx,也不是让每个本地应用单独接入 CDN。香港 Nginx 仍然负责证书、域名分流、上游选择和故障回退。

最终请求逻辑可以概括为:


用户 -> 香港 Nginx

             |-> WSS FRP 主通道 -> 本地服务

             `-> 直连 FRP 备用 -> 本地服务

主通道提供更低延迟,备用通道覆盖 EdgeOne 周期断连和重连失败窗口。两条线路使用不同入口和不同 FRPS 实例,避免单一链路故障拖垮全部公网服务。

安全与运维注意事项

  • FRP Token、MCP 密钥、对象存储密钥和 SSH 凭据都不应写入文章或公开配置;
  • FRPS 的业务映射端口只监听回环地址,由 Nginx 统一暴露;
  • WSS FRPS 与直连 FRPS 使用独立服务和配置文件;
  • systemd 配置 `Restart=always`,同时监控重连日志和端口注册状态;
  • 发布配置前先执行 `nginx -t`,成功后再 reload;
  • 定期进行真实故障演练,而不是只确认服务显示 `active`。

这次改造的关键并不是单纯“套一层 CDN”,而是把链路优化和故障回退同时纳入设计。WSS 负责速度,直连 FRP 负责兜底,Nginx 负责在两者之间自动选择。

评论