# 系统架构 ## 进程模型 REX Hub 和 REX Agent 使用相同的运行时模型:单个可执行文件启动后,父进程作为 supervisor,启动 1 个 worker 子进程负责业务逻辑。 ```text rex-hub / rex-agent 启动(PID 1) ↓ 父进程进入 supervisor 模式 ↓ 启动 worker 子进程 ``` ### supervisor 循环 supervisor 负责: 1. 启动 worker 子进程 2. 监控 worker 退出状态 3. 根据退出码决定下一步(重启/更新/回滚) ### 退出码语义 | 退出码 | 含义 | supervisor 行为 | |--------|------|----------------| | `0` | 正常退出 | 检查 update-state.json,决定是否替换二进制 | | `10` | 请求更新 | 读取 update-state.json,替换二进制,启动新版 | | `11` | 健康检查失败 | attempt + 1,连续 3 次回滚 | | `12` | 崩溃/异常退出 | attempt + 1,连续 3 次回滚 | ## 通信协议 ### 浏览器 ↔ Hub | 链路 | 协议 | |------|------| | 控制台 ↔ 服务端 | HTTPS (REST API) + WebSocket (终端/数据实时流) | ### Hub ↔ Agent | 链路 | 协议 | |------|------| | Agent ↔ 服务端 | WebSocket (TLS) 加密反向隧道 | Agent 从内网主动出站连接 Hub,建立 WebSocket 加密隧道,内网服务器无需开放入站端口。 ## 连接通道 ### 直连资源 ```text 浏览器 ↓ WebSocket Hub worker ↓ 协议 crate 目标资源 ``` 适用场景: - 公网 SSH - 云数据库 - 公网 S3/MinIO - Hub 所在网络可直接访问的资源 ### Agent 代理资源 ```text 浏览器 ↓ WebSocket Hub worker ↓ Agent WebSocket 隧道 Agent worker ↓ 协议 crate 内网目标资源 ``` 适用场景: - 家庭内网服务器 - 公司内网数据库 - 没有公网 IP 的 NAS - 不允许开放入站端口的设备 ## 加密 - **传输加密**:TLS 1.3 - **凭据加密**:AES-256-GCM 本地加密存储 - **密钥交换**:ECDHE-X25519 ## 共享 Rust crate Hub 和 Agent 共享所有协议 crate: ```text rex-common 通用类型、错误定义、CLI、supervisor、版本、更新状态 rex-ssh SSH/SFTP 协议实现 rex-mysql MySQL 协议实现 rex-postgresql PostgreSQL 协议实现 rex-redis Redis 协议实现 rex-sqlite SQLite 协议实现 rex-s3 S3/MinIO 协议实现 rex-transfer 文件传输引擎 rex-hub Hub 二进制入口(整合所有 crate + 前端静态资源) rex-agent Agent 二进制入口(整合所有 crate) ``` ## 文件传输架构 ### 设计原则 **文件传输数据不经过浏览器。** 前端只负责创建任务、选择源/目标、展示进度、处理冲突。实际传输由后端完成。 ### 传输流程 ```text 前端选择源文件 + 目标连接 ↓ Hub 创建 transfer task ↓ TransferCoordinator 找到 source connector 和 target connector ↓ source.open_read() ↓ target.open_write() ↓ 流式分块复制 ↓ 校验、rename、写入审计日志 ``` ### 写入策略 ```text 写入临时文件:{target}.rex.part ↓ 完成后校验大小和 SHA256 ↓ 校验通过 → 原子 rename 替换目标文件 校验失败 → 保留或清理临时文件 ``` ## 自更新机制 1. worker 检查更新 2. 下载新版 3. 校验 SHA256 4. 备份当前版本 5. 写 update-state.json 6. 优雅退出 7. supervisor 替换二进制 8. 启动新版 9. 健康轮询(失败 3 次回滚) ## Windows 差异 Windows 不支持 POSIX fork + exec,解决方案: ```text 用户启动 rex-hub.exe ↓ 首次启动时复制自身到 data/rex-supervisor.exe ↓ rex-supervisor.exe 常驻运行(supervisor 角色) ↓ rex-supervisor.exe 启动 data/rex-worker.exe(worker 角色) ↓ 更新时: rex-supervisor.exe 下载新版 → data/rex-worker.new.exe 停止旧 worker.exe → 替换为新 worker.exe → 启动新 worker.exe supervisor 副本不变,不需要在运行时替换自身 ```