docs(release): record server B consolidation evidence
This commit is contained in:
@@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
## 当前状态
|
## 当前状态
|
||||||
|
|
||||||
- 当前任务:`20260630release` 稳定版封版
|
- 当前任务:`S56 - 全部当前服务收敛到 Server B`
|
||||||
- 本次变更摘要:已核对 `tests/reports/` 下 8.2-8.10 远程测试结果;修复客户充值接口负数扣款、active call hangup 超长/无分隔 ID 参数校验、Fastify 路由参数长度限制,以及既有环境号码库内置角色权限补齐迁移。追加修复业务前缀管理页面 `normalizeBusinessPrefix is not defined`、号码库页面 `emptyNumberLibraryRows is not defined`、客户网关编辑触发 React #137 的前端运行时错误。最新 s53 在菜单展开 Logo 后增加 `SIP` 文字,收起菜单仍展示 `logo2`,并发布 Web-only release。已将稳定代码提交 `9920575bbae7fbef4929843632f94d687ffbe289` 标记为 `20260630release`,并创建稳定分支 `stable/20260630release`;B 当前 release 为 `s53-brand-logo-sip-text-20260630105500`。
|
- 本次变更摘要:确认 B 已同时运行 OpenSIPS、RTPEngine、录音守护进程、Web/API/Worker、MySQL、Redis 与监控;将 Recording Worker 从 B 到 A 的 SSH 拉取改为 B 本机 ready 目录读取,安装本机 finalizer timer,并通过 systemd BindPaths/附加组暴露最小目录权限。当前 release 为 `s56-b-consolidation-20260827T095812Z`,提交为 `309bffc7ffa70a760bce21ae59cb6c457c9c57fe`。
|
||||||
- 总体状态:S30 已完成;本地 KVM 开发环境 V2 闭环原冻结 release 为 `s28-v2-20260621220924`;B 二期冻结基线为 `s42-phase2-business-prefix-20260624140000`,当前 release 为 `s53-brand-logo-sip-text-20260630105500`;稳定版名称 `20260630release`,Git tag `20260630release` 和分支 `stable/20260630release` 均指向稳定代码提交 `9920575bbae7fbef4929843632f94d687ffbe289`。2026-06-30 开机后已恢复 A/B/T 服务:A `opensips`、`rtpengine-daemon`、`rtpengine-recording-daemon`、`lisglosips-redis-auth-proxy`、`lisglosips-node-exporter`、`lisglosips-recording-finalize.timer` active,`lisglosips-redis-hotpath-load.service` Result=success;B `mysql`、`redis-server`、`nginx`、`lisglosips@api`、`lisglosips@cdr-worker`、`lisglosips@recording-worker`、`lisglosips@config-publisher`、`heplify-server`、`lisglosips-prometheus`、`grafana-server` active,preflight ok,API ready ok,封版 MySQL 备份 `/data/backups/mysql/20260630T061723Z`,Redis 备份 `/data/backups/redis/20260630T061723Z`;T `opensips`、`rtpengine-daemon`、`rtpengine-recording-daemon`、`lisglosips-s28-uas`、`apache2`、`mariadb/mysql` active。B preflight、远程 smoke、8.2/8.7/8.8 定向复测均通过;业务前缀、号码库、客户网关编辑与前缀选择 Web-only 修复后,s53 当前首页引用 Web JS `index-CrjpbrU-.js`、CSS `index-CrJGI5_R.css`,并包含 `/favicon.ico`、`/brand/logo1.png`、`/brand/logo2.png`;封版远程 smoke `REMOTE_SMOKE_20260630T061636Z.md` 通过;完整按钮级远程浏览器巡检 `REMOTE_WEB_UI_SMOKE_20260629T104040Z.md` 通过,覆盖 15 个核心菜单及安全主操作,客户网关管理编辑报告包含 `business-prefix-checkbox-toggle-ok: false->true->false`;封版报告为 `docs/20260630_RELEASE_BASELINE_REPORT.md`;当前仍未导入真实 80 万手机号段;阿里云迁移前需按 S30 Runbook 重新演练
|
- 总体状态:S30 已完成;本地 KVM 开发环境 V2 闭环原冻结 release 为 `s28-v2-20260621220924`;B 二期冻结基线为 `s42-phase2-business-prefix-20260624140000`,当前 release 为 `s53-brand-logo-sip-text-20260630105500`;稳定版名称 `20260630release`,Git tag `20260630release` 和分支 `stable/20260630release` 均指向稳定代码提交 `9920575bbae7fbef4929843632f94d687ffbe289`。2026-06-30 开机后已恢复 A/B/T 服务:A `opensips`、`rtpengine-daemon`、`rtpengine-recording-daemon`、`lisglosips-redis-auth-proxy`、`lisglosips-node-exporter`、`lisglosips-recording-finalize.timer` active,`lisglosips-redis-hotpath-load.service` Result=success;B `mysql`、`redis-server`、`nginx`、`lisglosips@api`、`lisglosips@cdr-worker`、`lisglosips@recording-worker`、`lisglosips@config-publisher`、`heplify-server`、`lisglosips-prometheus`、`grafana-server` active,preflight ok,API ready ok,封版 MySQL 备份 `/data/backups/mysql/20260630T061723Z`,Redis 备份 `/data/backups/redis/20260630T061723Z`;T `opensips`、`rtpengine-daemon`、`rtpengine-recording-daemon`、`lisglosips-s28-uas`、`apache2`、`mariadb/mysql` active。B preflight、远程 smoke、8.2/8.7/8.8 定向复测均通过;业务前缀、号码库、客户网关编辑与前缀选择 Web-only 修复后,s53 当前首页引用 Web JS `index-CrjpbrU-.js`、CSS `index-CrJGI5_R.css`,并包含 `/favicon.ico`、`/brand/logo1.png`、`/brand/logo2.png`;封版远程 smoke `REMOTE_SMOKE_20260630T061636Z.md` 通过;完整按钮级远程浏览器巡检 `REMOTE_WEB_UI_SMOKE_20260629T104040Z.md` 通过,覆盖 15 个核心菜单及安全主操作,客户网关管理编辑报告包含 `business-prefix-checkbox-toggle-ok: false->true->false`;封版报告为 `docs/20260630_RELEASE_BASELINE_REPORT.md`;当前仍未导入真实 80 万手机号段;阿里云迁移前需按 S30 Runbook 重新演练
|
||||||
- 最后更新:2026-06-30 14:20 +08:00
|
- 最后更新:2026-08-27 18:16 +08:00
|
||||||
- 当前阻塞:本轮 8.2/8.7/8.8、业务前缀页面、号码库页面、客户网关编辑运行时错误、测试门禁修复、B SSH/HTTPS 来源限制移除无阻塞。遗留问题:未提交 Git;未改 A OpenSIPS/Lua/RTPEngine 或 T 配置;8.9 轻量 API burst p95 超过 10 秒需结合服务端日志和测试方式继续定位;SIP CPS 探针中 BYE 被 `403 Rate Limited` 属 A 侧限流策略问题,修复前需说明影响、备份 A 配置并安排维护窗口;8.10 备份、隔离恢复、真实回滚、OpenSIPS 配置恢复受权限或维护窗口阻塞;真实 80 万手机号段尚未导入;OpenSIPS dialog 残留根因仍待单独分析。
|
- 当前阻塞:无发布阻塞。尚未发起新的真实收费/外呼来生成生产录音,因此真实 `incoming -> ready -> /data/recordings -> recordings READY -> 鉴权播放` 仍需在下一次受控呼叫时补验;本次未修改 TLS、数据库结构或 A/T 配置。
|
||||||
- 当前环境:A/B/T 为本地 KVM 开发服务器,通过 Tailscale 联调;开发完成后再迁移阿里云
|
- 当前环境:A/B/T 为本地 KVM 开发服务器,通过 Tailscale 联调;开发完成后再迁移阿里云
|
||||||
- 私密访问资料:`.codex-private/SERVER_ACCESS.md`,只在实际连接时读取,禁止回显
|
- 私密访问资料:`.codex-private/SERVER_ACCESS.md`,只在实际连接时读取,禁止回显
|
||||||
|
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
| 代号 | 地址 | 用户 | 用途 |
|
| 代号 | 地址 | 用户 | 用途 |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| A | `100.90.90.90` | `hector` | OpenSIPS、RTPEngine、录音内存盘、HEP、Exporter |
|
| A | `100.90.90.90` | `hector` | 历史节点/回滚参考;S56 起不参与当前生产服务或录音传输 |
|
||||||
| B | `100.90.90.91` | `hector` | API、Worker、Redis、MySQL、录音、HOMER、Prometheus/Grafana |
|
| B | `100.90.90.91` | `hector` | OpenSIPS、RTPEngine、录音、Nginx、API、Worker、Redis、MySQL、HOMER、Prometheus/Grafana |
|
||||||
| T | `100.93.185.30` | `hector` | 已安装 OpenSIPS,模拟客户 SIP 注册与呼叫 |
|
| T | `100.93.185.30` | `hector` | 已安装 OpenSIPS,模拟客户 SIP 注册与呼叫 |
|
||||||
|
|
||||||
## 任务状态表
|
## 任务状态表
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
# Server B 单机服务收敛发布报告
|
||||||
|
|
||||||
|
发布日期:2026-08-27
|
||||||
|
生产提交:`309bffc7ffa70a760bce21ae59cb6c457c9c57fe`
|
||||||
|
生产 release:`/opt/lisglosips/releases/s56-b-consolidation-20260827T095812Z`
|
||||||
|
|
||||||
|
## 发布结果
|
||||||
|
|
||||||
|
当前服务已全部留在 Server B。Recording Worker 使用 `RECORDING_SOURCE_MODE=local` 读取
|
||||||
|
`/dev/shm/voip_rec/ready`,不再连接 A,也不再产生录音 SSH 子进程。A 未执行任何配置修改或停机操作;B 上旧 SSH 文件暂留作短期回滚材料,但不被当前 env 和进程引用。
|
||||||
|
|
||||||
|
## 代码与配置
|
||||||
|
|
||||||
|
- 新增 `LocalRecordingClient`,保留大小校验、SHA-256、临时文件、原子改名、数据库 upsert 和成功后删除源文件的原语义。
|
||||||
|
- 新增 B finalizer service/timer,每 5 秒将稳定 WAV/MP3 从 `incoming` 推进到 `ready`。
|
||||||
|
- Recording Worker 使用 `SupplementaryGroups=rtpengine` 与 `BindPaths=/dev/shm/voip_rec/ready`;持久化目录仍为 `/data/recordings`。
|
||||||
|
- finalizer 的 `fuser` 调用已按 B 的 psmisc 实现改为兼容语法。
|
||||||
|
- 未修改 TLS、数据库 schema、SIP/RTP 监听地址、防火墙、A 或 T。
|
||||||
|
|
||||||
|
## 备份与回滚点
|
||||||
|
|
||||||
|
- 最终 MySQL 备份:`/data/backups/mysql/20260827T095812Z`
|
||||||
|
- 最终 Redis 备份:`/data/backups/redis/20260827T095813Z`
|
||||||
|
- 最终配置备份:`/var/backups/lisglosips-s56/20260827T095812Z`
|
||||||
|
- 上一可用 release:`/opt/lisglosips/releases/s56-b-consolidation-20260827T093227Z`
|
||||||
|
|
||||||
|
发布脚本会在失败时恢复 previous release、Recording Worker env 与 systemd drop-in,并重启旧 Worker。回滚不删除已持久化录音。
|
||||||
|
|
||||||
|
## 验证证据
|
||||||
|
|
||||||
|
| 检查 | 结果 |
|
||||||
|
| --- | --- |
|
||||||
|
| 定向 Vitest | `apps/worker-recording/src/transfer.spec.ts` 5/5 通过 |
|
||||||
|
| TypeScript / ESLint | Recording Worker 构建及三个变更文件 lint 通过 |
|
||||||
|
| 发布 preflight | MySQL、Redis、Nginx、API、全部 Worker、HOMER、Prometheus、Grafana 通过 |
|
||||||
|
| 核心服务 | OpenSIPS、RTPEngine、Recording Daemon、Web/API/DB/Worker 全部 active |
|
||||||
|
| API 与首页 | readiness HTTP 200;首页 HTTP 200 |
|
||||||
|
| Worker 模式 | 启动日志为 `sourceMode=local`、`sourceDir=/dev/shm/voip_rec/ready` |
|
||||||
|
| 稳定性 | 连续运行 1100 秒,`NRestarts=0`,超过旧 SSH 约 135 秒失败周期 |
|
||||||
|
| SSH 依赖 | Worker 子进程为空;只存在系统管理用 sshd/运维会话 |
|
||||||
|
| 目录可见性 | 主机与 Worker 命名空间 ready 目录设备号/inode 同为 `27:7` |
|
||||||
|
| finalizer 隔离测试 | 19 字节测试文件成功形成 `.ready`,权限 `0640 rtpengine:rtpengine`,测试目录已清理 |
|
||||||
|
| 生效文件一致性 | systemd drop-in 与 finalizer 的仓库/服务器 SHA-256 分别一致 |
|
||||||
|
|
||||||
|
## 剩余验收
|
||||||
|
|
||||||
|
本次未主动发起真实外呼,避免生成计费、CDR 和业务录音。下一次受控真实呼叫需要核对:
|
||||||
|
|
||||||
|
1. Recording Daemon 在 B 生成 `incoming` 文件。
|
||||||
|
2. finalizer 生成 `.ready`。
|
||||||
|
3. Worker 写入 `/data/recordings` 并将数据库状态更新为 `READY`。
|
||||||
|
4. 有 `recordings.play` 权限的账号可播放,直接访问 Nginx internal 路径仍返回 404。
|
||||||
Reference in New Issue
Block a user