一、简介
RocketMQ是阿里开源的一款分布式消息中间件,满足线上海量消息堆积的需求, 在2016年底捐赠给Apache开源基金会成为孵化项目,2017年正式成为了Apache顶级项目。是一款纯Java的消息中间件,可靠性、低延迟、可扩展、易于使用的特性而著称。
1、背景介绍
阿里早期也是基于ActiveMQ 5.x的分布式消息中间件来构建其消息中间件,但是随着主题和队列的增加慢慢的发现ActiveMQ IO模块遇到了瓶颈。我们尽力通过节流,断路器或降级解决这个问题,但效果不佳。因此,我们开始关注当时流行的消息传递解决方案Kafka。不幸的是,Kafka无法满足我们的要求,特别是在低延迟和高可靠性方面。Kafka是一个分布式流媒体平台,它源于日志聚合案例。它不需要太高的并发性。在阿里巴巴的一些大型案例中,我们发现原始模型无法满足我们的实际需求。
RocketMQ起源于最开始阿里的Metaq( Metamorphosis) 经历过Metaq 1.x、Metaq 2.x、RocketMQ3.x在其3.0版本的时候更名为RocketMQ,目前最新版本为RocketMQ4.5.x。
2、使用场景
与其说是RocketMQ的使用场景,不如说是MQ(消息队列)的使用场景,MQ的产品比较多目前比较流行的有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ等
MQ 可应用在多个领域,包括异步通信解耦、企业解决方案、金融支付、电信、电子商务、快递物流、广告营销、社交、即时通信、手游、视频、物联网、车联网等。
下面列举了一些常用的场景:
-
一对多,多对多异步解耦,基于发布订阅模型,对分布式应用进行异步解耦,增加应用的水平扩展能力。
-
削峰填谷,大促等流量洪流突然来袭时,MQ 可以缓冲突发流量,避免下游订阅系统因突发流量崩溃。
-
日志监控,作为重要日志的监控通信管道,将应用日志监控对系统性能影响降到最低。
-
消息推送,为社交应用和物联网应用提供点对点推送,一对多广播式推送的能力。
-
金融报文,发送金融报文,实现金融准实时的报文传输,可靠安全。
-
电信信令,将电信信令封装成消息,传递到各个控制终端,实现准实时控制和信息传递
3、主流MQ比较
主流的MQ的对比RocketMQ 、 ActiveMQ 、 Kafka
消息产品 | 客户端SDK | 协议和规范 | 消息存储 | 服务器触发重新传递 | 广播消息 | 高可用性和故障转移 | 消息跟踪 |
---|---|---|---|---|---|---|---|
ActiveMQ | Java,.NET,C ++等 | 推模型,支持OpenWire,STOMP,AMQP,MQTT,JMS | 使用JDBC和高性能日志(如levelDB,kahaDB)支持非常快速的持久性 | 不支持 | 支持 | 支持,根据存储,如果使用kahadb,则需要ZooKeeper服务器 | 不支持 |
Kafka | Java,Scala等 | 拉模型,支持TCP | 高性能文件存储 | 不支持 | 不支持 | 支持,需要ZooKeeper服务器 | 不支持 |
RocketMQ | Java,C ++,Go | 拉模型,支持TCP,JMS,OpenMessaging | 高性能和低延迟的文件存储 | 支持 | 支持 | 支持的Master-Slave模型,没有其他套件 | 支持 |
二、概况
1、RocketMQ集群部署结构
imageName Server
Name Server是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。
Broker
Broker部署相对复杂,Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master,Master与Slave的对应关系通过指定相同的Broker Name,不同的Broker Id来定义,BrokerId为0表示Master,非0表示Slave。Master也可以部署多个。
每个Broker与Name Server集群中的所有节点建立长连接,定时(每隔30s)注册Topic信息到所有Name Server。Name Server定时(每隔10s)扫描所有存活broker的连接,如果Name Server超过2分钟没有收到心跳,则Name Server断开与Broker的连接。
Producer
Producer与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可集群部署。
Producer每隔30s(由ClientConfig的pollNameServerInterval)从Name server获取所有topic队列的最新情况,这意味着如果Broker不可用,Producer最多30s能够感知,在此期间内发往Broker的所有消息都会失败。
Producer每隔30s(由ClientConfig中heartbeatBrokerInterval决定)向所有关联的broker发送心跳,Broker每隔10s中扫描所有存活的连接,如果Broker在2分钟内没有收到心跳数据,则关闭与Producer的连接。
Consumer
Consumer与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker配置决定。
Consumer每隔30s从Name server获取topic的最新队列情况,这意味着Broker不可用时,Consumer最多最需要30s才能感知。
Consumer每隔30s(由ClientConfig中heartbeatBrokerInterval决定)向所有关联的broker发送心跳,Broker每隔10s扫描所有存活的连接,若某个连接2分钟内没有发送心跳数据,则关闭连接;并向该Consumer Group的所有Consumer发出通知,Group内的Consumer重新分配队列,然后继续消费。
当Consumer得到master宕机通知后,转向slave消费,slave不能保证master的消息100%都同步过来了,因此会有少量的消息丢失。但是一旦master恢复,未同步过去的消息会被最终消费掉。
2、消息发送类型
1)同步消息(可靠)
同步发送,线程阻塞,投递completes阻塞结束
如果发送失败,会在默认的超时时间3秒内进行重试,最多重试2次
投递completes不代表投递成功,要check SendResult.sendStatus来判断是否投递成功
2)异步消息(可靠)
发送异步消息需要指定消息发送成功后的回调函数,调用发送消息的API会立刻返回,消息发送者的线程不阻 塞,直到运行结束,消息发送成功或者失败的回调任务在新的线程中执行。
3)单向消息(不可靠)
消息不可靠,性能高,只负责往服务器发送一条消息,不会重试也不关心是否发送成功
此方式发送消息的过程耗时非常短,一般在微秒级别
3、消费模式(集群/广播)
RocketMQ物理部署图:
image术语解释
消息主题(Topic)
Topic是生产者在发送消息和消费者在拉取消息的类别。Topic与生产者和消费者之间的关系非常松散。具体来说,一个Topic可能有0个,一个或多个生产者向它发送消息;相反,一个生产者可以发送不同类型Topic的消息。类似的,消费者组可以订阅一个或多个主题,只要该组的实例保持其订阅一致即可。
一个主题对应多个队列(默认4个)
消息是存储在不同的队列中
消费组(ConsumerGroup)
一类 Consumer 的集合名称,组内的 Consumer 通常消费一类消息,消费消息逻辑一致。
一个consumerGroup只对应一个topic
同一个ConsumerGroup中的消费者订阅的主题(Topic)和标签(Tag)必须一致(集群模式下消费会有问题)
一个消息队列只会对应一个消费者
生产组(ProducerGroup)
一类 Producer 的集合名称,组内的 Producer 通常发送一类消息,发送消息逻辑一致
1)广播模式
一条消息被多个consumer消费,即使这些consumer属于同一个ConsumerGroup,消息也会被ConsumerGroup中的每个Consumer都消费一次,广播消费中ConsumerGroup概念可以认为在消息划分方面无意义。
2)集群模式(默认)
一个ConsumerGroup中的Consumer实例平均分摊消费消息。例如某个Topic有9条消息,其中一个ConsumerGroup有3个实例(可能是3个进程,或者3台机器),那么每个实例只消费其中部分,消费完的消息不能被其他实例消费。
网友评论