RocketMQ 结构
概述
Apache RocketMQ是一个分布式消息传递和流平台,具有低延迟,高性能和可靠性,万亿级容量和灵活的可扩展性。它由四部分组成:NameServer、broker、producer 和 consumer。它们中的每一个都可以水平扩展而没有单点故障。 如上图所示。
NameServer集群
NameServer提供轻量级服务发现和路由。每个NameServer记录完整的路由信息,提供相应的读写服务,并支持快速存储扩展。
Broker集群
Broker通过提供轻量级的TOPIC和QUEUE机制来处理消息存储。它们支持Push和Pull模型,包含容错机制(2个副本或3个副本),并提供强大的峰值填充和以原始时间顺序堆积数千亿条消息的能力。此外,Broker还提供容灾恢复,丰富的埋点统计和报警机制,所有这些在传统的消息传递系统中都是缺乏的。
Producer集群
生产者支持分布式部署。分布式的Producer通过多种负载均衡模式向Broker集群发送消息。发送过程支持快速失败并具有低延迟性。
Consumer集群
消费者也支持Push和Pull模型中的分布式部署。它还支持集群消费和消息广播。它提供实时消息订阅机制,可以满足大多数消费者的需求。RocketMQ的网站为感兴趣的用户提供了一个简单的快速入门指南。
NameServer
NameServer 是一个功能齐全的服务器,主要包括两个功能:
- Broker管理,NameServer接受来自Broker集群的注册,并提供心跳机制来检查Broker是否存活。
- 路由管理,每个NameServer将保存有关Broker群集的整个路由信息和客户端查询的队列信息。
NameServer 与每台 Broker 服务器保持长连接,并间隔30s检测 Broker 是否存活,如果检测到 Broker 宕机,则从路由注册表中将其移除。但是路由变化不会马上通知消息生产者,为什么要这样设计呢?这是为了降低 NameServer 实现的复杂性,在消息发送端提供容错机制来保证消息发送的高可用性。NameServer 本身的高可用可通过部署多台 NameServer 服务器来实现,但彼此之间互不通信,也就是 NameServer 服务器之间在某一时刻的数据并不会完全相同,但这对消息发送不会造成任何影响,这也是 RocketMQ NameServer 设计的一个亮点,RocketMQ NameServer 设计追求简单高效。
我们知道,RocketMQ客户端(生产者/消费者)将从NameServer查询队列路由信息,但客户端如何找到NameServer地址?
将NameServer地址列表提供给客户端有四种方法:
- 编程方式,如
producer.setNamesrvAddr("ip:port")
。 - Java选项,使用
rocketmq.namesrv.addr
。 - 环境变量,使用
NAMESRV_ADDR
。 - HTTP Endpoint。
关于如何找到NameServer的更多信息请参考官方文档:http://rocketmq.apache.org/rocketmq/four-methods-to-feed-name-server-address-list/
Broker Server
Broker服务器负责消息存储和传递,消息查询,HA保证等。
如下图所示,Broker服务器有几个重要的子模块:
- Remoting模块,即Broker的entry,处理来自客户端的请求。
- 客户端管理,管理客户端(生产者/消费者)并维护消费者的主题订阅。
- 存储服务,提供简单的API来存储或查询物理磁盘中的消息。
- HA服务,提供主Broker和从Broker之间的数据同步功能。
- 索引服务,按指定key构建消息索引,并提供快速消息查询。
RocketMQ与ActiveMQ和Kafka的比较
消息产品 | 客户端SDK | 协议和规范 | 顺序消息 | 延时消息 | 批量消息 | 广播消息 | 消息过滤器 | 服务器触发重新传递 | 消息存储 | 消息追溯 | 消息优先级 | 高可用性和故障转移 | 消息跟踪 | 配置 | 管理和操作工具 |
ActiveMQ | Java,.NET,C++ etc. | Push模型,支持OpenWire,STOMP,AMQP,MQTT,JMS | 独占的消费者或独占的队列可以确保顺序 | 支持 | 不支持 | 支持 | 支持 | 不支持 | 使用JDBC和高性能日志(例如levelDB,kahaDB)支持非常快速的持久性 | 支持 | 支持 | 支持,根据存储,如果使用kahadb,则需要ZooKeeper服务器 | 不支持 | 默认配置为低级别,用户需要优化配置参数 | 支持 |
Kafka | Java,Scala etc. | Pull模型,支持TCP | 确保一个分区内的消息顺序 | 不支持 | 支持,使用异步生产者 | 不支持 | 支持,可以使用Kafka Streams过滤消息 | 不支持 | 高性能文件存储 | 支持,偏移量表示 | 不支持 | 支持,需要ZooKeeper服务器 | 不支持 | Kafka使用键值对格式进行配置。可以从文件或以编程方式提供这些值 | 支持,使用terminal命令公开核心指标 |
RocketMQ | Java,C++,Go | Pull模型,支持TCP,JMS,OpenMessaging | 确保严格的消息排序,并可以优雅地扩展 | 支持 | 支持,使用同步模式以避免消息丢失 | 支持 | 支持,基于SQL92的属性过滤器表达式 | 支持 | 高性能和低延迟的文件存储 | 支持,时间戳和偏移量两种表示 | 不支持 | 支持,Master-Slave模型,不需要其他工具 | 支持 | 开箱即用,用户只需要注意几个配置 | 支持了,丰富的Web和终端命令,以公开核心指标 |