一、 RocketMQ特点
- 具有灵活的可扩展性。 RocketMQ 天然支持集群,其核心四大组件(NameServer、Broker、 Producer、Consumer)的每一个都可以在没有单点故障的情况下进行水平扩展。
- 具有海量消息堆积能力。RocketMQ 采用零拷贝原理实现了超大量消息的堆积能力。
- 支持顺序消息。RocketMQ 可以保证消息消费者按照消息发送的顺序对消息进行消费。消息分为全局有序消息和局部有序消息,一般推荐使用局部有序消息,即生产者通过某一类消息顺序发生至同一队列中来实现。
- 支持多种消息过滤方式。消息过滤分为在服务器端过滤和在消费端过滤。在服务器端过滤时可以按照消息消费者的要求进行过滤,优点是减少了不必要的消息传输,缺点是增加了消息服务器的负担,实现相对复杂。消费端过滤则完全由具体应用自定义实 现,这种方式更加灵活,缺点是很多无用的消息会被传输给消息消费者
- 支持事务消息。RocketMQ 除支持普通消息、顺序消息之外,还支持事务消息,这个特性对于分布式事务来说提供了另一种解决思路
- 支持回溯消息。回溯消费是指对于消费者已经消费成功的消息,由于业务需求需要重新消费。RocketMQ 支持按照实践回溯消费,时间维度精确到毫秒,可以向前回溯, 可以向后回溯
二、基本概念
2.1 生产者
生产者:生产者负责生产消息,生产者向消息服务器发送由业务应用程序系统生成的消息。RocketMQ提供了三种方式发送消息:同步、异步和单向。
- 同步发送:同步发送指消息发送方发出数据后,会在收到接收方发回的相应之后才发送下一个数据包。一般适用于重要通知消息场景,如重要通知邮件、营销短信等。
- 异步发送:异步发送指发送方发出数据后,不等接收方发回响应,就接着发送发一个数据包。一般适用于可用于可能链路耗时较长而对响应时间敏感的业务场景,例如用户视频上传后通知启动转码服务等。
- 单向发送:单向发送指只负责发送消息而不等待服务器回应且没回调函数触发。一般适用于某些耗时非常短且对可靠性要求不高的场景,例如日志收集等。
2.2 生产者组
生产者是一类生产者的集合,这类生产者通常发送一类消息并且发送逻辑一致,所以将这些生产者分组在一起。从部署结构上看,生产者通过生产者组的名字来标识自己是一个群体。
2.3 消费者
消费者负责消费消息,它从消息服务器拉去消息并将其输入用户应用程序中。从用户应用的角度来看,消费者由两种类型:拉取型消费者和推送型消费者。
拉取型消费者(Pull Consumer)
拉取型消费者主动从消息服务器拉取消息,只要批量拉取到消息,用户应用就会启动消费过程,所以Pull被称为主动消费类型。
推送型消费者(Push Consumer)
推送型消费者封装了消息的拉取、消费进度和其他内部维护工作,将消息到达时执行的回调接口留给用户应用程序来实现。所以 Push 被称为被动消费类型。但从实现上看,还是从消息服务器拉取消息的。不同于 Pull 的是,Push首先要注册消费监听器,当监听器被触发后才开始消费消息。
2.4 消费者组
消费者组是一类消费者的集合,这类消费者通常消费同一类消息,并且消费逻辑一致,所以将这些消费者分组在一起,消费者组与生产者组类似,都是将相同角色的消费者分组在一起井命名的。
分组是一个很精妙的概念设计。RocketMQ 正是通过这种分组机制,实现了天然的消息负载均衡。在消费消息时,通过消费者组实现了将消息分发到多个消费者服务器实例,比如某个主题有 9 条消息,其中一个消费者组有 3 个实例 (3 个进程或 3台机器),那么每个实例将均摊 3 条消息,这也意味着我们可以很方便地通过增加机器来实现水平扩展。
2.5 消费服务器
消息服务器(Broker)是消息存储中心,其主要作用是接受来自生产者的消息并进行存储,消费者从这里拉取消息。它还存储与消息相关的元数据,包括用户组、消费进度偏移量、队列信息等。
Broker 有 Master 和 Slave 两种类型,其中 Master 既可以写,又可以读;Slave 不可以写,只可以读。从物理结构上看,Broker 的集群部署有单 Master、多 Master、多 Master 多 Slave(同步双写)、多 Master 多 Slave (异步复制)等多种方式。
单 Master
采用这种方式,一旦 Broker 重启或者宕机就会导致整个服务不可用。这种方式风险较大,所以不建议在线上环境中使用。
多 Master
所有消息服务器都是 Master,没有 Slave。这种方式的有点是配置简单,单个 Master 当即或重启维护对应用无影响;缺点是单台机器宕机期间,该机器上未被消费的消息在机器恢复之前不可订阅,消息的实时性会受到影响
多 Master 多 Slave(同步双写)
为每个 Master 都配置 Slave ,所以有多对 Master-Slave 消息采用同步双写方式,主备都写成功了才返回成功 。这种方式的优点是数据与服务都没有单点 Master 宕机时消息无延迟,服务与数据的可用性非常高;缺点是相对异步复制方式其性能略低,发送消息的延迟略高。
多 Master 多 Slave(异步复制)
为每个 Master 都配置一个 Slave ,所以有多对多 Master-Slave ,消息采用异步复制方式,主备之间有毫秒级消息延迟。这种方式的优点是丢失的消息非常少,且消息的实时性不会受到影响,Master 宕机后消费者可继续从 Slave 消费,中间的过程对用户应用程序透明,不需要人工干预,性能同多 Master 方式几乎一样;缺点是 Master 后在磁盘损坏的情况下会丢失极少量的消息。
2.6 名称服务器
名称服务器(NameServer )用来保存 Broker 相关元信息并给生产者和消费者查找 Broker 信息。名称服务器被设计成几乎无状态,可以横向扩展,节点之间无通信,通过部署多台机器来标识自己是一个伪集群。每个 Broker 在启动时都会到名称服务器中注册 ,生产者在发送消息前会根据主题到名称服务器中获取 Broker 的路由信息,消费者也会定时获取主题的路由信息。所以从功能上 ,它应该和 ZooKeeper 差不多,据说 RocketMQ 的早期版本确实使用了 Zoo Keeper ,后来改为自己实现的名称服务器。
2.7 消息
消息(Message )就是要传输的信息。一条消息必须有一个主题, 主题可以被看作是信件要邮寄的地址。一条消息也可以拥有一个可选的标签和额外的键值对,它们被用于设置一个业务 key 并在 Broker 查找此消息 ,以便在开发期间查找问题。
主题
主题( Topic )可以被看作是消息的归类,它是消息的第一级类型。比如一个电商系统可以分为交易消息、物流消息等。一条消息必须有一个主题。主题与 产者和消费关系非常松散,一个主题可以有 0 个、1个、多个生产者向其发送消息,一个生产者也可以同时向不同的主题发送消息。一个主题也可以被 0 个、1 个、多个消费者订阅。
标签
标签可以被看作是子主题,它是消息的第二级类型,用于为用户提供额外的灵活性。 使用标签,同一业务模块的不同目的的消息就可以用相同的主题而不同的标签来标识。比如交易消息又可以分为交易创建消息、交易完成消息等, 一条消息可以没有标签。标签有助于保持代码干净和连贯,并且还可以为 RocketMQ 查询系统提供帮助。
队列
主题被划分为一个或多个子主题,即队列 Queue 。在一个主题下可以设置多个队列,在发送消息时执行该消息的主题, RocketMQ 会轮询该主题下的所有队列将消息发送出去。Broker 内部消息情况如图所示
消息消费模式
消息消费模式有两种:集群消费( Clustering )和广播消费( Broadcasting )。
- 默认是集群消费,在该模式下一个消费者集群共同消费一个主题的多个队列,一个队列只会被一个消费者消费,如果某个消费者挂掉了,分组内的其他消费者会接替挂掉的消费者继续消费。
- 广播消费会将消息发给消费者组中的每一个消费者进行消费。
消费顺序
消费顺序有两种:顺序消费和并行消费。
- 顺序消费表示消息消费的顺序同生产者为每个消息队列发送的顺序一致,如果正在处理的全局顺 序是强制性的场景, 需要确保所使用的主题只有一个消息队列 。
- 并行消费不再保证消息顺序, 消费的最大并行数量受每个消费者客户端指定的线程池限制。