集群部署
RustPBX 支持多节点集群模式,实现注册状态同步、SipFlow 分布式采集和跨节点呼叫控制。
1. 架构概述
┌──────────────┐
│ Load Balancer│
│ (SIP/HTTP) │
└──────┬───────┘
┌───────────┼───────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Node 1 │ │ Node 2 │ │ Node 3 │
│ SIP+HTTP │◄─► SIP+HTTP│◄─► SIP+HTTP│
│ SipFlow │ │ SipFlow │ │ SipFlow │
└──────────┘ └──────────┘ └──────────┘
│ │ │
└───────────┼───────────┘
▼
┌──────────────┐
│ MySQL/PgSQL │
└──────────────┘
关键特性:
- 节点间通过 SIP MESSAGE 同步注册/在线状态事件
- SipFlow 支持一致性哈希,按
call_id路由到指定采集节点 - 共享数据库(MySQL/PostgreSQL)保证配置和 CDR 一致
2. 数据库要求
集群模式 不支持 SQLite,必须使用共享数据库:
| 数据库 | 最低版本 | 推荐 | 说明 |
|---|---|---|---|
| MySQL | 8.0+ | 8.4 LTS | 字符集 utf8mb4,排序规则 utf8mb4_unicode_ci |
| PostgreSQL | 14+ | 16 | 建议启用 pg_stat_statements 监控 |
连接字符串示例:
# MySQL
database_url = "mysql://rustpbx:password@10.0.0.100:3306/rustpbx"
# PostgreSQL
database_url = "postgres://rustpbx:password@10.0.0.100:5432/rustpbx"
注意事项:
- 所有节点必须连接同一个数据库实例
- 首次启动时 SeaORM 会自动执行 migration,后续节点启动会检测并跳过已执行的 migration
- 数据库 DDL 文件位于源码根目录(
rustpbx_ddl_*.sql),可供手动建表参考
3. 集群配置
3.1 节点间事件同步
在 config.toml 的 [cluster] 段配置 peer 节点:
[cluster]
peers = [
{ addr = "10.0.0.2", sip_port = 5060, ami_port = 8080 },
{ addr = "10.0.0.3", sip_port = 5060, ami_port = 8080 },
]
每个节点只需配置其他节点,不需要包含自身。节点间通过 SIP MESSAGE(application/x-rustpbx-cluster-event)传输 JSON 事件。
同步的事件类型:
- Locator 事件:用户注册/注销状态
- Presence 事件:用户在线/离线/忙碌状态
3.2 SipFlow 集群模式
[sipflow]
[sipflow.remote]
flush_interval_secs = 5
[[sipflow.remote.nodes]]
udp = "10.0.0.2:6060"
http = "http://10.0.0.2:6060"
[[sipflow.remote.nodes]]
udp = "10.0.0.3:6060"
http = "http://10.0.0.3:6060"
- 每个 proxy 节点可读可写,按
call_id一致性哈希路由到正确的 SipFlow 采集节点 - 独立部署
sipflow二进制(在源码src/bin/sipflow.rs)作为采集服务器
3.3 每个节点的核心配置
http_addr = "0.0.0.0:8080"
database_url = "mysql://rustpbx:password@dbhost:3306/rustpbx"
external_ip = "10.0.0.1" # 本节点的公网/内网 IP
[proxy]
addr = "0.0.0.0"
udp_port = 5060
modules = ["acl", "auth", "registrar", "call", "presence"]
media_proxy = "auto"
[console]
session_secret = "your-secret-here" # 所有节点必须相同
3.4 分布式会话注册表(0.5+)
在 locator/presence 同步之外,0.5 版本将集群级会话注册表端到端打通:
- 按归属节点路由的操作:任意节点都可以对接管节点之外的通话执行应答、转接、挂断、设置变量——请求自动转发到持有该会话的节点。节点故障时,其会话会被标记为 offline,而不是变成幽灵会话。
- 会话
user_data复制:挂载在会话上的应用数据(CRM 工单号、营销活动标签、坐席上下文)会复制到对端节点。转接和子会话会继承这些数据,业务上下文不会因节点切换而丢失。 - 心跳指标:每个节点上报其持有会话的存活状态;AMI 健康端点暴露这些 gauges 供监控使用,自清理的 locator 绑定会上报为 offline。
应用侧接入点:PUT /api/calls/active/{session_id}/userdata 与 GET /static/docs-zh/rustpbx/static/docs-zh/userdata 在任意节点均可调用——操作会透明路由到归属节点。
4. 负载均衡配置
4.1 SIP 流量
使用 SIP Load Balancer(如 OpenSIPS、Kamailio)或 DNS SRV:
- 源 IP 哈希:保证同一用户的 REGISTER 消息路由到同一节点(减少跨节点同步)
- Call-ID 哈希:保证同一通话的信令在同一节点处理
4.2 HTTP 流量
使用 Nginx/HAProxy 反向代理:
upstream rustpbx {
ip_hash; # Session 粘性
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
}
5. 部署步骤
# 1. 准备共享数据库
mysql -u root -p -e "CREATE DATABASE rustpbx CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
# 2. 在每个节点部署
docker pull docker.cnb.cool/miuda.ai/rustpbx:latest
# 3. Node 1 (10.0.0.1)
docker run -d --name rustpbx \
-v $(pwd)/config.toml:/app/config.toml \
-v $(pwd)/config:/app/config \
-p 8080:8080 -p 5060:5060/udp \
docker.cnb.cool/miuda.ai/rustpbx:latest
# 4. Node 2/3 同理,修改 external_ip 和 cluster.peers
6. 运维要点
- 数据库连接池:每个节点默认连接池大小由 SeaORM 管理,节点数 × 连接数不要超过数据库
max_connections - 时间同步:所有节点必须 NTP 同步,CDR 时间戳依赖系统时钟
- 配置一致性:
config/trunks/、config/routes/等文件建议通过共享存储或 GitOps 同步到所有节点 - 滚动重启:逐节点重启,确保至少一个节点在线处理通话
- SipFlow 存储规划:每个采集节点的磁盘空间独立规划,按每天通话量估算(每通约 50-200KB 信令数据)
8. 集群 AMI 端点(商业版)
多节点部署在 {ami_path} 下暴露额外的集群管理端点:
| 方法 | 路径 | 说明 |
|---|---|---|
POST | /cluster/ping | 对所有对等节点发起健康探活 |
GET | /cluster/reload_config | 基于 SSE 的集群配置重载流 |
POST | /cluster/reload_sync | 向特定对等节点同步 JSON 重载负载 |
POST | /cluster/dispatch_command | 向对等节点分发呼叫控制命令 |
POST | /cluster/session_op | 按归属节点路由的 RWI 命令信封(终端节点本地执行) |
GET | /cluster/show_session/{session_id} | 在对等节点上显示详细呼叫会话状态 |
GET | /cluster/session_owner/{call_id} | 解析通话由哪个节点承载 |
GET | /cluster/list_calls | 列出集群中所有活跃呼叫(集群感知的 GET /calls 查询) |
POST | /cluster/set_userdata / get_userdata | 按归属节点路由的会话 user_data 复制 |
POST | /cluster/set_var / get_var | 按归属节点路由的呼叫变量 |
GET | /cluster/logs/recent · /cluster/logs/follow | 对等节点的近期日志与流式日志 |
GET | /cluster/evaluate_route | 基于集群路由栈的路由评估 |
这些端点支持集中式呼叫控制、跨节点会话检查、从任一节点下发协调配置,以及会话 user_data 的跨节点复制。