Rocketmq整体分析
之前本人在实际的生产环境中,使用过activemq和rabbitmq消息队列,在使用过程中出现一些难以解决的问题,本文通过产品选型、网络架构和核心特性分析了rocketmq的优势和特性。
产品选型
我们在进行中间件选型时,一般都是通过下面几点来进行产品选型的:
1.性能
2.功能支持程度
3.开发语言(团队中是否有成员熟悉此中间件的开发语言,市场上此种语言的开发人员是否好招)
4.有多少公司已经在生产环境上实际使用过,使用的效果如何
5.社区的支持力度如何
6.中间件的学习程度是否简单、文档是否详尽
7.稳定性
8.集群功能是否完备
...
如果从以上8点来选型一个消息队列,作为一名熟悉java的程序员,当遇到重新选择消息队列的场景时,我会毫不犹豫的选型rocketmq,rocketmq除了在第5点上表现略差(文档少,学习成本高)以及监控管理功能不友好外,从其它方面来说,它真的是一款非常优秀的消息队列中间件。
网络架构

(图片来源于官方文档)
rocketmq的主要部分是由4种集群构成的:namesrv集群、broker集群、producer集群和consumer集群。
namesrv集群:也就是注册中心,rocketmq在注册中心这块没有使用第三方的中间件,而是自己写的代码来实现的,代码行数才1000行,producer、broker和consumer在启动时都需要向namesrv进行注册,namesrv服务之间不通讯。
broker集群:broker提供关于消息的管理、存储、分发等功能,是消息队列的核心组件。rocket关于broker的集群提供了主要两种方案,一种是主从同步方案,消息同时写到master和slave服务器视为消息发送成功;另一种是异步方案,slave的异步服务负责读取master的数据,本人在选择时更倾向于异步方案。
producer集群:消息的生产者,每个producer都需要属于一个group,producer的group概念除了在事务消息时起到一些作用,但是其它时候,更多的还只是一个虚拟的概念。
consumer集群:消息的消费者,有两个主要的consumer:DefaultMQPullConsumer和DefaultMQPushConsumer,深入代码后可以发现,rocket的consumer都是采用的pull模式来处理消息的。在集群消息的配置下,集群内各个服务平均分配消息,当其中一台consumer宕机,分配给它的消息会继续分配给其它的consumer。
核心特性
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整体分析
原文:https://www.cnblogs.com/mantu/p/6108645.html 之前本人在实际的生产环境中,使用过activemq和rabbitmq消息队列,在使用过程中出现一些难以解 ...
- MQ选型对比
现公司选择RocketMQ作为消息队列服务器,用于异步处理,应用解耦,流量削锋和消息通讯四个场景.RocketMQ特性参见:Rocketmq整体分析. PS: http://blog.csdn.net ...
- RocketMQ原理解析-Remoting
Remoting2. 通信层底层传输协议 RocketMq服务器与客户端通过传递RemotingCommand来交互,通过NettyDecoder,对RemotingCommand进行协议的编码与解码 ...
- RocketMQ原理解析-Broker
broker 1. broker的启动 brker的启动 Broker向namesrv注册 1. 获取namesrv的地址列表(是乱序的) 2. 遍历向每个namesrv注册topic的配置信息top ...
- RocketMQ原理解析-Consumer
consumer 1.启动 有别于其他消息中间件由broker做负载均衡并主动向consumer投递消息,RocketMq是基于拉模式拉取消息,consumer做负载均衡并通过长轮询向broker拉消 ...
- RocketMQ原理解析-Producer
producer producer 1.启动流程 Producer如何感知要发送消息的broker即brokerAddrTable中的值是怎么获得的, 1. 发送消息的时候指定会指定topic,如果 ...
- 分布式开放消息系统(RocketMQ)的原理与实践
分布式消息系统作为实现分布式系统可扩展.可伸缩性的关键组件,需要具有高吞吐量.高可用等特点.而谈到消息系统的设计,就回避不了两个问题: 消息的顺序问题 消息的重复问题 RocketMQ作为阿里开源的一 ...
- rocketmq生产者和消费者
1.生产者: package com.ebways.mq.test.mq; import com.alibaba.rocketmq.client.exception.MQClientException ...
- rocketmq查看命令
首先进入 RocketMQ 工程,进入/RocketMQ/bin 在该目录下有个 mqadmin 脚本 . 查看帮助: 在 mqadmin 下可以查看有哪些命令 a: 查看具体命令的使 ...
随机推荐
- 获取C++类成员变量的地址偏移
今天有在校学生问怎么获取类中的成员变量的地址偏移量,这个应该是很多初学C++的人很好奇的问题.以前我在学校的时候,也有过这种需求.忘了当时是要写什么“奇怪的程序”了,反正需要获取一个类的成员变量的地址 ...
- Java 可变参数
java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理.注意:可变参数必须位于最后一项.当可变参数个数多余一个时,必将有一个不是最后一项,所以只支持 ...
- CSS负边距自适应布局三例
单列定宽单列自适应布局: <!DOCTYPE HTML> <html> <head> <meta charset=”UTF-8″> <title& ...
- OC学习总结之面向对象和类
OC学习总结之面向对象和类 Objective-c是c语言的母集合,它的原意就是在原始的c语言的主体上加入面向对象的特性.1.面向对象和面向过程 面向对象和面向过程是编程的两种思考方式.面向对象 ...
- Zephyr-开发流程
开发流程 前提1:检查你的Linux主机满足入门指南中规定的最低要求. 具体请参考 : 物联网操作系统-Zephyr 前提2: 确保SDK的环境变量和zephyr项目的环境变量. 终端执行: $ e ...
- ps中常用的快捷键
ctrl+c 复制 ctrl+v 粘贴 ctrl+n 新建文件 ctrl+s 保存 空格键 手抓工具 ctrl+t 自由变形 ctrl+加号 放大 ctrl+减号 缩小 ctrl+r 标 ...
- while死循环问题-输入字符就会死循环
问题: 是否会遇到这样的问题,在while循环中 sanf("%d",&a);如果输入的不是数字,是字符就会进入死循环. 解决方案:都是缓冲区惹的祸,输入字符后,字符会一直 ...
- 求解:远程方法调用失败Exception from HRESULT: 0x800706BE)
服务器:Windows Server2003 sp2服务器 客户端:XP SP3 内容:C#Winform客户端调用服务器的Excel模板生成报表的时候,生成失败,抛出的异常如下: TargetInv ...
- Node.js事件循环
Node JS是单线程应用程序,但它通过事件和回调概念,支持并发. 由于Node JS每一个API是异步的,作为一个单独的线程,它使用异步函数调用,以保持并发性.Node JS使用观察者模式.Node ...
- [BZOJ 2007] [Noi2010] 海拔 【平面图最小割(对偶图最短路)】
题目链接:BZOJ - 2007 题目分析 首先,左上角的高度是 0 ,右下角的高度是 1.那么所有点的高度一定要在 0 与 1 之间.然而选取 [0, 1] 的任何一个实数,都可以用整数 0 或 1 ...