关于消息队列设计的思考

引入消息队列的目的

消息队列,顾名思义就是在两个系统之间传递消息的一种软件应用;引入消息队列的场景必定存在两个系统,需要相互同步一些信息,可以是数据、事件等等。但是消息同步的机制有很多,为什么需要引入消息队列,而不是通过其他方法;换言之,消息队列有什么独特的优势可以满足一些设计目的。

  • 解耦。考虑会有两个系统,系统A需要处理核心业务,系统B依赖A的消息,处理一些下游的业务。A不应该受到B的业务流程和处理能力限制,却又应该把核心业务的一些相关信息传递出去,此时引入消息队列就能解决。
  • 套用成熟的消费关系。考虑有多个核心系统,多个下游系统,核心系统和下游系统的发送接收关系是多对多的模型,引入消息队列可以引入一套投放和接收规则语义,保证双方按这套语义定义投递规则就能成功地投递和接收消息。
  • 降低处理能力的要求。一旦消息存下来了可以异步处理,下游业务就可以按照自己的处理能力灵活实现各种流控策略,就能起到削峰填谷的作用

设计范式

根据系统所需同步内容的不同,可能会有不一样的设计范式,可以参考设计整个系统。

数据同步

在该场景下,消息队列主要作为数据传递的管道,设计时应该多考虑系统上每个模块的处理能力,性能可能是最主要的风险

举例:流计算模型

参考:《Manning.Algorithms.and.Data.Structures.for.Massive.Datasets.MEAP.Edition.Version.3.2021》

事件同步

在该场景下,消息队列主要作为事件通知的方式,设计时应该多考虑各种异常情况,各种场景下的消息丢失或重复等异常可能是主要的风险

举例:Actor模型

参考:Actor模型 - 简书

设计范式是应该在一开始就定下来的东西,系统要知道的到底是什么,是数据最终是怎么样的?还是一个实体发生了什么事情?假如用事件同步的方式来进行数据同步,则接收方需要知道发送方的业务逻辑,才能保证再发生了同样的事件后,数据能够一致,造成系统间的业务耦合;假如用数据同步的方式来进行事件同步,那么接收方需要从数据的变动中进行分析,才能知道到底发生了什么事情,而这种分析在业务上是很难梳理完全的。

一些具体问题的解决思路

再次将目光看回到消息队列本身,有什么消息队列本身的要点是我们需要去注意和关注的。可以参考:消息队列设计精要 - 美团技术团队。这篇博客已经足够高屋建瓴,不需要再狗尾续貂,但是补充一些我对具体问题的思考

顺序性带来的挑战

如果要100%满足顺序性,则必须保证生产者到队列到消费者都是单点单线程,举个例子,选用kafka需要保证感知到partition级别,而且消费端不能用任何并发的手段增强处理的能力。这样的设计很容易识别各种风险,而且为了解决这种风险,我们会陷入对链路上各个环节的无休止分析,最终可能在可靠性上要做非常多复杂的工作。

此时一般会有如下考虑

  • 在保证最终一致性的场景下,允许消息丢失,但是需要一种全同步的手段;在识别到消息丢失之后,触发系统间的全同步,然后由新的消息开始消费;如果不能识别消息丢失,那就定时全同步
  • 假如消费端没有及时处理完毕触发ack,可能会有重复发送,此时要么保证消费幂等,要么需要一个唯一ID保证消息不会被重复处理,唯一ID可以是“时间戳+版本号”的形式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值