# Server B 单机服务收敛实施方案 日期:2026-08-27 范围:停止 B 到 A 的录音 SSH 依赖,当前生产服务全部留在 B。 ## 结论 B 已运行 OpenSIPS、RTPEngine、RTPEngine Recording Daemon、Nginx、API、MySQL、Redis、CDR Worker、Recording Worker 与 Config Publisher,CPU、内存和磁盘空间满足当前负载。现有单机化缺口只有录音 Worker 仍配置为 SSH 访问 A;A 不可达会导致该 Worker 周期性失败重启。 ## 改动 1. Recording Worker 新增 `local` 源模式,递归扫描 B 的 `.ready` 文件,保留大小校验、SHA-256、原子落盘、数据库 upsert 与成功后删除源文件语义。 2. B 启用录音 finalizer timer,将 Recording Daemon 生成的稳定 WAV/MP3 从 `incoming` 原子推进到 `ready`。 3. Worker systemd 增加 `rtpengine` 附加组,只开放 ready 目录和持久化目录权限。 4. B 生产环境改为 `RECORDING_SOURCE_MODE=local`;旧 SSH 文件不立即删除,只作短期回滚材料。 5. 不修改 TLS、数据库结构、SIP/RTP 监听地址和防火墙,不迁移历史录音,不停止不可达的 A。 ## 验收 - 定向单元测试和 TypeScript 构建通过。 - finalizer timer、Recording Worker、OpenSIPS、RTPEngine、API、Nginx、MySQL、Redis 均 active。 - Recording Worker 启动日志显示 `sourceMode=local`,稳定运行超过原失败周期,且无 SSH 子进程。 - API readiness、首页和发布 preflight 通过。 - 真实新通话录音应在下一次受控呼叫时补做:`incoming -> ready -> /data/recordings -> recordings READY -> 鉴权播放`。 ## 回滚 发布前备份 Worker env、systemd drop-in、finalizer 脚本和 unit。异常时停用 finalizer timer,恢复备份配置并将 release symlink 切回上一版本;不删除 B 已落盘录音。