AllStar2.0/开发周期.md

1324 lines
30 KiB
Markdown
Raw Normal View History

2026-04-27 14:42:20 +08:00
下面这份是**基于你提供的“智能锁新实时系统方案”整理的模块开发周期、技术栈、难点和注意事项**。我按**第一阶段独立部署 `session-orchestrator`** 的方案来拆分。
2026-04-27 14:46:21 +08:00
> 预估前提:
2026-04-27 14:42:20 +08:00
> - `starcloud`、`starlock`、`app-starlock`、现有设备端已有基础能力。
> - 新项目重点是实时控制面、BifroMQ、WebRTC/TURN/ZLMediaKit、事件链路、AI 旁路。
> - 团队配置按:后端 2 人、APP 1 人、设备端 1 人、运维 1 人、测试 1 人估算。
---
# 一、整体开发阶段建议
## 阶段划分
| 阶段 | 目标 | 周期预估 |
|---|---|---|
| 阶段 0方案细化与协议设计 | 确定 topic、状态机、API、媒体选路策略 | 1 - 2 周 |
| 阶段 1实时控制面 MVP | 完成 `session-orchestrator``device-bootstrap`、BifroMQ 基础接入 | 3 - 5 周 |
| 阶段 2WebRTC / TURN / ZLM 媒体链路 | 完成 P2P、TURN、ZLMediaKit 基础切换 | 4 - 8 周 |
| 阶段 3APP 与设备端联调 | APP、WiFi 锁、后台完整跑通呼叫、接听、挂断、切路 | 4 - 6 周 |
| 阶段 4事件、日志、可观测、弱网优化 | 完成事件消费、质量上报、链路追踪、告警 | 2 - 4 周 |
| 阶段 5AI 旁路接入 | 接入 `ai-gateway``xiaozhi_server` | 2 - 4 周 |
| 阶段 6灰度上线与稳定性优化 | 压测、弱网测试、灰度、回滚方案 | 2 - 4 周 |
## 总周期预估
| 范围 | 周期 |
|---|---|
| 最小可用版本 MVP | 8 - 12 周 |
| 可灰度上线版本 | 12 - 16 周 |
| 含 AI、完整动态选路、完整可观测版本 | 16 - 24 周 |
---
# 二、模块开发周期、技术栈、难点与注意事项
## 1. `starlock` 租户应用层改造
### 模块定位
`starlock` 是 APP 的统一业务入口,负责:
- APP 登录鉴权
- 家庭 / 门锁归属判断
- 调用 `starcloud` 共享能力
- 调用 `session-orchestrator` 创建实时会话
- 下发短期会话权限
- 处理事件回调和业务通知
### 开发周期
**2 - 4 周**
如果现有 PHP 代码结构清晰,只做 API 编排,约 2 周。
如果需要整理权限、设备归属、租户模型,可能 4 周以上。
### 技术栈
| 类型 | 技术 |
|---|---|
| 后端语言 | PHP |
| 框架 | Laravel / ThinkPHP / Yii / 原有框架,按现状 |
| API | RESTful API |
| 认证 | JWT / Session / OAuth2 内部 token |
| 数据库 | MySQL / PostgreSQL |
| 缓存 | Redis |
| 内部调用 | HTTP / gRPC可先 HTTP |
| 日志 | Monolog / ELK / Loki |
### 主要开发内容
- 新增“创建视频会话”接口
- 调用 `session-orchestrator` 创建 `sessionId`
- 根据用户、家庭、门锁关系做权限校验
- 返回 APP 所需短期 token、MQTT topic、媒体策略
- 处理 `MQTT event worker` 回调
- 处理 AI 会话状态回调
- 保留对 `starcloud` 的共享能力调用
### 难点
1. **权限边界**
- APP 用户是否有权访问某把锁
- 家庭成员、租户、渠道、套餐规则是否影响通话权限
2. **短期会话权限设计**
- APP 不能直接拿长期业务 token 去访问实时系统
- 需要生成短期、单会话、可过期的 token
3. **业务状态与实时状态解耦**
2026-04-27 14:46:21 +08:00
- `starlock` 不应该维护完整通话状态机
2026-04-27 14:42:20 +08:00
- 它只关心会话结果、事件回调和业务通知
4. **兼容旧链路**
- 旧 UDP 控制、旧 `scd/scrd/rpcd` 可能仍有设备在用
- 需要新旧能力并存一段时间
### 注意事项
- `starlock` 不要直接搬运 WebRTC signaling。
- APP 不应直接访问 `session-orchestrator` 的内部管理接口。
- 所有会话创建都必须经过设备归属和家庭权限校验。
- 短期 token 要绑定:
- `userId`
- `deviceId`
- `sessionId`
- 过期时间
- 权限范围
- 事件回调要做幂等处理,防止重复消费。
- 所有敏感操作要写审计日志。
---
## 2. `starcloud` 共享业务能力对接
### 模块定位
`starcloud` 是共享业务平台,主要提供:
- 用户 / 权限策略
- 家庭 / 设备关系
- 套餐 / 计费
- 审计 / 风控
- 通用业务规则
### 开发周期
**1 - 3 周**
如果现有 API 完备,只需对接和字段适配,约 1 周。
如果需要补充共享能力 API则需要 2 - 3 周。
### 技术栈
| 类型 | 技术 |
|---|---|
| 后端 | 现有 `starcloud` 技术栈 |
| API | REST / RPC |
| 鉴权 | 内部服务 token / AK-SK / OAuth2 |
| 数据库 | 现有数据库 |
| 缓存 | Redis |
| 审计 | 日志服务 / 审计表 |
### 主要开发内容
- 提供设备归属查询能力
- 提供用户权限策略查询能力
- 提供风控和审计接口
-`starlock` 提供标准化业务 API
### 难点
- 多租户和跨项目能力边界容易混乱
- 共享模型与 `starlock` 定制逻辑可能重复
- 权限策略需要兼容现有用户体系
### 注意事项
- `starcloud` 不直接参与实时会话状态机。
- `starcloud` 只输出通用业务判断,不关心 WebRTC、BifroMQ、ZLM 细节。
- 通用能力和租户定制能力要分清。
- 不要把实时系统的 topic、signaling、media route 等细节侵入 `starcloud`
---
## 3. `session-orchestrator` 会话编排服务
### 模块定位
这是新实时系统的核心模块,负责:
- 创建会话
- 管理会话状态机
- 下发控制指令
- 处理 ACK / 超时 / 重试
- 编排 signaling topic
- 控制媒体选路
- 记录会话状态和质量数据
### 开发周期
**4 - 8 周**
MVP 版本 4 周左右。
完整支持状态机、切路、追踪、重试、幂等,建议预留 6 - 8 周。
### 技术栈
推荐技术栈:
| 类型 | 推荐 |
|---|---|
| 后端语言 | Go / Java / Node.js |
| 推荐优先级 | Go 或 Java 更适合长连接、并发和状态机 |
| Web 框架 | Go Fiber / GinJava Spring Boot |
| 内部 API | REST / gRPC |
| MQTT Client | Eclipse Paho / gmqtt / HiveMQ Client |
| 状态缓存 | Redis |
| 持久化 | MySQL / PostgreSQL |
2026-04-27 14:46:21 +08:00
| 消息序列 | Redis Stream / Kafka可顺续引入 |
2026-04-27 14:42:20 +08:00
| 日志追踪 | OpenTelemetry |
| 指标 | Prometheus |
| 配置 | YAML / ENV / Nacos / Consul |
### 主要开发内容
- `CreateSession`
- `InviteDevice`
- `AcceptSession`
- `RejectSession`
- `StartSignaling`
- `ReportQuality`
- `SwitchRoute`
- `Hangup`
- `Timeout`
- `Terminate`
- 会话状态机
- MQTT topic 分配
- 短期 token 校验
- ACK / seq / retry
- 会话日志落库
- 媒体策略下发
### 推荐状态机
```text
pending
-> ringing
-> accepted
-> connecting
-> connected
-> degraded
-> switching_route
-> recovered
-> ended
异常结束:
-> rejected
-> timeout
-> failed
```
### 难点
1. **状态一致性**
- APP、设备、云端三方状态容易不一致。
- 必须通过状态机和事件序列统一收敛。
2. **ACK 与超时控制**
- `invite` 发出后,设备可能离线、延迟、重复 ACK。
- 所有控制指令要有 `seq``ack``timeout`
3. **动态选路**
- 什么时候从 P2P 切 TURN
- 什么时候从 TURN 切 ZLM
- 切路过程中如何不中断或少中断?
4. **幂等性**
- APP 重试创建会话
- 设备重复上报 accept
- MQTT 重复投递
- 都必须能安全处理
5. **分布式扩容**
- 多个 `session-orchestrator` 实例时,会话归属、锁、状态更新要处理好。
### 注意事项
- 会话 ID 必须全局唯一。
- 所有指令都要带:
- `sessionId`
- `eventId`
- `seq`
- `timestamp`
- `expireAt`
- `from`
- `to`
- 状态变更必须有合法状态迁移校验。
- 会话状态建议短期放 Redis终态落 MySQL。
- 不建议在 MQTT retained message 中保存敏感 signaling。
- `session-orchestrator` 不搬运大媒体流。
- `session-orchestrator` 应只管控制面,不直接承载视频数据。
---
## 4. `device-bootstrap` 设备接入服务
### 模块定位
设备首次或周期性接入时,通过该服务获取:
- 设备认证
- MQTT 连接参数
- 短期 MQTT 凭证
- 设备 topic 权限
- 设备能力配置
- 固件能力声明
### 开发周期
**2 - 4 周**
如果设备认证机制已存在2 周左右。
如果需要重新设计设备证书、密钥、签名3 - 4 周。
### 技术栈
| 类型 | 技术 |
|---|---|
| 后端语言 | Go / Java / PHP 均可 |
| API | HTTPS |
| 鉴权 | 设备证书 / 设备密钥 / HMAC 签名 |
| 存储 | MySQL |
| 缓存 | Redis |
| MQTT 权限 | BifroMQ Auth Provider / 自定义鉴权 |
### 主要开发内容
- 设备身份校验
- 颁发 MQTT username/password/token
- 生成设备 topic ACL
- 返回 BifroMQ 连接地址
- 返回心跳周期
- 返回设备配置
- 支持设备能力声明:
- 是否支持 WebRTC
- 是否支持 ZLM
- 是否支持 AI 音频旁路
- 是否支持 BLE 透传
### 难点
- 设备端时间不准导致签名过期判断失败
- 设备密钥泄露风险
- MQTT ACL 粒度设计
- 新旧设备兼容
### 注意事项
- 不要给设备长期固定 MQTT 密码。
- MQTT 凭证建议短期有效,可刷新。
- topic 权限必须最小化。
- 设备只能发布和订阅自己的 topic。
- 设备 capability 要版本化,方便后续灰度。
---
## 5. Apache BifroMQ 模块
### 模块定位
BifroMQ 承担:
- 设备在线状态
- 发现
- MQTT signaling
- 事件总线
- APP 与设备信令通道
### 开发周期
**2 - 4 周**
部署和基础联调 1 - 2 周。
完整 ACL、认证、监控、压测建议 3 - 4 周。
### 技术栈
| 类型 | 技术 |
|---|---|
| MQTT Broker | Apache BifroMQ |
| 协议 | MQTT 3.1.1 / MQTT 5 |
| APP 连接 | MQTT over WSS |
| 设备连接 | MQTT over TLS |
| 鉴权 | 自定义 Auth Provider |
| 监控 | Prometheus / Grafana |
| 日志 | Loki / ELK |
### Topic 设计建议
```text
tenant/{tenantId}/device/{deviceId}/status
tenant/{tenantId}/device/{deviceId}/event
tenant/{tenantId}/session/{sessionId}/signal/app
tenant/{tenantId}/session/{sessionId}/signal/device
tenant/{tenantId}/session/{sessionId}/control
tenant/{tenantId}/session/{sessionId}/quality
```
### 难点
1. **topic 权限控制**
- APP 只能访问自己本次会话相关 topic。
- 设备只能访问自己所属 topic。
2. **在线状态判断**
- MQTT connected 不等于设备业务可用。
- 需要结合心跳、lastWill、设备能力状态。
3. **QoS 选择**
- signaling 可用 QoS 1。
- 质量上报可用 QoS 0。
- 控制指令建议 QoS 1 + 应用层 ACK。
4. **消息顺序**
- MQTT 不能替代完整状态机。
- 状态一致性仍应由 `session-orchestrator` 控制。
### 注意事项
- 不要通过 MQTT 传大视频流。
- 不要把长期敏感 token 放在 topic 或 payload 里。
- topic 命名要预留租户维度。
- MQTT payload 要版本化。
- retained message 谨慎使用,尤其是 signaling 类消息。
- LWT 遗嘱消息要设计好,用于设备离线通知。
---
## 6. APP 端 `app-starlock` 改造
### 模块定位
APP 需要支持:
- 调用 `starlock` 创建会话
- 连接 BifroMQ
- 订阅 session topic
- WebRTC offer/answer/candidate
- 媒体链路质量上报
- 动态切路响应
- 弱网提示
- AI 辅助入口
### 开发周期
**4 - 8 周**
如果现有 Flutter 已有实时对讲能力,约 4 - 5 周。
如果 WebRTC 从零接入,建议 6 - 8 周。
### 技术栈
| 类型 | 技术 |
|---|---|
| APP 框架 | Flutter |
| WebRTC | flutter_webrtc |
| MQTT | mqtt_client / 其他 Flutter MQTT SDK |
| 网络 | Dio |
| 状态管理 | Riverpod / Bloc / Provider |
| 本地存储 | shared_preferences / hive |
| 日志 | Sentry / 自建日志上报 |
| 推送 | FCM / APNs / 厂商推送 |
### 主要开发内容
- 会话创建 API
- MQTT over WSS 连接
- WebRTC PeerConnection
- ICE candidate 处理
- offer/answer 交换
- TURN 配置
- ZLM 播放 / 推流能力接入
- route switch 指令处理
- 通话 UI 状态机
- 通话质量上报
- 异常提示和重连
### 难点
1. **Flutter WebRTC 稳定性**
- Android 和 iOS 行为不同。
- 后台、锁屏、权限、音频路由复杂。
2. **弱网处理**
- 网络切换 WiFi/4G
- ICE reconnect
- MQTT 断线重连
- 媒体重连
3. **状态同步**
- APP UI 状态必须跟云端会话状态保持一致。
- 不能只靠本地 WebRTC 状态判断。
4. **音频权限和回声消除**
- 双向语音容易出现回声、啸叫、音量问题。
### 注意事项
- APP 不要保存长期 MQTT 密钥。
- APP 进入后台时要处理 MQTT 和 WebRTC 生命周期。
- 会话失败要区分:
- 设备离线
- 权限不足
- signaling 超时
- ICE 失败
- ZLM 失败
- 所有通话状态变化都要上报。
- iOS 需要特别注意后台音视频权限和推送唤醒策略。
- Android 需要注意不同厂商后台保活限制。
---
## 7. WiFi 网关锁 / 设备端改造
### 模块定位
WiFi 锁作为网关设备,需要支持:
- HTTPS bootstrap
- MQTT/TLS 连接
- 在线状态上报
- 会话 invite/accept/reject/hangup
- WebRTC 采集、编码、推流
- TURN / ZLM / relay 切换
- AI 音频旁路
- BLE 锁透传
### 开发周期
**6 - 12 周**
如果设备端已有音视频 SDK 和 WebRTC 能力6 - 8 周。
如果从零接入 WebRTC尤其是嵌入式平台可能 12 周以上。
### 技术栈
| 类型 | 技术 |
|---|---|
| 语言 | C / C++ |
| MQTT | Eclipse Paho Embedded / mosquitto client / 自研 |
| TLS | mbedTLS / OpenSSL |
| WebRTC | libwebrtc / Pion 设备适配 / vendor SDK |
| 编码 | H.264 / H.265 / AAC / Opus |
| 媒体 | GStreamer / FFmpeg / 设备厂商 SDK |
| 存储 | Flash / 本地配置 |
| 日志 | 本地环形日志 + 云端上报 |
### 主要开发内容
- bootstrap 接入
- MQTT topic 订阅和发布
- 设备能力声明
- 接收 `invite`
- 发送 `ringing/accept/reject`
- signaling 处理
- WebRTC 建链
- TURN 支持
- ZLM 推流或 WebRTC 接入
- 质量指标采集
- route switch 响应
- 会话结束清理
2026-04-27 14:46:21 +08:00
- AI旁路转发
2026-04-27 14:42:20 +08:00
### 难点
1. **设备性能限制**
- CPU、内存、编码能力有限。
- WebRTC 对资源要求高。
2. **嵌入式 WebRTC 集成难**
- ICE、DTLS、SRTP、NAT 穿透复杂。
- SDK 移植成本高。
3. **音视频编码兼容**
- APP、ZLM、WebRTC 对 codec 支持要统一。
- H.264 profile、packetization mode 要注意。
4. **切路过程中资源释放**
- P2P 切 ZLM 时要释放旧连接。
- 防止摄像头、麦克风、编码器被占用。
5. **断网恢复**
- 设备重连后要恢复 MQTT 状态。
- 旧会话要能被云端清理。
### 注意事项
- 设备端必须实现控制指令 ACK。
- 设备端所有消息要带 `sessionId``seq`
- 设备端不能信任任意 MQTT 消息,必须校验 token 或签名。
- 摄像头、麦克风只能被一个会话独占,除非明确支持多路。
- 本地日志非常重要,否则现场问题很难定位。
- 如果设备端 WebRTC 难度过高,可以第一阶段优先走 ZLMediaKit 或厂商 SDK再逐步补 P2P。
---
## 8. WebRTC / TURN 媒体链路模块
### 模块定位
负责 APP 与设备之间的实时音视频链路:
- 优先 P2P
- P2P 不通走 TURN
- 弱网时可切 ZLM
- 最终兜底走中心转发
### 开发周期
**4 - 8 周**
APP、设备、服务端三方联调复杂建议至少预留 1 个月。
### 技术栈
| 类型 | 技术 |
|---|---|
| WebRTC | libwebrtc / flutter_webrtc |
| STUN/TURN | coturn |
| 加密 | DTLS-SRTP |
| NAT 穿透 | ICE |
| 编码 | H.264 / Opus |
| 质量监控 | getStats / 自定义质量上报 |
### 主要开发内容
- ICE server 配置
- offer/answer
- candidate 收集和交换
- TURN credential
- 质量上报
- P2P / TURN 判定
- ICE restart
- 通话异常恢复
### 难点
- NAT 类型复杂
- 对称 NAT 下 P2P 失败率高
- TURN 成本高,带宽压力大
- ICE 状态和业务状态不完全一致
- 移动网络切换容易断流
### 注意事项
- TURN 账号必须短期有效。
- TURN 带宽成本要评估。
- 不要把 TURN 当成无限免费兜底。
- WebRTC 质量指标要持续上报:
- RTT
- packet loss
- jitter
- bitrate
- candidate type
- frame drop
- 首版可以先实现“失败后重建到 ZLM”不要一开始追求无感切换。
---
## 9. `ZLMediaKit` 中心转发模块
### 模块定位
ZLMediaKit 用于:
- 弱网优先转发
- P2P/TURN 失败后的媒体兜底
- 标准化流媒体接入
- 后续录像、截图、事件视频处理
### 开发周期
**3 - 6 周**
基础部署和推拉流 1 - 2 周。
与 APP、设备、鉴权、会话状态打通约 3 - 6 周。
### 技术栈
| 类型 | 技术 |
|---|---|
| 流媒体服务 | ZLMediaKit |
| 协议 | WebRTC / RTSP / RTMP / HLS / HTTP-FLV |
| 编码 | H.264 / AAC / Opus |
| 鉴权 | ZLM hook + 业务鉴权 |
| 部署 | Docker / systemd |
| 负载均衡 | Nginx / SLB |
| 监控 | Prometheus exporter / 日志采集 |
### 主要开发内容
- ZLM 部署
- 推流地址生成
- 播放地址生成
- Hook 鉴权
- 流开始 / 结束事件回调
-`session-orchestrator` 对接
- APP 播放适配
- 设备推流适配
- 异常断流重试
### 难点
1. **协议选择**
- 设备推什么协议?
- APP 拉什么协议?
- 是否都走 WebRTC
2. **延迟控制**
- HLS 延迟高,不适合实时对讲。
- WebRTC / RTMP / HTTP-FLV 要按实际需求选。
3. **双向语音**
- 只看视频容易,双向对讲更复杂。
- 要确认 ZLM 在当前方案中如何承载上行音频。
4. **鉴权和防盗链**
- 推流 / 播放 URL 必须短期有效。
- 不能裸露固定流地址。
### 注意事项
- 弱网优先 ZLM 是合理的,但要明确“实时对讲”的延迟指标。
- 首版建议只做一套主协议,避免 RTMP、RTSP、WebRTC、FLV 全部都上。
- ZLM 的 hook 回调要和 `session-orchestrator` 状态机打通。
- 流 ID 要绑定 `sessionId`
- 推流和播放权限必须过期。
- 要有自动清理僵尸流机制。
---
## 10. `media-relay` 中心转发兜底模块
### 模块定位
`media-relay` 是最终兜底。
但你文档里已经明确:**优先采用 ZLMediaKit 落地,通常不需要长期维护自研 relay。**
### 开发周期
| 方案 | 周期 |
|---|---|
| 不自研,直接用 ZLMediaKit 承担 | 0 - 1 周设计适配 |
| 轻量封装 ZLM relay API | 2 - 3 周 |
| 自研完整音视频 relay | 8 - 16 周,不建议第一阶段做 |
### 技术栈
如果不自研:
| 类型 | 技术 |
|---|---|
| Relay 实现 | ZLMediaKit |
| 控制层 | `session-orchestrator` |
| 鉴权 | ZLM hook |
| 监控 | Prometheus / 日志 |
如果自研:
| 类型 | 技术 |
|---|---|
| 语言 | C++ / Go |
| 媒体协议 | RTP / SRTP / WebRTC |
| 编码处理 | FFmpeg / GStreamer |
| NAT | ICE / TURN |
| 难度 | 高 |
### 难点
- 自研媒体转发成本极高
- 音视频同步、抖动缓冲、拥塞控制都复杂
- 稳定性和性能验证成本高
### 注意事项
- 第一阶段不建议自研 `media-relay`
- 先让 `media-relay` 成为逻辑模块,由 ZLMediaKit 实现。
- 后续只有在 ZLM 无法满足业务需求时再考虑自研。
---
## 11. `MQTT event worker` / 原 `event_listener` 演进
### 模块定位
负责消费设备事件和实时事件:
- 门锁事件
- 设备上下线
- 通话事件
- 媒体事件
- AI 事件
- 图片 / 视频后处理
- 回调 `starlock`
### 开发周期
**2 - 4 周**
### 技术栈
| 类型 | 技术 |
|---|---|
| 后端语言 | Go / Java / PHP Worker / Node.js |
| 消息来源 | BifroMQ MQTT |
| 队列 | Redis Stream / Kafka / RabbitMQ可选 |
| 存储 | MySQL / Redis |
| 回调 | HTTP |
| 重试 | 延迟队列 / 定时任务 |
### 主要开发内容
- MQTT 事件订阅
- 事件解析
- 事件幂等
- 回调 `starlock`
- 失败重试
- 死信队列
- 事件日志落库
- 媒体后处理触发
### 难点
- MQTT 事件可能重复
- 设备事件顺序可能乱
- 回调失败后要重试
- 事件消费不能阻塞主实时链路
### 注意事项
- 每个事件必须有唯一 `eventId`
- 回调 `starlock` 要支持幂等。
- 不要在 worker 中做耗时媒体处理,应该异步化。
- 事件处理失败要可追踪、可重放。
- 事件 schema 要版本化。
---
## 12. `realtime-store` 实时状态与日志缓存
### 模块定位
用于保存:
2026-04-27 14:46:21 +08:00
- 会话临时状态
2026-04-27 14:42:20 +08:00
- 会话质量指标
- signaling 摘要
- route 切换记录
- 调试日志
- 会话终态
### 开发周期
**1 - 3 周**
### 技术栈
| 类型 | 技术 |
|---|---|
| 热状态 | Redis |
| 持久化 | MySQL / PostgreSQL |
| 日志 | Loki / Elasticsearch |
| 指标 | Prometheus |
| 链路追踪 | OpenTelemetry |
### 数据建议
#### Redis
```text
session:{sessionId}:state
session:{sessionId}:participants
session:{sessionId}:route
session:{sessionId}:quality
device:{deviceId}:online
device:{deviceId}:capability
```
#### MySQL
- `realtime_session`
- `realtime_session_event`
- `realtime_quality_report`
- `realtime_route_switch`
- `device_online_log`
### 难点
- 热状态和持久化状态一致性
- 会话结束后的资源清理
- 日志量较大
- 敏感数据脱敏
### 注意事项
- Redis key 必须设置 TTL。
- signaling 内容不建议完整长期保存,只保存必要摘要。
- 质量数据可以采样,不要无限写入。
- 终态必须落库,便于审计和问题排查。
- 需要按 `sessionId` 能快速查完整链路。
---
## 13. `ai-gateway` 与 `xiaozhi_server` AI 旁路模块
### 模块定位
AI 不进入主通话状态机,而是旁路能力:
- 设备音频旁路到 AI
- APP AI 辅助模式
- AI 结果回传 `starlock`
- 不影响主对讲链路
### 开发周期
**2 - 4 周**
如果只是接入已有 `xiaozhi_server`2 周左右。
如果需要实时音频流、唤醒词、语音识别、语音合成4 周以上。
### 技术栈
| 类型 | 技术 |
|---|---|
| 网关语言 | Go / Python / Node.js |
| AI 服务 | xiaozhi_server |
| 音频协议 | WebSocket / RTP / HTTP streaming |
| 编码 | PCM / Opus / AAC |
| 鉴权 | 短期 token |
| 回调 | HTTP 到 `starlock` |
### 主要开发内容
- AI 会话创建
- 音频旁路接入
- AI 服务转发
- AI 结果回调
- 会话结束清理
- AI 异常不影响主通话
### 难点
- 音频格式转换
- 实时性要求
- AI 服务异常隔离
- 主通话和 AI 旁路资源竞争
- 隐私和权限控制
### 注意事项
- AI 不要阻塞主对讲链路。
- AI 失败不能导致视频通话失败。
- AI 音频采集要经过用户授权。
- AI 数据要做隐私合规处理。
- AI 事件要独立状态机,不能混入主通话状态机。
---
## 14. 运维部署与基础设施模块
### 模块定位
负责部署:
- BifroMQ
- `session-orchestrator`
- `device-bootstrap`
- coturn
- ZLMediaKit
- MQTT event worker
- Redis
- MySQL
- 日志、监控、告警
### 开发周期
**3 - 6 周**
MVP Docker Compose 1 - 2 周。
生产高可用部署 4 - 6 周。
### 技术栈
| 类型 | 技术 |
|---|---|
| 容器 | Docker |
| 编排 | Docker Compose / Kubernetes |
| 网关 | Nginx / Ingress |
| 证书 | Let's Encrypt / 企业证书 |
| 监控 | Prometheus + Grafana |
| 日志 | Loki / ELK |
| 追踪 | Jaeger / Tempo |
| CI/CD | GitLab CI / GitHub Actions |
| 配置 | ENV / Secret / ConfigMap |
### 难点
- BifroMQ 集群部署
- TURN 公网 IP 和端口规划
- ZLM 带宽和并发压力
- 日志量控制
- 多服务之间配置复杂
- 灰度和回滚
### 注意事项
- coturn 必须部署在公网可达节点。
- TURN UDP 端口范围要提前开放。
- ZLM 和 TURN 带宽要按峰值计算。
- 所有服务要有健康检查。
- 生产环境密钥不能写在配置文件仓库中。
- 日志要设置保留周期,避免磁盘被打满。
- 要准备一键回滚方案。
---
# 三、模块优先级建议
## P0第一阶段必须完成
| 模块 | 说明 |
|---|---|
| `starlock` 会话入口 | APP 创建会话必须依赖 |
| `session-orchestrator` | 新实时系统核心 |
| `device-bootstrap` | 设备拿 MQTT 凭证 |
| BifroMQ | 发现、在线、信令 |
| APP MQTT + WebRTC 基础 | APP 端通话能力 |
| 设备 MQTT + WebRTC/ZLM 基础 | 设备端通话能力 |
| coturn | P2P 失败补位 |
| ZLMediaKit 基础转发 | 弱网和失败兜底 |
| `MQTT event worker` | 事件回调 |
| 基础监控日志 | 联调和上线必需 |
## P1灰度上线前建议完成
| 模块 | 说明 |
|---|---|
| 完整 ACK / 超时 / 重试 | 提升状态一致性 |
| 质量指标上报 | 支撑动态选路 |
| 动态 route switch | P2P / TURN / ZLM 切换 |
| 会话追踪 | 定位问题 |
| ZLM hook 鉴权 | 防止盗流 |
| TURN 临时凭证 | 安全必需 |
| 异常恢复 | 网络切换、断线重连 |
| 压测和弱网测试 | 上线前必需 |
## P2后续增强
| 模块 | 说明 |
|---|---|
| AI 旁路 | 不影响主链路,可后置 |
| 自研 media-relay | 如 ZLM 不满足再考虑 |
| 高级网络评分模型 | 根据数据逐步优化 |
| 多区域接入 | 用户量上来后再做 |
| 完整录像 / 云存储 | 按业务套餐推进 |
---
# 四、关键技术难点总结
## 1. 控制面和媒体面解耦
难点不是画架构,而是实现时防止耦合:
- `session-orchestrator` 不能直接处理视频流
- BifroMQ 不能传大媒体
- `starlock` 不能变成实时状态机
- ZLM 不能承载业务权限判断
正确边界是:
```text
starlock业务权限
session-orchestrator会话状态机
BifroMQ信令和事件通道
WebRTC/ZLM/TURN媒体链路
event worker异步事件处理
```
---
## 2. 会话状态一致性
这是整个方案最大的工程难点之一。
必须解决:
- APP 发起了但设备没收到
- 设备 accept 了但 APP 已取消
- MQTT 重连导致重复消息
- WebRTC 连上但云端状态还是 connecting
- P2P 断了但双方状态不一致
- 会话结束后资源没释放
建议所有状态变化都通过 `session-orchestrator` 收敛。
---
## 3. 媒体动态选路
动态选路不要一开始做得太复杂。
建议第一版策略:
```text
默认尝试 P2P
-> ICE 失败或超时,切 TURN
-> TURN 仍失败,切 ZLMediaKit
-> ZLMediaKit 失败,提示通话失败或走旧 relay
```
弱网优化版再做:
```text
根据 RTT、丢包、jitter、candidate type、带宽评估是否提前切 ZLM
```
---
## 4. 设备端复杂度
设备端是高风险点。
尤其要确认:
- 芯片性能是否支撑 WebRTC
- 是否有硬编 H.264
- 是否支持 Opus / AAC
- 是否支持 TLS
- 是否支持 MQTT 长连接
- 摄像头和麦克风资源是否可同时给 WebRTC 和 AI
- 固件 OTA 是否方便灰度
如果设备 WebRTC 成本过高,建议:
```text
第一阶段:设备 -> ZLMediaKitAPP -> ZLMediaKit
第二阶段:中高端设备支持 WebRTC P2P
```
---
## 5. BifroMQ 权限和 topic 设计
MQTT topic 一旦上线后修改成本较高。
建议提前确定:
- topic 命名规范
- tenant 隔离
- device 隔离
- session 隔离
- QoS 策略
- retained 使用策略
- LWT 设备离线策略
- ACL 权限模型
---
# 五、上线前必须注意的点
## 1. 安全
必须做好:
- MQTT TLS
- MQTT ACL
- 短期 token
- TURN 临时账号
- ZLM 播放 / 推流鉴权
- 设备密钥不能明文泄露
- 日志脱敏
---
## 2. 可观测性
至少要能按 `sessionId` 查到:
- 谁发起
- 哪个设备
- 哪个 APP
- 设备是否在线
- invite 是否送达
- accept 是否收到
- offer/answer 是否完成
- ICE 是否成功
- 使用了 P2P / TURN / ZLM / relay 哪条链路
- 失败原因是什么
- 最终状态是什么
否则后期排查会非常痛苦。
---
## 3. 弱网和异常测试
必须覆盖:
- APP 4G / WiFi 切换
- 设备断网重连
- MQTT 断线重连
- TURN 不可用
- ZLM 不可用
- BifroMQ 重启
- `session-orchestrator` 重启
- APP 杀进程
- 设备重复上线
- 双端同时挂断
- 多个 APP 同时呼叫同一把锁
---
## 4. 资源和成本
需要重点评估:
| 资源 | 风险 |
|---|---|
| TURN | 带宽成本高 |
| ZLMediaKit | 中心转发带宽和 CPU 压力 |
| BifroMQ | 长连接数量 |
| Redis | 会话状态和 TTL 清理 |
| 日志系统 | signaling 和质量上报可能量很大 |
| MySQL | 会话事件写入频率 |
---
# 六、推荐的第一阶段 MVP 范围
第一阶段不要一次性做太满,建议 MVP 范围如下:
## 必做
- `starlock` 创建会话 API
- `session-orchestrator` 独立服务
- BifroMQ 接入
- APP MQTT over WSS
- 设备 MQTT/TLS
- 基础 invite / accept / reject / hangup
- WebRTC P2P 基础链路
- coturn 兜底
- ZLMediaKit 兜底链路
- 基础质量上报
- 基础会话日志
- 事件 worker 回调 `starlock`
## 暂缓
- AI 深度集成
- 自研 media-relay
- 复杂无感切路
- 多区域部署
- 高级网络评分模型
- 全量录像和云存储
- 复杂套餐计费联动
---
# 七、建议的里程碑排期
## 第 1 - 2 周:协议和架构落地
- 确定 API 文档
2026-04-27 14:46:21 +08:00
- 确定 MQTT topic
2026-04-27 14:42:20 +08:00
- 确定状态机
- 确定 route 策略
- 确定设备 capability schema
- 搭建 BifroMQ、coturn、ZLM 测试环境
## 第 3 - 6 周:控制面 MVP
- `session-orchestrator`
- `device-bootstrap`
- `starlock` 会话入口
- APP MQTT
- 设备 MQTT
- invite / accept / hangup 跑通
## 第 7 - 10 周:媒体链路 MVP
- WebRTC P2P
- TURN
- ZLM 推拉流
- APP 与设备完整通话
- 失败后切换到 ZLM
## 第 11 - 14 周:稳定性和可观测
- ACK / retry / timeout 完善
- 质量上报
- 会话追踪
- 事件 worker
- 日志和监控
- 弱网测试
## 第 15 - 16 周:灰度上线
- 小范围设备灰度
- 问题收集
- 性能压测
- 回滚方案
- 运维文档
---
# 八、最终建议
这个架构方向是合理的,关键是第一阶段要控制范围。
我建议优先落地这条主链路:
```text
APP
-> starlock
-> session-orchestrator
-> BifroMQ signaling
-> 设备
-> WebRTC P2P / TURN
-> 失败后 ZLMediaKit
```
同时把 AI、自研 relay、高级动态选路放到第二阶段。
最需要重点投入的模块是:
1. `session-orchestrator` 状态机
2. BifroMQ topic / ACL / token 设计
3. APP 与设备端 WebRTC 联调
4. ZLMediaKit 弱网兜底
5. 会话日志与问题追踪
如果这 5 个点做好,后续 AI、录像、套餐、计费、多区域扩容都可以逐步叠加。