消息队列

月伴飞鱼 2024-09-06 15:51:56
系统设计
支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者!

三类角色:

Broker(服务端):

  • MQ 中最核心的部分,是 MQ 的服务端,核心逻辑几乎全在这里
    • 它为生产者和消费者提供 RPC 接口,负责消息的存储、备份和删除,以及消费关系的维护等。

Producer(生产者):

  • MQ 的客户端之一,调用 Broker 提供的 RPC 接口发送消息。

Consumer(消费者):

  • MQ 的另外一个客户端,调用 Broker 提供的 RPC 接口接收消息,同时完成消费确认。
img

完整的数据流:

img

RPC通信

解决的是 Broker 与 Producer 以及 Consumer 之间的通信问题。

  • 如果不重复造轮子,直接利用成熟的 RPC 框架 Dubbo 或者 Thrift 实现即可
    • 这样不需要考虑服务注册与发现、负载均衡、通信协议、序列化方式等一系列问题了。

也可以基于 Netty 来做底层通信,用 Zookeeper、Euraka 等来做注册中心

  • 然后自定义一套新的通信协议(类似 Kafka)

也可以基于 AMQP 这种标准化的 MQ 协议来做实现(类似 RabbitMQ)。

  • 对比直接用 RPC 框架,这种方案的定制化能力和优化空间更大。

高可用设计

高可用主要涉及两方面:

  • Broker 服务的高可用、存储方案的高可用。

Broker 服务的高可用

只需要保证 Broker 可水平扩展进行集群部署即可

  • 进一步通过服务自动注册与发现、负载均衡、超时重试机制、发送和消费消息时的 ack 机制来保证。

存储方案的高可用有两个思路:

参考 Kafka 的分区 + 多副本模式

  • 但是需要考虑分布式场景下数据复制和一致性方案(类似 Zab、Raft等协议),并实现自动故障转移

还可以用主流的 DB、分布式文件系统、带持久化能力的 KV 系统,它们都有自己的高可用方案。

存储设计

存储的高性能如何保证?

  • 这个问题的决定因素在于存储结构的设计。

目前主流的方案是:

  • 追加写日志文件(数据部分) + 索引文件的方式(很多主流的开源 MQ 都是这种方式)

索引设计上可以考虑稠密索引或者稀疏索引,查找消息可以利用跳转表、二份查找等

  • 还可以通过操作系统的页缓存、零拷贝等技术来提升磁盘文件的读写性能。

如果不追求很高的性能,也可以考虑现成的分布式文件系统、KV 存储或者数据库方案。

消费关系管理

为了支持发布-订阅的广播模式,Broker 需要知道每个主题都有哪些 Consumer 订阅了

  • 基于这个关系进行消息投递。

由于 Broker 是集群部署的,所以消费关系通常维护在公共存储上

  • 可以基于 Zookeeper、Apollo 等配置中心来管理以及进行变更通知。

高性能设计

存储的高性能前面已经谈过了,还可以从其他方面进一步优化性能。

  • 比如 Reactor 网络 IO 模型、业务线程池的设计、生产端的批量发送、Broker 端的异步刷盘、消费端的批量拉取等等。
支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者!