好的实现不会依赖用户反复刷新碰运气,而会让每个阶段有明确输入、输出、超时和终态。 Pub/Sub 通常提供瞬时广播而非持久历史。消费者需要频道 epoch 与递增序列检测缺口,发现 gap 后读取权威快照而不是猜丢失内容。
实时后端必须在身份、顺序、背压和断线恢复之间给出一致语义。每条消息都要知道属于哪个会话版本、能否重放以及慢消费者达到上限后如何退出。
先定义系统契约
先把下面几项写成可评审的规则,而不是散落在回调和界面判断里。规则越清楚,后续扩容、兼容和排错越少靠猜。
- 订阅切换先建立新订阅并确认起始序列,再释放旧订阅;事件携带 entityVersion,接收端按版本应用且允许重复。
- 为状态写出唯一所有者、版本号和终态;任何回调只能修改自己创建的版本。
- 上线参数必须有保守默认值、服务端上限和灰度开关,不能把浏览器传来的数字直接当作资源预算。
“实时 Pub/Sub 扇出:订阅变更、乱序与重复投递怎么收敛”的交付标准是正常路径可用、异常路径收敛、资源有界,并且用户能理解系统为何采用当前状态。 这样得到的不是演示代码,而是能解释、能降级、能回滚的生产能力。
哪些情况会破坏契约
不要把异常路径理解成弹一次提示。它还包括在途工作如何停、对端如何获知、残留数据如何处置,以及下一次操作是否会继承旧状态。
- 先退订旧节点再订阅新节点会形成静默窗口;把 Redis 到达顺序当成全局业务顺序则在分片或重连后覆盖新状态。
- 刷新或网络切换同时触发两条恢复路径,重复副作用被误当成两次真实用户操作。
- 指标标签直接包含用户或任务标识,既制造高基数成本,也让诊断数据泄露不必要的身份信息。
如何逐条验证契约
用已知输入和可控故障建立金样本,然后把线上低基数指标与测试结果对齐。只有指标能提前识别同类退化,验证才真正延伸到生产。
- 在持续发布时迁移连接、重启订阅节点并人为重复与交换事件,最终快照、在线人数和会话状态必须一致。
- 用乱序、重复和延迟消息驱动状态机,确认旧版本被丢弃且显式停止不会被自动恢复覆盖。
- 分别覆盖直连、中转、弱网、后台标签页和移动端,报告不能只给平均值或一次成功截图。
最终交付标准应当是:正常路径足够快,异常路径能够收敛,用户意图不会被自动恢复覆盖,运维人员也能从有限而安全的证据定位问题。