前言: 

MQ简介、特点、使用场景

RocketMQ简介及主流消息队列选型技术比较

  • RocketMQ简介:

RocketMQ是阿里出品,Java语言编写的,历经多次双十一大促考验,它的性能、稳定性和可靠性都是值得信赖,每秒钟大概能处理几十万条消息,采用发布订阅模式。源代码相对也比较容易读懂,也容易对 RocketMQ 进行扩展或者二次开发。RocketMQ 对在线业务的响应时延做了很多的优化,大多数情况下可以做到毫秒级的响应。比如交易系统和金融系统,很在意响应时延,那应该选择使用 RocketMQ。另,RocketMQ采用自研的协议,不支持 AMQP 协议等任何主流协议

基础

技术架构

四大组件

  1. Producer:生产者
  2. Consumer:消费者
  3. NameServer:简化版路由注册中心,其角色类似Dubbo中的zookeeper
  4. BrokerServer:Broker主要负责消息的存储

工作流程

rocketmq指标监控_rocketmq工作流程

基础概念

  • Topic:主题 可以理解为一级分类,比如订单类消息

Topic是一个逻辑上的概念,实际上在每个broker上以queue的形式保存,也就是说每个topic在 broker上会划分成几个逻辑队列(这些逻辑队列=queue),每个逻辑队列保存一部分消息数据

  • Tags: 消息标签 可以理解为二级分类,比如手机订单
  • Topic 分片:一个Topic在一个Broker上的子集定义为一个Topic分片
  • Queue:上文说了broker上会划分成几个逻辑队列,这些逻辑队列就是queue。

每个queue中存储多条消息(Message),且同一queue中的消息是有先后顺序的

queue是消费者消费的基本单元,queue越多,消费速度越快。

  • Message:生产者生产的消息
  • Message的属性如下:
  • topic:消息主题
  • tag :消息 TAG ,消费者消费消息时,用于同一Topic下消息的过滤
  • keys: Message 索引键,用来快速搜索消息
  • waitStoreMsgOK:消息发送时是否等消息存储完成后再返回

安装部署

集群搭建的几种方式

  1. 单Master模式:

这种方式风险较大,一旦Broker重启或者宕机时,会导致整个服务不可用。不建议线上环境使用,可以用于本地测试

  1. 多Master模式

一个集群无Slave,全是Master,例如2个Master或者3个Master,这种模式的优缺点如下:

优点:配置简单,单个Master宕机或重启维护对应用无影响,在磁盘配置为RAID10时,即使机器宕机不可恢复情况下,由于RAID10磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢),性能最高;

缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到影响。

  1. 多Master多Slave模式-异步复制

每个Master配置一个Slave,有多对Master-Slave,HA采用异步复制方式,主备有短暂消息延迟(毫秒级),这种模式的优缺点如下:

优点:即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,同时Master宕机后,消费者仍然可以从Slave消费,而且此过程对应用透明,不需要人工干预,性能同多Master模式几乎一样;

缺点:Master宕机,磁盘损坏情况下会丢失少量消息。

  1. 多Master多Slave模式-同步双写

每个Master配置一个Slave,有多对Master-Slave,HA采用同步双写方式,即只有主备都写成功,才向应用返回成功,这种模式的优缺点如下:

优点:数据与服务都无单点故障,Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高;

缺点:性能比异步复制模式略低(大约低10%左右),发送单个消息的RT会略高,且目前版本在主节点宕机后,备机不能自动切换为主机。

  1. Dledger集群(推荐)

rocketmq指标监控_rocketmq_02

RocketMQ-on-DLedger Group 是指一组相同名称的 Broker,至少需要 3 个节点,通过 Raft 自动选举出一个 Leader,其余节点 作为 Follower,并在 Leader 和 Follower 之间复制数据以保证高可用。

RocketMQ-on-DLedger Group 能自动容灾切换,并保证数据一致。

RocketMQ-on-DLedger Group 是可以水平扩展的,也即可以部署任意多个 RocketMQ-on-DLedger Group 同时对外提供服务

Dledger快速搭建

Dledger集群部署

部署常见配置:请参考本文第8节最佳配置

注册发现(NameServer-注册中心)

rocketmq指标监控_rocketmq原理_03

  • 产生背景

解决消息生产者如何知道消息要发往哪台Broker服务器的问题

解决Broker服务器宕机了,生产者在不重启服务即可感知并切换到可用服务的问题

消息发送(producer-生产者)

消息发送流程

  1. Broker启动时,Broker向NameServer提交注册信息
  2. 客户端调用producer发送消息,先从NameServer获取该topic的路由信息(本地有缓存会先查询缓存),从NameServer返回的路由信息,包括topic包含的queue列表和broker列表
  3. Producer端根据消息选择器策略(可自定义:例如顺序发送),选出其中一个queue,组装请求
  4. producer向Broker发送请求,broker将消息保存。
  5. broker返回结果

消息发送方式(代码、示例)

  • 同步:同步等待返回结果
  • 异步:接收异步回调结果
  • one-way:只管发送,不管返回结果

DefaultMQProducer 使用指引

DefaultMQProducer类是应用用来投递消息的入口,开箱即用,可通过无参构造方法快速创建一个生产者。主要负责消息的发送。

无法复制加载中的内容

消息存储(broker-代理)

消息存储组件

  1. CommitLog文件:保存消息的地方
  2. ConsumerQueue:消息消费队列文件,该文件可以看成是 CommitLog 关于消息消费的“索引”文件

消息存储流程

消息存储时首先将消息追加到内存,再根据配置的刷盘策略在不同时间进行写入磁盘CommitLog文件

消息存储方式

异步刷盘:消息存储到内存,便返回生产者成功

同步刷盘:消息存储到内存后,同步将消息存储到磁盘完成,才返回生产者成功

过期删除机制

默认存储3天,过期将删除

消息消费(consumer-消费者)

消费者集群的概念:使用相同Group ID的消费者属于同一个消费者集群。

消息消费的方式:集群与广播

  • 集群消费:当使用集群消费模式时,消息队列RocketMQ认为任意一条消息只需要被集群内的任意一个消费者处理即可。适用于消费端集群化部署,每条消息只需要被处理一次的场景。此外,由于消费进度在服务端维护,可靠性更高。

rocketmq指标监控_消息队列_04

  • 广播消费:当使用广播消费模式时,消息队列RocketMQ版会将每条消息推送给集群内所有注册过的消费者,保证消息至少被每个消费者消费一次。实际应用场景不多,适用于每条消息需要被集群下的每个消费者处理的场景(例如,注册中心某台服务挂掉了,需要通知每一个节点)

消费消息的模式:推与拉

  • 推:

推模式指的是消息从 Broker 推向 Consumer,即 Consumer 被动的接收消息,由 Broker 来主导消息的发送。

  • 推模式有什么好处?

消息实时性高, Broker 接受完消息之后可以立马推送给 Consumer。

对于消费者使用来说更简单,只需要等待消息推送过来。

  • 推模式有什么缺点?

推送速率难以适应消费速率,推模式的目标就是以最快的速度推送消息,当生产者往 Broker 发送消息的速率大于消费者消费消息的速率时,随着时间的增长消费者那边可能就“爆仓”了,因为根本消费不过来啊。

  • 总结:推模式难以根据消费者的状态控制推送速率,适用于消息量不大、消费能力强要求实时性高的情况下
  • 拉:

拉模式指的是 Consumer 主动向 Broker 请求拉取消息,即 Broker 被动的发送消息给 Consumer。

  • 拉模式有什么好处?

拉模式主动权就在消费者身上了,消费者可以根据自身的情况来发起拉取消息的请求。假设当前消费者觉得自己消费不过来了,它可以根据一定的策略停止拉取,或者间隔拉取都行。

拉模式可以更合适的进行消息的批量发送,基于推模式不知道消费者到底能不能处理这么多消息。而拉模式就更加合理,它可以参考消费者请求的信息来决定缓存多少消息之后批量发送。

  • 拉模式有什么缺点?

消息延迟,毕竟是消费者去拉取消息,但是消费者怎么知道消息到了呢?所以它只能不断地拉取,但是又不能很频繁地请求,太频繁了就变成消费者在攻击 Broker 了。因此需要降低请求的频率,比如隔个 2 秒请求一次,你看着消息就很有可能延迟 2 秒了。

  • 总结:RocketMQ 中的推模式其实是拉模式的包装,本质上都是拉模式。但RocketMQ本身对其做了优化(根据消息队列和消费者的数量做负载均衡、新消息来时及时唤醒等)避免了拉模式的缺点。

常见问题

生产者:采用同步发送+适当的重试策

Broker:采用同步刷盘,同步复制

消费者:消费成功再提交

RocketMQ本身不保证消息不会被重复处理,需要消费者自己对业务做幂等性处理

  • 最优配置
  1. HTTP静态服务器寻址(默认)

客户端启动后,会定时访问一个静态HTTP服务器,地址如下:http://jmenv.tbsite.net:8080/rocketmq/nsaddr,这个URL的返回内容如下:



192.168.0.1:9876;192.168.0.2:9876

客户端默认每隔2分钟访问一次这个HTTP服务器,并更新本地的Name Server地址。URL已经在代码中硬编码,可通过修改/etc/hosts文件来改变要访问的服务器,例如在/etc/hosts增加如下配置:



10.232.22.67 jmenv.taobao.net

推荐使用HTTP静态服务器寻址方式,好处是客户端部署简单,且Name Server集群可以热升级。

…………(待完善)

最佳配置

监控(控制台)

rocketmq指标监控_rocketmq工作流程_05

参考文献:

  1. RocketMQ 官方中文文档 (入门指引,知识讲解)
  2. RocketMQ 技术内幕-丁威 (原理讲解)
  3. RocketMQ 从入门到实战-丁威 (实战问题及解决方案)