Apache RocketMQ 的基础特性介绍
Apache RocketMQ 的基础特性介绍
Apache RocketMQ 系列:
Apache RocketMQ之JMS基本概念及使用:https://www.jianshu.com/p/d2e3fd77c4f4
Apache RocketMQ 基础概念及架构解析:https://www.jianshu.com/p/95ab928960b3
Apache RocketMQ 的基础特性介绍:https://www.jianshu.com/p/570680b32590
Apache RocketMQ 集群搭建(两主两从):https://www.jianshu.com/p/b090138cf52c
Apache RocketMQ 刷盘策略与复制策略: https://www.jianshu.com/p/d66b381428bb
RcoketMQ 是一款低延迟、高可靠、可伸缩、易于使用的消息中间件。具有以下特性:
- 支持发布/订阅(Pub/Sub)和点对点(P2P)消息模型
- 在一个队列中可靠的先进先出(FIFO)和严格的顺序传递
- 支持拉(pull)和推(push)两种消息模式
- 单一队列百万消息的堆积能力
- 支持多种消息协议,如 JMS、MQTT 等
- 分布式高可用的部署架构,满足至少一次消息传递语义
- 提供 docker 镜像用于隔离测试和云集群部署
- 提供配置、指标和监控等功能丰富的 Dashboard
相关名词介绍:
Producer
消息生产者,生产者的作用就是将消息发送到 MQ,生产者本身既可以产生消息,如读取文本信息等。也可以对外提供接口,由外部应用来调用接口,再由生产者将收到的消息发送到 MQ,一般由业务系统负责产生消息。
Producer Group
生产者组,简单来说就是多个发送同一类消息的生产者称之为一个生产者组。在这里可以不用关心,只要知道有这么一个概念即可。
Consumer
消费者,简单来说,消费 MQ 上的消息的应用程序就是消费者,至于消息是否进行逻辑处理,还是直接存储到数据库等取决于业务需要,一般是后台系统负责异步消费。
Consumer Group
消费者组,和生产者类似,消费同一类消息的多个 consumer 实例组成一个消费者组。
Topic
Topic 是一种消息的逻辑分类,比如说你有订单类的消息,也有库存类的消息,那么就需要进行分类,一个是订单 Topic 存放订单相关的消息,一个是库存 Topic 存储库存相关的消息。
Message
Message 是消息的载体。一个 Message 必须指定 topic,相当于寄信的地址。Message 还有一个可选的 tag 设置,以便消费端可以基于 tag 进行过滤消息。也可以添加额外的键值对,例如你需要一个业务 key 来查找 broker 上的消息,方便在开发过程中诊断问题。
Tag
标签可以被认为是对 Topic 进一步细化。一般在相同业务模块中通过引入标签来标记不同用途的消息。
Broker
消息中转角色,负责存储消息,转发消息,一般也称为 Server,在 JMS 规范中称为 Provider
Name Server
服务发现Server,用于生产者和消费者获取Broker的服务;
RocketMQ 源码Git地址:https://github.com/apache/rocketmq
RocketMQ 模块划分:
名称 | 描述 |
---|---|
broker | broker模块:c和p端消息存储逻辑 |
client | 客户端api:produce、consumer端 接受与发送api |
common | 公共组件:常量、基类、数据结构 |
tools | 运维tools:命令行工具模块 |
store | 存储模块:消息、索引、commitlog存储 |
namesrv | 服务管理模块:服务注册topic等信息存储 |
remoting | 远程通讯模块:netty+fastjson |
logappender | 日志适配模块 |
example | Demo列子 |
filtersrv | 消息过滤器模块 |
srvutil | 辅助模块 |
filter | 过滤模块:消息过滤模块 |
distribution | 部署、运维相关zip包中的代码 |
openmessaging | 兼容openmessaging分布式消息模块 |
RocketMQ 高可用:
情况 | 发送消息 | 发送消息过程中 | 接受消费消息 |
---|---|---|---|
停用一个 NameSrv | 不影响通信 | 不影响通信 | 不影响通信 |
停用全部 NameSrv | 影响通信 | 不影响通信 | 影响通信,启动任意NameSrv后恢复 |
停用一个 Master Broker | 不影响通信 | 不影响通信 | 不影响通信 |
停用全部 Master Broker | 影响通信 | 影响通信,无法恢复 | 影响通信 |
停用任意 Slave Broker | 不影响通信 | 不影响通信 | 不影响通信 |
恢复任意 Master Broker | 不影响通信 | 影响通信,数秒恢复 | 不影响通信,数秒恢复 |
特性:
Producer端:
发送方式:
-
Sync:同步的发送方式,会等待发送结果后才返回。
-
Async:异步的发送方式,发送完后,立刻返回。Client 在拿到 Broker 的响应结果后,会回调指定的 callback. 这个 API 也可以指定 。
-
Timeout,不指定也是默认的 3000ms。
-
Oneway:比较简单,发出去后,什么都不管直接返回。Ps:发送日志可以用这种
发送结果:
-
org.apache.rocketmq.client.producer.SendStatus
SEND_OK:消息发送成功。 -
FLUSH_DISK_TIMEOUT:消息发送成功,但是服务器刷盘超时,消息已经进入服务器队列,只有此时服务器宕机,消息才会丢失。
-
FLUSH_SLAVE_TIMEOUT:消息发送成功,但是服务器同步到 Slave 时超时,消息已经进入服务器队列,只有此时服务器宕机,消息才会丢失。
-
SLAVE_NOT_AVAILABLE: 消息发送成功,但是此时 slave 不可用,消息已经进入服务器队列,只有此时服务器宕机,消息才会丢。
消息种类:
普通消息:
org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl#sendDefaultImpl
2.png
-
准备工作 mesasge、网络相关、线程相关
-
从namesrv获取topic路由(缓存机制)
-
组装数据,broker需要的序列化数据(json)
-
Netty发送
定时消息
-
定时消息是指消息发到 Broker 后,不能立刻被 Consumer 消费,要到特定的时间点或者等待特定的时间后才能被消费。(第三方 job 步长)
-
固定精度:
1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
org.apache.rocketmq.store.config.MessageStoreConfig#messageDelayLevel
顺序消息:
-
场景:订单->下单->支付->配送->签收
-
底层原理:4个队列,一个订单下面不同状态的消息是顺序的只需要发到一个队列中
org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl#sendSelectImpl
3.png
事务消息:
4.png更详细的介绍:
http://rocketmq.apache.org/rocketmq/the-design-of-transactional-message/
Consumer端:
消费模型:
org.apache.rocketmq.common.protocol.heartbeat.MessageModel#BROADCASTING
org.apache.rocketmq.common.protocol.heartbeat.MessageModel#CLUSTERING
消费选择:
第一次启动从队列最后位置消费,后续再启动接着上次消费的进度开始消费
org.apache.rocketmq.common.consumer.ConsumeFromWhere#CONSUME_FROM_LAST_OFFSET
第一次启动从队列初始位置消费,后续再启动接着上次消费的进度开始消费
org.apache.rocketmq.common.consumer.ConsumeFromWhere#CONSUME_FROM_FIRST_OFFSET
第一次启动从指定时间点位置消费,后续再启动接着上次消费的进度开始消费
org.apache.rocketmq.common.consumer.ConsumeFromWhere#CONSUME_FROM_TIMESTAMP
以上所说的第一次启动是指从来没有消费过的消费者,如果该消费者消费过,那么会在broker端记录该消费者的消费位置,如果该消费者挂了再启动,那么自动从上次消费的进度开始
广播消费:
一条消息被多个 Consumer 消费,即使返些 Consumer 属亍同一个 Consumer Group,消息也会被 Consumer
Group 中的每个 Consumer 都消费一次,广播消费中的 Consumer Group 概念可以讣为在消息划分方面无意义。
在 CORBA Notification 规范中,消费方式都属亍广播消费。
在 JMS 规范中,相当亍 JMS publish/subscribe mod
集群消费:
一个 Consumer Group 中的 Consumer 实例平均分摊消费消息。例如某个 Topic 有 9 条消息,其中一个
Consumer Group 有 3 个实例(可能是 3 个进程,或者 3 台机器),那么每个实例只消费其中的 3 条消息。
Message Queue
在 RocketMQ 中,所有消息队列都是持久化,长度无限的数据结构。
所谓长度无限是指队列中的每个存储
单元都是定长,访问其中的存储单元使用 Offset 来访问,offset 为 java long 类型,64 位,理论上在 100
年内不会溢出,所以认为是长度无限。
另外队列中只保存最近几天的数据,之前的数据会按照过期时间来删除。
消息重复幂等:
RocketMQ无法避免消息重复,所以如果业务对消费重复非常敏感,务必要在业务层面去重。可以根据业务上唯一标识来作为幂等处理的依据。