系统设计 --- 多节点中按顺序处理消息
系统设计 --- 多节点按顺序处理消息
- 背景
- 解决方案1 --- 手动设置routing key
- 解决方案2 --- Consistent Hashing Exchange
- 方案对比
背景
- 有两个service A 和 B, 各有20个实例同时运行.
- A会接收外部Object发来的消息,经过处理之后发给B.
- A 和 B 之间使用消息队列进行通信,并满足以下条件
- 同一个Object发的消息需要被顺序(串行)处理.
- 反例:假设A处理了Object 1 的两条消息 Msg 1 和 Msg 2,并发给消息队列. 此时假设 service B有两个节点处于空闲状态,则Msg1 和 Msg 2 会被B的两个节点同时处理.

解决方案1 — 手动设置routing key
同一个Object的消息永远被同一个节点处理
- 对 service A和B的20个实例从0到19进行标注 (使用K8s中的stateful set可以实现对每个实例进行编号)
- 根据节点的标注号码构建消息队列的bindign key 和 routing key
- service A的三号节点发送消息的routing key:
Task.3- service B的三号节点的binding key:
Task.3
- 根据Object Id做hash,结果映射到 0 - 19,并根据hash作为routing key发送消息
- 假设A处理了Object 1 的两条消息 Msg 1 和 Msg 2,根据hash结果创建routing key并发给消息队列. 此时假设 service B有多个节点处于空闲状态,Msg 1 和 Msg 2都会被同一个service B的实例顺序处理.

解决方案2 — Consistent Hashing Exchange
- Consistent Hashing Exchange是RabbitMQ中一种特殊的交换器类型,通过一致性哈希算法实现消息的负载均衡,可显著降低节点增减时的数据迁移量
方案对比

