5.6 KiB
5.6 KiB
语音房火箭功能架构
服务边界
room-service是火箭进度、点火、待发射队列和奖励结算 owner。gateway-service只提供 App HTTP 入口和鉴权后的协议转换;GET /api/v1/rooms/{room_id}/rocket会按奖励resource_group_id查询 wallet-service 并嵌入resource_group.items。server/admin只读写room-service内部配置接口,不直连 room 数据库。wallet-service负责资源组发放。activity-service负责区域/全局飘屏和带用户资料的奖励房间 IM。- 腾讯云 IM 负责房间群、区域群和全局群投递。
状态模型
RoomRocketState 保存当前正在累计的火箭和已点火待发射队列。
| 字段 | 说明 |
|---|---|
current_level |
当前正在累计的等级,最高 5 |
current_fuel |
当前等级燃料 |
fuel_threshold |
当前等级阈值 |
status |
charging 或 completed |
rocket_id |
当前正在累计的火箭 ID |
pending_launches |
已点火、等待延迟发射的火箭 |
last_rewards |
最近一次发射奖励结果 |
pending_launches 中每一项锁定:
| 字段 | 说明 |
|---|---|
rocket_id |
本枚火箭幂等 ID |
level |
点火等级 |
fuel_threshold |
点火阈值 |
ignited_at_ms |
点火时间 |
launch_at_ms |
预计发射时间 |
reset_at_ms |
UTC 日重置时间 |
top1_user_id |
点火时贡献第一 |
igniter_user_id |
点火人 |
config_version |
点火配置版本 |
cover_url |
小封面图 |
送礼加燃料
SendGift先调用 wallet 扣费。- 扣费成功后,Room Cell 串行更新热度、礼物榜和火箭。
- 燃料来自 wallet 返回的
heat_value。 - 当前等级未满时,增加
min(本次燃料, 剩余阈值)。 - 超过阈值的燃料直接写入
overflow_fuel,不进入下一等级。 - 当前等级满后:
- 写入
RoomRocketFuelChanged。 - 写入
RoomRocketIgnited。 - 将当前火箭追加到
pending_launches。 - 如果未到 5 级,立刻把当前状态切到下一等级,
current_fuel=0。 - 如果 5 级已满,状态切到
completed,UTC 重置前不再累计新火箭。
- 写入
发射结算
RoomRocketIgnited被 outbox worker 处理后,安排 RocketMQ delayed wakeup。- 本地扫描 worker 也会扫描已加载且仍持有 lease 的 Room Cell,作为兜底。
- 到点后
LaunchRoomRocket命令重新加载 Room Cell。 - 命令必须校验:
rocket_id存在于pending_launches。level匹配。launch_at_ms <= now_ms。now_ms < reset_at_ms。
- 结算时按发射瞬间
OnlineUsers抽在房奖励。 top1和igniter使用点火时锁定的用户,离房后仍发对应奖励。- 发奖完成后移除该
pending_launches项,当前正在累计的火箭不被发射命令推进。
奖励
| 奖励 | 用户来源 |
|---|---|
| 点火人奖励 | pending_launches[].igniter_user_id |
| 贡献第一奖励 | pending_launches[].top1_user_id |
| 在房奖励 | 发射命令执行时 Room Cell OnlineUsers |
发放规则:
| 奖励 | 规则 |
|---|---|
| 在房奖励 | 每个在线用户从 inRoomRewards 按权重随机抽 1 个 |
| 贡献第一奖励 | top1 用户获得 top1Rewards 配置池内全部奖励 |
| 点火人奖励 | 点火用户获得 igniterRewards 配置池内全部奖励 |
同一用户同时是 top1 和点火人时,top1 池和点火人池继续叠加;如果该用户发射瞬间仍在房间,也会再拿 1 个在房随机奖励。
IM
| 事实 | IM | 投递方 |
|---|---|---|
RoomRocketFuelChanged |
room_rocket_fuel_changed |
room-service IM bridge |
RoomRocketIgnited |
room_rocket_ignited |
room-service IM bridge |
RoomRocketIgnited |
room_rocket 区域/全局飘屏 |
activity-service |
RoomRocketLaunched |
room_rocket_launched |
room-service IM bridge |
RoomRocketRewardGranted |
room_rocket_reward_granted 房间奖励 IM |
activity-service |
奖励 IM 由 activity-service 查询用户公开资料后组装,包含头像、昵称、短 ID 和奖励信息。room-service 不反查 user-service。
奖励资源组内容不写入 Room Cell;客户端需要金币数量、有效期、聊天气泡或麦位特效素材时,通过 rocket GET 接口读取展开后的 resource_group。
高频处理
- Room Cell 串行处理送礼命令,所以同房高频送礼不会并发写乱进度。
- 满阈值时只把火箭追加到
pending_launches,不会阻塞下一等级继续累计。 - 房间状态 IM 通过 room outbox 补偿投递,不在送礼主链路同步调用腾讯 IM。
- 奖励 IM 合并为一条消息,
rewards内包含所有中奖人,避免按用户逐条堆积。 - RocketMQ delayed wakeup 只负责唤醒,最终发射仍由 Room Cell 命令校验。
UTC 重置
- 火箭周期按 UTC 自然日。
- 到达
reset_at_ms后,查询或下一次送礼会投影为 1 级新进度。 - 跨过 UTC 日界仍未发射的待发射火箭不结算。
后台配置
配置表:room_rocket_configs
| 字段 | 说明 |
|---|---|
enabled |
是否开启 |
fuel_source |
固定 heat_value |
launch_delay_ms |
点火到发射延迟 |
broadcast_enabled |
是否发飘屏 |
broadcast_scope |
region、global、none |
reward_stack_policy |
历史兼容字段;当前特殊身份奖励按上方规则叠加 |
levels_json |
5 级阈值、物料和奖励池 |
gift_fuel_rules_json |
礼物燃料规则 |
levels_json 字段使用 fuelThreshold、coverUrl、animationUrl、launchAnimationUrl、launchedImageUrl、inRoomRewards、top1Rewards、igniterRewards。