Rocketmq

tim-qtp...大约 10 分钟Rocketmq框架

1.为什么要使用消息队列呢?

消息队列(Message Queue, MQ)是一种非常重要的中间件技术,广泛应用于分布式系统中,以提高系统的可用性、解耦能力和异步通信效率。

①、解耦

实现解耦 其他的动作一定程度上和我没有关系消息丢进队列里,下游服务自己去调用

像任务审批,就用了 RocketMQ 来做解耦。

②、异步

系统可以将那些耗时的任务放在消息队列中异步处理,从而快速响应用户的请求。比如说,用户下单后,系统可以先返回一个下单成功的消息,然后将订单信息放入消息队列中,后台系统再去处理订单信息(扣减库存,增加积分,发送消息),链路一长,响应时间就变长了,引入消息队列,除了更新订单状态,其它的都可以异步去做,这样一来就来,就能降低响应时间。

消息队列异步
消息队列异步

③、削峰

削峰填谷是一种常见的技术手段,用于应对系统高并发请求的瞬时流量高峰,通过消息队列,可以将瞬时的高峰流量转化为持续的低流量,从而保护系统不会因为瞬时的高流量而崩溃。

**缺点:

宕机后整个业务就会产生影响

引入MQ后,数据链路就会变得很复杂

还得考虑喜消息不丢失问题,顺序问题,重复消费问题

2.为什么要选择 RocketMQ?

RocketMQ 是一个 队列模型 的消息中间件,具有高性能、高可靠、高实时、分布式 的特点。它是一个采用 Java 语言开发的分布式的消息系统,由阿里巴巴团队开发,在 2016 年底贡献给 Apache,成为了 Apache 的一个顶级项目。 在阿里内部,RocketMQ 很好地服务了集团大大小小上千个应用,在每年的双十一当天,更有不可思议的万亿级消息通过 RocketMQ 流转。

四大消息队列对比
四大消息队列对比

平时做的系统主要面向 C 端用户,有一定的并发量,对性能也有比较高的要求,所以选择了低延迟、吞吐量比较高,可用性比较好的 RocketMQ。

3.RocketMQ 有什么优缺点?

RocketMQ 优点:

  • 单机吞吐量:十万级
  • 可用性:非常高,分布式架构
  • 消息可靠性:经过参数优化配置,消息可以做到 0 丢失
  • 功能支持:MQ 功能较为完善,还是分布式的,扩展性好
  • 支持 10 亿级别的消息堆积,不会因为堆积导致性能下降
  • 源码是 Java,方便结合公司自己的业务二次开发
  • 天生为金融互联网领域而生,对于可靠性要求很高的场景,尤其是电商里面的订单扣款,以及业务削峰,在大量交易涌入时,后端可能无法及时处理的情况
  • RoketMQ在稳定性上可能更值得信赖,这些业务场景在阿里双 11 已经经历了多次考验,如果你的业务有上述并发场景,建议可以选择RocketMQ

RocketMQ 缺点:

  • 支持的客户端语言不多,目前是 Java 及 c++,其中 c++不成熟
  • 没有在 MQ 核心中去实现JMS等接口,有些系统要迁移需要修改大量代码

4.消息队列有哪些消息模型?

消息队列有两种模型:队列模型发布/订阅模型

队列模型
队列模型
发布-订阅模型
发布-订阅模型

5.那 RocketMQ 的消息模型呢?

RocketMQ 中的消息模型就是按照 主题模型 所实现的。

其实对于主题模型的实现来说每个消息中间件的底层设计都是不一样的,就比如 Kafka 中的 分区RocketMQ 中的 队列RabbitMQ 中的 Exchange 。我们可以理解为 主题模型/发布订阅模型 就是一个标准,那些中间件只不过照着这个标准去实现而已。

假设我们有一个电商系统,系统中有以下功能:

  1. 下单:用户下单后生成订单。
  2. 支付:用户支付订单。
  3. 发货:商家发货后更新物流信息。

1. Topic(主题)

  • Topic 是消息的归类,比如我们可以定义两个 Topic:
    • OrderTopic:用于处理订单相关的消息。
    • LogisticsTopic:用于处理物流相关的消息。

2. Message(消息)

  • 消息是传输的信息,比如:
    • 用户下单后,生成一条消息,内容是订单信息(如订单号、商品信息等),这条消息的 Topic 是 OrderTopic
    • 用户支付后,生成一条消息,内容是支付信息(如订单号、支付金额等),这条消息的 Topic 也是 OrderTopic
    • 商家发货后,生成一条消息,内容是物流信息(如订单号、快递单号等),这条消息的 Topic 是 LogisticsTopic

3. Tag(标签)

  • Tag 是消息的子分类,用于更细粒度地标识消息。比如:
    • OrderTopic 下,我们可以定义两个 Tag:
      • CreateOrder:表示订单创建的消息。
      • PayOrder:表示订单支付的消息。
    • LogisticsTopic 下,我们可以定义一个 Tag:
      • ShipOrder:表示订单发货的消息。
  • 这样,生产者发送消息时,可以指定 Topic 和 Tag:
    • 下单时发送的消息:Topic=OrderTopic, Tag=CreateOrder
    • 支付时发送的消息:Topic=OrderTopic, Tag=PayOrder
    • 发货时发送的消息:Topic=LogisticsTopic, Tag=ShipOrder

4. Group(消费组)

  • 消费组是一组消费者的集合,它们共同消费一个 Topic 下的消息。比如:
    • 我们可以定义一个消费组 OrderGroup,用于处理订单相关的消息。
    • 另一个消费组 LogisticsGroup,用于处理物流相关的消息。
  • 消费组的特点
    • 同一个消费组内的消费者是竞争关系,一条消息只会被组内的一个消费者消费。
    • 不同消费组之间是独立的,一条消息可以被多个消费组分别消费。

5. Message Queue(消息队列)

  • 一个 Topic 下可以设置多个消息队列,比如:
    • OrderTopic 下有 4 个消息队列(Queue1、Queue2、Queue3、Queue4)。
    • LogisticsTopic 下有 2 个消息队列(Queue1、Queue2)。
  • 消费者的消费方式
    • 如果消费组 OrderGroup 有 2 个消费者(Consumer1 和 Consumer2),那么它们会分别从 OrderTopic 的 4 个队列中消费消息:
      • Consumer1 消费 Queue1 和 Queue2。
      • Consumer2 消费 Queue3 和 Queue4。

6. Offset(消费位置)

  • Offset 是消息的消费进度,比如:
    • OrderTopic 的 Queue1 中,有 100 条消息。
    • 消费组 OrderGroup 已经消费了前 50 条消息,那么它的 Offset 就是 50。
    • 消费组 LogisticsGroup 还没有消费过 Queue1 的消息,那么它的 Offset 就是 0。
  • Offset 的作用
    • 确保每条消息只会被消费组消费一次。
    • 如果消费者宕机,重启后可以从上次的 Offset 继续消费。

6.消息的消费模式?

消息消费模式有两种:Clustering(集群消费)和Broadcasting(广播消费)。

默认情况下就是集群消费,这种模式下一个消费者组共同消费一个主题的多个队列,一个队列只会被一个消费者消费,如果某个消费者挂掉,分组内其它消费者会接替挂掉的消费者继续消费。

而广播消费消息会发给消费者组中的每一个消费者进行消费。

7.RoctetMQ 基本架构?

一共有四个部分组成:NameServer,Broker,Producer 生产者,Consumer 消费者,它们对应了:发现、发、存、收,为了保证高可用,一般每一部分都是集群部署的。

类比一下我们生活的邮政系统——

邮政系统要正常运行,离不开下面这四个角色, 一是发信者,二 是收信者, 三是负责暂存传输的邮局, 四是负责协调各个地方邮局的管理机构。对应到 RocketMQ 中,这四个角色就是 Producer、 Consumer、 Broker 、NameServer。

RocketMQ类比邮政体系
RocketMQ类比邮政体系
NameServer

NameServer 是一个无状态的服务器,角色类似于 Kafka 使用的 Zookeeper,但比 Zookeeper 更轻量。

特点:

  • 每个 NameServer 结点之间是相互独立,彼此没有任何信息交互。
  • Nameserver 被设计成几乎是无状态的,通过部署多个结点来标识自己是一个伪集群,Producer 在发送消息前从 NameServer 中获取 Topic 的路由信息也就是发往哪个 Broker,Consumer 也会定时从 NameServer 获取 Topic 的路由信息,Broker 在启动时会向 NameServer 注册,并定时进行心跳连接,且定时同步维护的 Topic 到 NameServer。

功能主要有两个:

  • 1、和 Broker 结点保持长连接。
  • 2、维护 Topic 的路由信息。
Broker

消息存储和中转角色,负责存储和转发消息。

  • Broker 内部维护着一个个 Consumer Queue,用来存储消息的索引,真正存储消息的地方是 CommitLog(日志文件)。

  • 单个 Broker 与所有的 Nameserver 保持着长连接和心跳,并会定时将 Topic 信息同步到 NameServer,和 NameServer 的通信底层是通过 Netty 实现的

Producer

消息生产者,业务端负责发送消息,由用户自行实现和分布式部署。

  • Producer由用户进行分布式部署,消息由Producer通过多种负载均衡模式发送到Broker集群,发送低延时,支持快速失败。

RocketMQ 提供了三种方式发送消息:同步、异步和单向

  • 同步发送:同步发送指消息发送方发出数据后会在收到接收方发回响应之后才发下一个数据包。一般用于重要通知消息,例如重要通知邮件、营销短信。
  • 异步发送:异步发送指发送方发出完数据后,不等接收方发回响应,接着发送下个数据包,一般用于可能链路耗时较长而对响应时间敏感的业务场景,例如用户视频上传后通知启动转码服务。转码完成后,转码服务会通过回调函数通知你。
  • 单向发送:单向发送是指只负责发送消息而不等待服务器回应且没有回调函数触发,适用于某些耗时非常短但对可靠性要求并不高的场景,例如日志收集
Consumer

消息消费者,负责消费消息,一般是后台系统负责异步消费。

  • Consumer也由用户部署,支持 PUSH 和 PULL 两种消费模式,支持集群消费广播消费,提供实时的消息订阅机制
  • Pull:拉取型消费者(Pull Consumer)主动从消息服务器拉取信息,只要批量拉取到消息,用户应用就会启动消费过程,所以 Pull 称为主动消费型。
  • Push:推送型消费者(Push Consumer)封装了消息的拉取、消费进度和其他的内部维护工作,将消息到达时执行的回调接口留给用户应用程序来实现。所以 Push 称为被动消费类型,但其实从实现上看还是从消息服务器中拉取消息,不同于 Pull 的是 Push 首先要注册消费监听器,当监听器处触发后才开始消费消息。