生产者:生产者负责生产消息,生产者向消息服务器发送由业务应用程序系统生成的消息。RocketMQ提供了三种方式发送消息:同步、异步和单向。
生产者是一类生产者的集合,这类生产者通常发送一类消息并且发送逻辑一致,所以将这些生产者分组在一起。从部署结构上看,生产者通过生产者组的名字来标识自己是一个群体。
消费者负责消费消息,它从消息服务器拉去消息并将其输入用户应用程序中。从用户应用的角度来看,消费者由两种类型:拉取型消费者和推送型消费者。
拉取型消费者(Pull Consumer)
拉取型消费者主动从消息服务器拉取消息,只要批量拉取到消息,用户应用就会启动消费过程,所以Pull被称为主动消费类型。
推送型消费者(Push Consumer)
推送型消费者封装了消息的拉取、消费进度和其他内部维护工作,将消息到达时执行的回调接口留给用户应用程序来实现。所以 Push 被称为被动消费类型。但从实现上看,还是从消息服务器拉取消息的。不同于 Pull 的是,Push首先要注册消费监听器,当监听器被触发后才开始消费消息。
消费者组是一类消费者的集合,这类消费者通常消费同一类消息,并且消费逻辑一致,所以将这些消费者分组在一起,消费者组与生产者组类似,都是将相同角色的消费者分组在一起井命名的。
分组是一个很精妙的概念设计。RocketMQ 正是通过这种分组机制,实现了天然的消息负载均衡。在消费消息时,通过消费者组实现了将消息分发到多个消费者服务器实例,比如某个主题有 9 条消息,其中一个消费者组有 3 个实例 (3 个进程或 3台机器),那么每个实例将均摊 3 条消息,这也意味着我们可以很方便地通过增加机器来实现水平扩展。
消息服务器(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 后在磁盘损坏的情况下会丢失极少量的消息。
名称服务器(NameServer )用来保存 Broker 相关元信息并给生产者和消费者查找 Broker 信息。名称服务器被设计成几乎无状态,可以横向扩展,节点之间无通信,通过部署多台机器来标识自己是一个伪集群。每个 Broker 在启动时都会到名称服务器中注册 ,生产者在发送消息前会根据主题到名称服务器中获取 Broker 的路由信息,消费者也会定时获取主题的路由信息。所以从功能上 ,它应该和 ZooKeeper 差不多,据说 RocketMQ 的早期版本确实使用了 Zoo Keeper ,后来改为自己实现的名称服务器。
消息(Message )就是要传输的信息。一条消息必须有一个主题, 主题可以被看作是信件要邮寄的地址。一条消息也可以拥有一个可选的标签和额外的键值对,它们被用于设置一个业务 key 并在 Broker 查找此消息 ,以便在开发期间查找问题。
主题
主题( Topic )可以被看作是消息的归类,它是消息的第一级类型。比如一个电商系统可以分为交易消息、物流消息等。一条消息必须有一个主题。主题与 产者和消费关系非常松散,一个主题可以有 0 个、1个、多个生产者向其发送消息,一个生产者也可以同时向不同的主题发送消息。一个主题也可以被 0 个、1 个、多个消费者订阅。
标签
标签可以被看作是子主题,它是消息的第二级类型,用于为用户提供额外的灵活性。 使用标签,同一业务模块的不同目的的消息就可以用相同的主题而不同的标签来标识。比如交易消息又可以分为交易创建消息、交易完成消息等, 一条消息可以没有标签。标签有助于保持代码干净和连贯,并且还可以为 RocketMQ 查询系统提供帮助。
队列
主题被划分为一个或多个子主题,即队列 Queue 。在一个主题下可以设置多个队列,在发送消息时执行该消息的主题, RocketMQ 会轮询该主题下的所有队列将消息发送出去。Broker 内部消息情况如图所示
消息消费模式
消息消费模式有两种:集群消费( Clustering )和广播消费( Broadcasting )。
消费顺序
消费顺序有两种:顺序消费和并行消费。