Rocketmq 整体分析

一、Rocketmq 组件: NameSrv: 负责维护一些全局的路由信息:当前有哪些broker,每个Topic在哪个broker上等; Broker: 具体处理消息的存储和服务; producer: 消息生产者 consumer: 消息消费者

十分钟入门RocketMQ http://jm.taobao.org/2017/01/12/rocketmq-quick-start-in-10-minutes/ http://www.infoq.com/cn/news/2017/02/RocketMQ-future-idea http://www.cnblogs.com/mantu/p/6108645.html

rocketmq 的主要部分是由4种集群构成的:namesrv集群、broker集群、producer集群和consumer集群。 namesrv集群:也就是注册中心,rocketmq在注册中心这块没有使用第三方的中间件,而是自己写的代码来实现的,代码行数才1000行,producer、broker和consumer在启动时都需要向namesrv进行注册,namesrv服务之间不通讯。 broker集群:broker提供关于消息的管理、存储、分发等功能,是消息队列的核心组件。 rocketmq关于broker的集群提供了主要两种方案,一种是主从同步方案,消息同时写到master和slave服务器视为消息发送成功;另一种是异步方案,slave的异步服务负责读取master的数据,本人在选择时更倾向于异步方案。 producer集群:消息的生产者,每个producer都需要属于一个group, producer的group概念除了在事务消息时起到一些作用,但是其它时候,更多的还只是一个虚拟的概念。 consumer集群:消息的消费者,有两个主要的consumer:DefaultMQPullConsumer和DefaultMQPushConsumer,深入代码后可以发现,rocketmq的consumer都是采用的pull模式来处理消息的。在集群消息的配置下,集群内各个服务平均分配消息,当其中一台consumer宕机,分配给它的消息会继续分配给其它的consumer。

一 nameserver 相对来说,nameserver的稳定性非常高。原因有二: 1 nameserver互相独立,彼此没有通信关系,单台nameserver挂掉,不影响其他nameserver,即使全部挂掉,也不影响业务系统使用,这点类似于dubbo的zookeeper。 2 nameserver不会有频繁的读写,所以性能开销非常小,稳定性很高。

二 broker 1 与nameserver关系 ● 连接:单个broker和所有nameserver保持长连接 ● 心跳 心跳间隔:每隔30秒(此时间无法更改)向所有nameserver发送心跳,心跳包含了自身的topic配置信息。 心跳超时:nameserver每隔10秒钟(此时间无法更改),扫描所有还存活的broker连接,若某个连接2分钟内(当前时间与最后更新时间差值超过2分钟,此时间无法更改)没有发送心跳数据,则断开连接。 ● 断开 时机:broker挂掉;心跳超时导致nameserver主动关闭连接 动作:一旦连接断开,nameserver会立即感知,更新topic与队列的对应关系,但不会通知生产者和消费者

2 负载均衡 ● 一个topic分布在多个broker上,一个broker可以配置多个topic,它们是多对多的关系。 ● 如果某个topic消息量很大,应该给它多配置几个队列,并且尽量多分布在不同broker上,减轻某个broker的压力。 ● topic消息量都比较均匀的情况下,如果某个broker上的队列越多,则该broker压力越大。

3 可用性 由于消息分布在各个broker上,一旦某个broker宕机,则该broker上的消息读写都会受到影响。所以rocketmq提供了master/slave的结构,salve定时从master同步数据,如果master宕机,则slave提供消费服务,但是不能写入消息,此过程对应用透明,由rocketmq内部解决。 这里有两个关键点: ● 一旦某个broker master宕机,生产者和消费者多久才能发现?受限于rocketmq的网络连接机制,默认情况下,最多需要30秒,但这个时间可由应用设定参数来缩短时间。这个时间段内,发往该broker的消息都是失败的,而且该broker的消息无法消费,因为此时消费者不知道该broker已经挂掉。 ● 消费者得到master宕机通知后,转向slave消费,但是slave不能保证master的消息100%都同步过来了,因此会有少量的消息丢失。但是消息最终不会丢的,一旦master恢复,未同步过去的消息会被消费掉。

4 可靠性: 所有发往broker的消息,有同步刷盘和异步刷盘机制,总的来说,可靠性非常高 ● 同步刷盘时,消息写入物理文件才会返回成功,因此非常可靠 ● 异步刷盘时,只有机器宕机,才会产生消息丢失,broker挂掉可能会发生,但是机器宕机崩溃是很少发生的,除非突然断电 5 消息清理 ● 扫描间隔: 默认10秒,由broker配置参数cleanResourceInterval决定 ● 空间阈值 物理文件不能无限制的一直存储在磁盘,当磁盘空间达到阈值时,不再接受消息,broker打印出日志,消息发送失败,阈值为固定值85% ● 清理时机: 默认每天凌晨4点,由broker配置参数deleteWhen决定;或者磁盘空间达到阈值 ● 文件保留时长: 默认72小时,由broker配置参数fileReservedTime决定

6 读写性能 ● 文件内存映射方式操作文件,避免read/write系统调用和实时文件读写,性能非常高 ● 永远一个文件在写,其他文件在读 ● 顺序写,随机读 ● 利用linux的sendfile机制,将消息内容直接输出到sokect管道,避免系统调用 7 系统特性 ● 大内存,内存越大性能越高,否则系统swap会成为性能瓶颈 ● IO密集 ● cpu load高,使用率低,因为cpu占用后,大部分时间在IO WAIT ● 磁盘可靠性要求高,为了兼顾安全和性能,采用RAID10阵列 ● 磁盘读取速度要求快,要求高转速大容量磁盘

三 消费者 1 与nameserver关系 ● 连接: 单个消费者和一台nameserver保持长连接,定时查询topic配置信息,如果该nameserver挂掉,消费者会自动连接下一个nameserver,直到有可用连接为止,并能自动重连。 ● 轮询时间: 默认情况下,消费者每隔30秒从nameserver获取所有topic的最新队列情况,这意味着某个broker如果宕机,客户端最多要30秒才能感知。该时间由DefaultMQPushConsumer的pollNameServerInteval参数决定,可手动配置。 ● 心跳: 与nameserver没有心跳

2 与broker关系 ● 连接: 单个消费者和该消费者关联的所有broker保持长连接。 ● 心跳: 默认情况下,消费者每隔30秒向所有broker发送心跳,该时间由DefaultMQPushConsumer的heartbeatBrokerInterval参数决定,可手动配置。broker每隔10秒钟(此时间无法更改),扫描所有还存活的连接,若某个连接2分钟内(当前时间与最后更新时间差值超过2分钟,此时间无法更改)没有发送心跳数据,则关闭连接,并向该消费者分组的所有消费者发出通知,分组内消费者重新分配队列继续消费 ● 断开 时机:消费者挂掉;心跳超时导致broker主动关闭连接 动作:一旦连接断开,broker会立即感知到,并向该消费者分组的所有消费者发出通知,分组内消费者重新分配队列继续消费

3 负载均衡: 集群消费模式下,一个消费者集群多台机器共同消费一个topic的多个队列,一个队列只会被一个消费者消费。如果某个消费者挂掉,分组内其它消费者会接替挂掉的消费者继续消费。

4 消费机制 ● 本地队列 消费者不间断的从broker拉取消息,消息拉取到本地队列,然后本地消费线程消费本地消息队列,只是一个异步过程,拉取线程不会等待本地消费线程,这种模式实时性非常高。对消费者对本地队列有一个保护,因此本地消息队列不能无限大,否则可能会占用大量内存,本地队列大小由DefaultMQPushConsumer的pullThresholdForQueue属性控制,默认1000,可手动设置。 ● 轮询间隔 消息拉取线程每隔多久拉取一次?间隔时间由DefaultMQPushConsumer的pullInterval属性控制,默认为0,可手动设置。 ● 消息消费数量 监听器每次接受本地队列的消息是多少条?这个参数由DefaultMQPushConsumer的consumeMessageBatchMaxSize属性控制,默认为1,可手动设置。

5 消费进度存储 每隔一段时间将各个队列的消费进度存储到对应的broker上,该时间由DefaultMQPushConsumer的persistConsumerOffsetInterval属性控制,默认为5秒,可手动设置。

6 如果一个topic在某broker上有3个队列,一个消费者消费这3个队列,那么该消费者和这个broker有几个连接? 一个连接,消费单位与队列相关,消费连接只跟broker相关,事实上,消费者将所有队列的消息拉取任务放到本地的队列,挨个拉取,拉取完毕后,又将拉取任务放到队尾,然后执行下一个拉取任务

四 生产者 1 与nameserver关系 ● 连接: 单个生产者者和一台nameserver保持长连接,定时查询topic配置信息,如果该nameserver挂掉,生产者会自动连接下一个nameserver,直到有可用连接为止,并能自动重连。 ● 轮询时间: 默认情况下,生产者每隔30秒从nameserver获取所有topic的最新队列情况,这意味着某个broker如果宕机,生产者最多要30秒才能感知,在此期间,发往该broker的消息发送失败。该时间由DefaultMQProducer的pollNameServerInteval参数决定,可手动配置。 ● 心跳: 与nameserver没有心跳

2 与broker关系 ● 连接: 单个生产者和该生产者关联的所有broker保持长连接。 ● 心跳:默认情况下,生产者每隔30秒向所有broker发送心跳,该时间由DefaultMQProducer的heartbeatBrokerInterval参数决定,可手动配置。broker每隔10秒钟(此时间无法更改),扫描所有还存活的连接,若某个连接2分钟内(当前时间与最后更新时间差值超过2分钟,此时间无法更改)没有发送心跳数据,则关闭连接。 ● 连接断开:移除broker上的生产者信息

3 负载均衡: 生产者时间没有关系,每个生产者向队列轮流发送消息

核心特性 1.读队列数量和写队列数量可以不一致:当我们使用updateTopic命令创建topic时,会发现新建的topic下会有默认的8个写对列和8个读对列(依赖于配置),并且读队列的数量和写队列的数量还可以不一致,这是为什么呢?难道在底层读写队列是在物理上分离的吗?抱着这个问题,我分析了相关的源代码,发现底层代码对于读写队列指的都是同一个队列,其中写队列的数量是针对的producer,读队列的数量针对的是consumer: a.假设写队列有8个、读队列有4个,那么producer产生的消息会按轮训的方式写入到8个队列中,但是consumer却只能消费前4个队列,只有把读队列重新设置为8后,consumer可以继续消费后4个队列的历史消息; b.假设写队列有4个、读队列有8个,那么producer产生的消息会按轮训的方式写入到4个队列中,但是consumer却能消费8个队列,只是后4个队列没有消息可以消费罢了。 2.存储为文件存储方式,支持同步落盘和异步刷盘两种方式,我倾向于选择异步刷盘的方式,毕竟broker挂掉的概率比较小,大部分的业务场景下在极端情况下丢失及其少量消息是可以忍受的; 3.支持消息回溯,支持定期删除历史消息; 4.集群方案比activemq要优秀很多,支持多主多从方案,例如在2主2从异步架构下,a,b为master,as,bs为slaver,当a机宕机后,producer会将消息全部发往b机,consumer会消费as,b和bs上的消息,理论上只会丢失毫秒级别的消息,不会影响业务的正常使用。可以说rocketmq的集群方案完爆activemq的集群方案,很多时候,我们对于异步队列的性能要求不高,但是集群的可用性要求一定是很高的。下面是activemq的三种集群方案: a.磁盘阵列类,成本较高,也是一种通用的方案; b.利用jdbc来实现统一存储消息,不但性能成问题,而且也只是把问题丢给了数据库罢了,没有解决集群的单机问题; c.利用zookeeper的注册中心的选主功能,在各个服务之间同步数据,在实际的使用过程中发现主机自动漂移,同步数据不完全造成的数据错乱且服务启动不了,反而不如单机来的稳定; 5.队列数量单机支持10000个以上; 6.consumer支持集群功能,可以平均消费消息,当有一台consumer宕机后,其它consumer继续均分; 7.consumer是靠pull的方式来消费消息的,性能不低于push的方式,这也是broker的并行能力强的一个原因,将主动权下放给了consumer,降低了broker的运算量和线程切换成本; 8.支持顺序消息,可以在发送消息时,利用selector机制的hash方式取模来实现消息落到哪个broker的哪个queue上,当某个broker宕机后,由于取模值也发生变化,会自动切换队列; 9.producer发送消息时支持同步返回、异步返回和oneway三种方式; 10.broker保证每条消息至少投递到consumer一次,因此consumer的业务需要支持幂等; 11.消息堆积能力惊人,消息队列的一个作用便是防止洪峰直接冲垮后端业务; 12.支持按照消息id和消息key来查询消息,本人很喜欢按照key来查询消息这个功能,例如在下单业务中,可以使用订单id作为key,便于分析异常订单在系统中的处理过程; 13.支持消息过滤; ...

RocketMQ的技术概览 在我们看来,它最大的创新点在于能够通过精巧的横向、纵向扩展,不断满足与日俱增的海量消息在高吞吐、高可靠、低延迟方面的要求。 目前RocketMQ主要由NameServer、Broker、Producer以及Consumer四部分构成,如下图所示。

所有的集群都具有水平扩展能力,无单点障碍。 NameServer 以轻量级的方式提供服务发现和路由功能,每个NameServer存有全量的路由信息,提供对等的读写服务,支持快速扩缩容。 Broker 负责消息存储,以Topic为纬度支持轻量级的队列,单机可以支撑上万队列规模,支持消息推拉模型,具备多副本容错机制(2副本或3副本)、强大的削峰填谷以及上亿级消息堆积能力,同时可严格保证消息的有序性。除此之外,Broker还提供了同城异地容灾能力,丰富的Metrics统计以及告警机制。这些都是传统消息系统无法比拟的。 Producer 由用户进行分布式部署,消息由Producer通过多种负载均衡模式发送到Broker集群,发送低延时,支持快速失败。 Consumer 也由用户部署,支持PUSH和PULL两种消费模式,支持集群消费和广播消息,提供实时的消息订阅机制,满足大多数消费场景。

Namesrv组件 ● KVConfigManager:KV配置管理 ○ key-value配置管理,增删改查 ● RouteInfoManager:路由信息管理 ○ 注册Broker,提供Broker信息(名字、角色编号、地址、集群名) ○ 注册Topic,提供Topic信息(Topic名、读写权限、队列情况)

2、Producer 发送消息

转载于:https://my.oschina.net/u/3656642/blog/1580359

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值