news 2026/8/24 11:26:38

RustDesk 私有化高可用部署:双信令节点加四层负载均衡落地

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RustDesk 私有化高可用部署:双信令节点加四层负载均衡落地

RustDesk 私有化高可用部署:双信令节点加四层负载均衡落地

【免费下载链接】rustdeskAn open-source remote desktop application designed for self-hosting, as an alternative to TeamViewer.项目地址: https://gitcode.com/GitHub_Trending/ru/rustdesk

凌晨一点,告警群弹出"信令服务器无响应",客户端开始成批报"连接服务器失败"——单台自建 RustDesk 信令/中继服务器宕机,所有远程会话同时断开。本文给出可落地的方案:2 台无状态 RustDesk 信令/中继服务器 + 1 台四层负载均衡,客户端填双 IP 自动切换,从克隆仓库到验证会话约 20 分钟。

部署全景图:信令双节点加四层负载均衡

图 1:客户端首页,ID 由信令服务器签发

[RustDesk 客户端 xN] | 信令 UDP 21116 / TCP 21117,中继 TCP 21118 [ nginx stream 四层负载均衡 ] | | [rustdesk-server A] [rustdesk-server B] [ relay 中继节点(独立,只挂 21118)]

客户端负责会话建立与 P2P 打洞;负载均衡层做四层转发,无状态;信令/中继服务器无本地状态,任意一台可承接新会话,这是双机切换的前提;relay 节点独立部署,避免信令故障连带拖死在途流量。

前置准备:2C4G 起与端口清单

  • 2 台 2C4G Linux 服务器(Ubuntu 20.04+ 或 Debian 11),1 台 nginx 负载均衡机(可复用其中一台)
  • 端口:UDP21116(信令)、TCP21117(备用信令)、TCP21118(中继转发)
  • 构建机需要 Rust 工具链、vcpkg 及libvpx libyuv opus aom编译依赖(见仓库 Dockerfile 的依赖清单)
  • 客户端版本与服务端版本保持同一主线,跨大版本可能协议不兼容

克隆源码并编译客户端

git clone https://gitcode.com/GitHub_Trending/ru/rustdesk cd rustdesk && cargo build --release
  • --release全量编译约 15~30 分钟
  • 产物落在target/release/,供下一步 systemd 路径引用

核心部署步骤:从防火墙到双节点切换

开放信令与中继端口的防火墙配置

服务器防火墙

ufw allow 21116/udp # 信令主通道,P2P 打洞 ufw allow 21117/tcp # 信令备用通道 ufw allow 21118/tcp # 中继转发 ufw enable
  • UDP21116不通时打洞协商无法进行
  • TCP21117是 UDP 受阻时的兜底信令
  • TCP21118承载所有 P2P 失败流量的中转

部署 RustDesk 服务单元并开启自动拉起

服务单元模板在res/rustdesk.service,不要整篇照抄——官方模板缺Restart行(⚠️ 进程崩溃后 systemd 默认不会拉起),按下面三处改完再装:

[Service] ExecStart=/opt/rustdesk/rustdesk --server Restart=always RestartSec=3 LimitNOFILE=100000
  • ExecStart指向二进制真实路径,装错路径服务起不来
  • Restart=always+RestartSec=3:异常退出 3 秒后自动拉起
  • LimitNOFILE决定单机可承载的并发会话上限

配置 nginx 四层负载均衡与中继粘滞

编辑 nginx 配置,在events块后加入:

stream { upstream sig_udp { server 10.0.0.11:21116; server 10.0.0.12:21116; } upstream sig_tcp { server 10.0.0.11:21117; server 10.0.0.12:21117; } upstream relay { server 10.0.0.13:21118; server 10.0.0.14:21118; hash $remote_ip consistent; } server { listen 21116 udp; proxy_pass sig_udp; } server { listen 21117; proxy_pass sig_tcp; } server { listen 21118; proxy_pass relay; } }
  • 信令 UDP/TCP 做普通轮询,连接短命、无状态
  • 中继hash $remote_ip consistent:同一会话必须粘滞在固定节点,漂移即断流
  • consistent保证节点增减时大部分哈希桶不动,存量会话不迁移

在客户端填入双节点地址完成接入

客户端设置页的"自定义中继服务器"分别填10.0.0.11:2111710.0.0.12:21117与对应中继地址,IP 列表两个节点都填,客户端会自动完成切换。验证链路:

sudo nginx -s reload systemctl status rustdesk-server ss -lntu | grep -E '2111[6-8]'

图 2:远程会话建立后的文件传输页

关键参数深度解读:最容易配错的三处

将 LimitNOFILE 调到 100000 防 fd 耗尽

  • 默认值:systemd 默认1024
  • 推荐值:100000res/rustdesk.service模板中的取值)
  • 为什么:每个远程会话占用多个 fd——视频流、音频、剪贴板、文件传输通道各占一份,并发 500 台设备时1024上限会被快速吃满,新连接在握手阶段就被拒;100000基本不会触发上限。

中继端口 21118 的定位:兜底通道而非主路

  • 默认值:relay 监听21118
  • 推荐值:保持不变
  • 为什么:P2P 打洞成功时客户端之间直连,中继不走流量;打洞失败才经21118中转。中继节点带宽按"预期走中继的流量"规划,通常是全量的零头,把它当主路规划会白白多买带宽。

把 Restart 设为 always 并保留 3 秒间隔

  • 默认值:systemdRestart=no
  • 推荐值:Restart=always+RestartSec=3
  • 为什么:进程被 OOM killer 或段错误杀掉后,no意味着 systemd 不再拉起,要等人工发现,而会话已经断了;RestartSec=3给 3 秒缓冲,避免进程反复崩溃时的重启风暴。

故障诊断路径:从连接失败现象逐级定位

现象:客户端卡在"正在连接信令服务器"。先查服务是否还活着——systemctl status rustdesk-server,已退出就journalctl -u rustdesk-server -n 50看崩溃前最后几行,OOM 记录里会写明被杀的时机;再查端口是否真的在监听——ss -lntu | grep 21117,端口没起来通常是进程异常退出,端口在但客户端连不上则是网络问题;最后从客户端侧抓包——tcpdump -i any port 21116 or port 21117,包发出去了收不到回应,问题在中间链路(安全组、NAT)把 UDP 丢了,此时改用 TCP 21117 兜底。

现象:信令通了但延迟高、流量走了中继。在 relay 节点上同时抓两个端口:

tcpdump -i any port 21118 or port 21116 -n
  • 媒体流全在2111821116上几乎没有打洞流量,说明 P2P 长期失败
  • 常见根因是客户端侧对称型 NAT,打洞成功率极低
  • 可在客户端设置里启用disable-udp让信令强制走 TCP(src/lang/cn.rs中有该选项的说明文案),打洞成功率下降,换的是连接建立的稳定性

生产环境建议:按规模选边界

  • 信令双机 + 四层负载均衡:单台宕机时客户端切到另一台,全程不断信;代价是两台都要预留完整会话容量,平时利用率约 50%
  • relay 节点独立部署:不要把信令和中继塞进同一个进程或容器,信令挂了不该连带拖死在途流量;代价是多占一台 2C4G
  • 客户端填双节点 IP 列表:切换由客户端本地完成,对业务无感;代价是每个节点都要持有完整设备密钥
  • 中继带宽按中继流量预留:别按全量买,实际 P2P 成功的会话不经它;代价是 P2P 失败比例突增时会出现排队

这套方案适合几十到几百台被控设备的私有化部署,单机房或双机房都够用;一旦需要账号体系、Web 管理台或多租户隔离,应升级到商业版 Server Pro;再往上按 K8s 加多可用区规划,本文的单机 systemd 方案就不适用了。

【免费下载链接】rustdeskAn open-source remote desktop application designed for self-hosting, as an alternative to TeamViewer.项目地址: https://gitcode.com/GitHub_Trending/ru/rustdesk

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/24 11:26:35

AI自动化代理入门:从核心原理到LangChain实战构建智能业务助手

最近在技术社区和开发者交流中,经常看到大家对“AI自动化代理”这个概念既充满好奇,又感到无从下手。很多人以为这需要高深的算法知识或庞大的算力,但实际上,借助成熟的工具和清晰的思路,初学者完全可以从一个具体的、…

作者头像 李华
网站建设 2026/8/24 11:23:02

STM32+FreeRTOS信号量原理与实战:从内存布局到三类选型

1. 为什么在STM32上用FreeRTOS信号量,而不是裸机轮询或全局标志?我第一次在STM32F407上做温湿度采集OLED显示串口上传三任务协同时,用的是最原始的全局变量while(1)轮询:主循环里不断检查ADC转换完成标志、OLED刷新计时器、串口接…

作者头像 李华
网站建设 2026/8/24 11:21:36

C++模板核心概念解析:类模板与模板类的本质区别

1. 项目概述:从“模板”的困惑说起如果你在C的学习或面试准备中,看到“类模板”和“模板类”、“函数模板”和“模板函数”这两组词,是不是感觉头都大了?它们看起来几乎一样,很多教材和网络文章也常常混用,…

作者头像 李华
网站建设 2026/8/24 11:21:15

5 步跑通 Deep-Live-Cam:从空白环境到实时换脸的完整路线图

5 步跑通 Deep-Live-Cam:从空白环境到实时换脸的完整路线图 【免费下载链接】Deep-Live-Cam real time face swap and one-click video deepfake with only a single image 项目地址: https://gitcode.com/GitHub_Trending/de/Deep-Live-Cam Deep-Live-Cam 是…

作者头像 李华
网站建设 2026/8/24 11:21:13

C++模板核心解析:类模板与模板类的本质区别与应用实践

1. 项目概述:从“模板”的困惑说起 如果你在C的学习或面试路上,被“类模板”和“模板类”、“函数模板”和“模板函数”这两组词绕晕过,那你绝对不是一个人。这几乎是每个C开发者都会遇到的经典困惑点,看似是文字游戏,…

作者头像 李华