RocketMQ主要由 Producer、Broker、Consumer、NameServer四部分组成
- Producer 生产消息
- Consumer 从Broker读取消费消息
- Broker 存储Producer发送过来的消息
- NameServer 为Producer或Consumer路由消息到Broker
Broker 在实际部署过程中对应一台服务器,每个 Broker 可以存储多个Topic的消息,每个Topic的消息也可以分片存储于不同的 Broker。Message Queue 用于存储消息的物理地址,每个Topic中的消息地址存储于多个 Message Queue 中。ConsumerGroup 由多个Consumer 实例构成。RocketMQ启动顺序为先NameServer,再Broker。
Topic与Queue
Topic是一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是RocketMQ进行消息订阅的基本单位。
在RocketMQ中Queue是组成Topic的更小单元,集群消费模式下一个消费者只消费该Topic中部分Queue中的消息,当一个消费者开启广播模式时则会消费该Topic下所有Queue中的消息。Broker Server(代理服务器)
消息中转角色,负责存储消息、转发消息。代理服务器在RocketMQ系统中负责接收从生产者发送来的消息并存储、同时为消费者的拉取请求作准备。代理服务器也存储消息相关的元数据,包括消费者组、消费进度偏移(offset)和主题(Topic)和队列消息等。
Name Server(名字服务)
名称服务充当路由消息的提供者。生产者或消费者能够通过名字服务查找各主题相应的Broker IP列表。多个Namesrv实例组成集群,但相互独立,没有信息交换。
Producer Group(生产者组)
同一类Producer的集合,这类Producer发送同一类消息且发送逻辑一致。如果发送的是事物消息且原始生产者在发送之后崩溃,则Broker服务器会联系同一生产者组的其他生产者实例以提交或回溯消费。
Consumer Group(消费者组)
同一类Consumer的集合,这类Consumer通常消费同一类消息且消费逻辑一致。消费者组使得在消息消费方面,实现负载均衡和容错的目标变得非常容易。要注意的是,消费者组的消费者实例必须订阅完全相同的Topic。RocketMQ 支持两种消息模式:集群消费(Clustering) 和广播消费(Broadcasting)。
Offset(Message Queue下的offset)
- max offset
MessageQueue中的max offset在源码中表示指消息的最大offset+1,即下条消息入队的位置。 - min offset
标识当前队列的最小offset。由于消息存储一段时间后,消费了的消息会从从磁盘物理删除,message queue的min offset也就对应增长,即比minOffset小的消息不存在broker上了。 - consumer offset
Consumer Group在MessageQueue上的消息消费进度,其实际值为队列中消费了的消息数+1,即表示下次拉取消息的位置。
DefaultMQPushConsumer.setConsumeFromWhere(ConsumerFromWhere)可设置从哪开始消费消息,但该设置的优先级在offset store后,当从offset store中读取不到offset的时候,ConsumerFromWhere的设置才生效。大部分该设置在ConsumerGroup初次启动时才有效(启动会一般会存储offset),即使Consumer正常运行时重启,依旧会接着上次的offset(从offset store中获取)开始消费,ConsumeFromWhere的设置无效。
- max offset
Clustering(集群消费)
集群消费模式下,相同Consumer Group的每个Consumer实例平均分摊消息。
广播消费(Broadcasting)
广播消费模式下,相同Consumer Group的每个Consumer实例都接收全量的消息。
Normal Ordered Message(普通顺序消息)
普通顺序消费模式下,消费者通过同一个消费队列收到的消息是有顺序的,不同消息队列收到的消息则可能是无顺序的。
如Broker Server将消息Msg_A、Msg_B、Msg_C按顺序发送到Topic_A主题上的队列Q_A、Q_B、Q_A,Consumer_A从订阅的Topic_A拉去消息的顺序可能为下:- Msg_A->Msg_B->Msg_C
- Msg_B->Msg_A->Msg_C
- Msg_A->Msg_C->Msg_B
Msg_B进入队列Q_A在Msg_A之后,所以Msg_B必然在接收到Msg_A后才被发送
Strictly Ordered Message(严格顺序消息)
严格顺序消息模式下,消费者收到的所有消息均是有顺序的。如上例中Consumer_A收到的顺序只会是Msg_A->Msg_B->Msg_C
Message(消息)
消息系统所传输信息的物理载体,生产和消费数据的最小单位,每条消息必须属于一个主题。RocketMQ中每个消息拥有唯一的Message ID,且可以携带具有业务标识的Key。系统提供了通过Message ID和Key查询消息的功能。常用属性:
- topic: 所属topic
- tags: 消息标签,用来做服务端消息过滤。一个topic下可以有很多tags,一般都通过topic+tags来消费自己想要的结果。
- keys: 消息关键词,查询消息使用
- body: 消息内容
Tag(标签)
可理解为二级Topic,用于同一Topic下区分不同类型的消息。来自同一业务单元的消息,可以根据不同业务目的在同一Topic下设置不同标签。标签能够有效地保持代码的清晰度和连贯性,并优化RocketMQ提供的查询系统。消费者可以根据Tag实现对不同子Topic的不同消费逻辑,实现更好的扩展性。
各MQ产品对比(译自RocketMQ官方对比)
RocketMQ | Kafka | ActiveMQ | |
---|---|---|---|
客户端SDK | Java,C ++,Go | Java,Scala等 | Java,.NET,C ++等 |
协议规范 | 拉模型,支持TCP,JMS,OpenMessaging | 拉模型,支持TCP | 推送模型,支持OpenWire,STOMP,AMQP,MQTT,JMS |
消息排序 | 确保对消息进行严格排序,并可以正常扩展 | 确保分区内消息的顺序 | 排他消费者或排他队列可确保顺序 |
定时消息 | 支持 | 不支持 | 支持 |
批量消息 | 支持,具有同步模式,可避免消息丢失 | 支持,带异步Producer | 不支持 |
广播消息 | 支持 | 不支持 | 支持 |
消息过滤器 | 支持,基于SQL92的属性过滤器表达式过滤 | 支持,使用kafka stream过滤 | 支持 |
服务器触发重新交付 | 支持 | 不支持 | 不支持 |
消息存储 | 高性能和低延迟文件存储 | 高性能文件存储 | 使用JDBC和高性能日志(例如levelDB,kahaDB)存储支持非常快速持久性 |
消息追溯 | 支持时间戳和偏移量追溯 | 支持的偏移量追溯 | 支持 |
消息优先级 | 不支持 | 不支持 | 支持 |
高可用与故障切换 | 支持主从模式 | 支持,需额外配置ZooKeeper服务器 | 支持,取决于存储,如果使用kahadb,则需要ZooKeeper服务器 |
消息追踪 | 支持 | 不支持 | 不支持 |
配置特点 | 开箱即用,用户只需要注意一些配置 | 使用键值对格式进行配置,这些值可以从文件或以编程方式提供 | 默认配置为低级别,用户需要优化配置参数 |
操作管理工具 | 支持,Web控制台和终端命令都可操作管理 | 支持,使用终端命令管理 | 支持 |