媒体计量部署与运维
本页供自部署平台的维护人员使用。租户充值和计价规则见音视频计费。启用标准时长扣费后,媒体服务必须提供实际接收层计量、签名上报和持久化补报;仅升级业务后端而继续使用原始 LiveKit 镜像,不能完成新计费链路。
部署关系
Client SDK → Metered LiveKit → Persistent report spool
↓ signed report
Backend usage API
↓ transaction
Receipt + Monthly total + App wallet增强镜像基于固定 LiveKit v1.13.1。采集由服务端完成,不依赖浏览器或 App 自报账单。普通通话和 RTC 频道共用一个计量协议。媒体服务的 API Secret 仅保存在后端和媒体服务器,不能下发给客户端。
配置与持久化
| 设置 | 要求 |
|---|---|
| 媒体镜像 | 使用包含 im-standard-duration-v1 适配的增强 LiveKit 镜像 |
IM_BILLING_URL | 媒体容器可访问的 /rtc/v1/usage/<service_id> 完整后端地址 |
IM_BILLING_SECRET | 该媒体服务在平台登记的 API Secret |
IM_BILLING_SPOOL | 容器内持久目录,默认 /var/lib/im-billing |
IM_BILLING_TIMEZONE | 与后端统计时区一致,默认 Asia/Shanghai |
LiveKit keys 与 Webhook | 使用原服务凭据,事件回调保持可达;用量接口不能代替原 Webhook |
将补报目录挂载到主机持久目录或持久卷。三台媒体服务器应分别有自己的可靠目录,不能把多个写进程直接放到同一个无协调的共享目录。增强 LiveKit 已有需要保留的本地计量数据,重建容器时不能把这些文件当作缓存清理。
后端提供用量接收接口;媒体服务器 /im/billing-health 用于检查协议及目标服务 ID。平台已有媒体服务 ID 不应因更新镜像而重新生成,回调和用量地址都应使用该 ID。
构建与覆盖文件示例
在仓库根目录构建增强镜像:
docker build -f deploy/livekit-billing/Dockerfile -t im/livekit-billing:1.13.1 .在现有 LiveKit 服务上增加覆盖文件,示例仅包含新增部分;原 keys、端口、Redis、WebHook 和媒体公网地址继续沿用实际运行配置:
services:
livekit:
image: im/livekit-billing:1.13.1
environment:
IM_BILLING_URL: ${IM_MEDIA_USAGE_URL:?Set the backend usage URL}
IM_BILLING_SECRET: ${LIVEKIT_API_SECRET:?Set the existing service secret}
IM_BILLING_SPOOL: /var/lib/im-billing
IM_BILLING_TIMEZONE: Asia/Shanghai
volumes:
- ./data/livekit-billing:/var/lib/im-billing部署环境的 IM_MEDIA_USAGE_URL 应是完整的后端用量地址,例如 http://backend:8080/rtc/v1/usage/<service_id>;替换为实际可达地址和服务 ID,不要照抄占位值。Secret 必须与平台该服务记录相同。把覆盖文件追加到现有 Compose 文件列表,先检查合并配置,再按升级窗口更新媒体服务。多主机部署需把镜像分发到每台节点。
本地联调也可使用仓库 make livekit-billing-up,先设置 IM_DEV_LIVEKIT_BILLING_URL;它使用开发 Compose 和独立持久卷,不应直接用来覆盖现有生产集群。
升级顺序
- 记录各节点镜像、媒体服务 ID、时区和有效配置,备份数据库、配置及旧镜像;已有计量部署还需保存补报目录。备份实际运行配置,不只备份仓库模板。
- 规划切换日和无活动媒体房间的更新窗口。执行新增迁移
billing/0008_app_wallets及实际待执行迁移,多节点共享数据库只迁移一次。 - 核对
media_billing_from。迁移初始日期按 UTC 写入,而业务统计按配置时区划日;维护人员应在正式启用前按既定切换日核对,避免时区边界错位。已有资金和回执产生后,不应随意前移/后移切换日。 - 升级全部后端和媒体节点,配置签名端点、原事件回调和持久目录。使用现有 Compose 覆盖文件的部署应继续加载全部集群覆盖,不要只启动基础 Compose。
- 验证每台
/readyz、计量协议、服务 ID、签名鉴权及补报目录读写;确认所有节点兼容后启用新规则。业务后端会检查计量协议,旧镜像或服务 ID 不匹配会阻止新媒体资源创建。 - 为隔离验收应用充值,实测已知时长的语音、单路视频、多路接收和跨日场景,对照标准时长及流水;重复上报不应重复扣费。
部署成功、端口返回 200、真实通话扣费验收是不同结论。记录实际完成的验证范围,不用匿名页面检查替代真实充值和媒体测试。
回传与补报
- 媒体连接建立后开始计量,停止后结束;采集实际转发的接收流空间层,每秒归一个档位。
- 每 5 秒将累计快照原子写入持久目录,断开时立即保存;每 5 秒尝试发送。HTTP 失败保留快照,最终快照成功确认后删除。
- 进程重启补报已经保存的秒数,不把停机时间补算成通话。持久快照不能保证恢复尚未落盘的所有采样,异常退出需结合最后成功快照核对。
- 签名是
HMAC-SHA256(API Secret, timestamp + "." + raw JSON),通过X-IM-Usage-Time、X-IM-Usage-Signature传递,允许 5 分钟时钟偏差。保持服务器时钟同步。 - 后端根据媒体服务及房间绑定确定应用,客户端提供的应用标识不能代替绑定。回执、月累计、余额和流水一起提交;同版冲突拒绝,旧版忽略,新版只结算差额。
健康检查与告警
| 检查项 | 如何判断与处理 |
|---|---|
| 后端就绪 | 各实例 /readyz 正常,同时检查依赖和迁移状态 |
| 媒体计量协议 | /im/billing-health 返回 im-standard-duration-v1,用量路径中的 ID 与该服务一致 |
| 补报积压 | 关注文件数量、最旧快照时间和发送错误;通话结束后积压持续增长需排查 |
| 磁盘与权限 | 补报目录可写、容量足够、挂载在重建后仍然存在 |
| 时钟与鉴权 | 401 时检查 Secret、原始 JSON、时间戳与时钟偏差 |
| 房间绑定 | 404 时检查服务 ID 和持久房间定位,不通过伪造应用字段绕过 |
| 账目一致 | 核对余额 = 累计充值 − 累计消耗、月标准时长与已扣分钟、重复与更正流水 |
排障时保留服务 ID、房间/回执标识、版本、请求 ID、时间与 HTTP 状态。日志和工单不应包含 Secret、用户令牌或完整通知凭据。用未知房间做鉴权探测可以检查签名边界,但不能代替真实媒体计量测试。
备份、恢复与回退
数据库保存钱包、流水、媒体回执和月累计,持久补报目录保存尚待确认的媒体快照,运行配置保存签名和路由关系。恢复方案必须同时考虑三者。
重建单台媒体容器时,保留原持久卷、服务身份与 Secret;连通后观察补报是否收敛。恢复旧目录但保留较新的数据库时,旧回执由幂等规则处理;不能因此删除仍未确认的新版快照。备份应保留原权限,并按部署的凭据管理要求保护。
回退业务或媒体镜像前,检查新规则启用后是否已产生应用充值和用量账本,旧版本是否识别它们。不要通过覆盖旧数据库或删除流水来回退。发生持续计量故障时先限制新的媒体准入、保留数据并修复回传,再根据已确认回执核对差额,避免继续提供无法核算的新媒体服务。
