这类问题看似集中在一个 API 或参数上,真正决定可用性的却是状态归属、资源上限和失败后的恢复方式。 WebSocket 本身绑定一个进程,但业务会话不必绑定。连接目录可以保存 device 到 instance 的短租约,权威任务状态放持久层,实例只持有可重建缓存。
实时后端必须在身份、顺序、背压和断线恢复之间给出一致语义。每条消息都要知道属于哪个会话版本、能否重放以及慢消费者达到上限后如何退出。
先把实现决策说清楚
实现之前先列出不可违反的不变量,再为性能与体验留出调节参数。参数可以灰度,身份、权限和终态规则不能在运行时随意漂移。
- 入口粘性只作为优化;跨实例命令经有确认的路由层送达,实例故障后新连接根据 session cursor 从权威状态恢复。
- 先定义正常、降级、取消和失败四类终态,再让界面、存储与指标消费同一状态。
- 上线参数必须有保守默认值、服务端上限和灰度开关,不能把浏览器传来的数字直接当作资源预算。
“信令服务该无状态还是粘性会话:先看状态到底放在哪”的交付标准是正常路径可用、异常路径收敛、资源有界,并且用户能理解系统为何采用当前状态。 这样得到的不是演示代码,而是能解释、能降级、能回滚的生产能力。
最容易漏掉的失败路径
失败路径需要与成功路径共享同一套状态模型。只弹一个错误提示却不释放资源、不传播终态,下一次恢复就会继承脏状态。
- 把内存 Map 当唯一会话数据库会在节点丢失时失去拒绝、取消和幂等记录;强依赖 cookie 粘性又让区域切换无法恢复。
- 旧响应在新任务建立后迟到,如果没有版本隔离,会把健康状态覆盖成失败或再次启动已取消工作。
- 降级路径从未压测,主路径故障时所有流量同时进入更慢、更昂贵的后备方案。
上线前怎样验证
验证需要先写预期状态轨迹,再执行故障注入。每个阶段同时核对用户可见结果、两端协议状态、持久记录和资源计数,才能证明闭环成立。
- 随机杀掉持有双方连接、仅持一方连接和空闲连接的节点,确认恢复语义相同且没有幽灵在线状态。
- 在操作中途断网、切换网络并恢复,核对两端状态、持久化记录和资源计数最终一致。
- 发布前记录成功率、p50/p95/p99 延迟、错误分类和资源高水位,并为回退条件设定明确阈值。
完成并不等于主路径跑通,而是每个终态都能对账、每个自动动作都受用户意图约束、每个成本都有明确上限。