您好,登录后才能下订单哦!
今天就跟大家聊聊有关rocketmq中专业术语、消息队列需要解决的问题,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
Producer: 消息生产者,负责产生消息,一般由业务系统负责产生消息
Consumer: 消息消费者,负责消费消息,一般是后台系统负责异步消费
Push Consumer:
Consumer的一种,应用通常向Consumer对象注册一个Listener接口,一旦收到消息,Consumer对象立刻回调Listener接口方法
Pull Consumer:
Consumer的一种,通常主动调用Consumer的拉消息方法从broker拉消息,主动权由应用控制
Producer Group:
一类Producer的集合名称,这类Producer通常发送一类消息,且发送逻辑一致
Consumer Group:
一类Consumer的集合名称,这类Consumer通常发送一类消息,且发送逻辑一致
Broker:
消息中转角色,负责存储消息,转发消息,一般也称为Server。在JMS规范中称为Provider
广播消费:
一条消息被多个Consumer消费,即使这些Consumer属于同一个Consumer Group,消息也会被Consumer Group中的每个Consumer都被消费一次,广播消费中的Consumer Group概念可以认为在消息 划分方面无意义。 在CORBA Notification规范中,消费方式都属于广播消费 在JMS规范中,相当于JMS publish/subscribe model
集群消费:
一个Consumer Group中的实例平均分摊消费消息。例如某个topic有9条消息,其中一个Consumer Group有3个实例(可能是三个进程或者3台机器),那么每个实例只能消费其中3条消息
顺序消息:
消费消息的顺序要同发送消息的顺序一致,在RocketMq中,主要指的是局部顺序,即一类消息为满足顺序性,必须Producer单线程顺序发送,且发送到同一个队列,这样Consumer就可以按照 Producer发送的顺序去消费消息。
普通顺序消息:
顺序消息的一种,正常情况下可以保证完全的顺序消息,但是一旦发生通信异常,Broker重启,由于队列总数发生变化,哈希取模后定位的队列会变化,产生短暂的消息队列顺序不一致。
如果业务能容忍在集群异常情况(如某个Broker宕机或者重启)下,消息短暂的乱序,使用普通顺内需方式比较合适。
严格顺序消息:
顺序消息的一种,无论正常异常情况都能保证顺序,但是牺牲了分布式FailOver特性,即Broker集群中要有一台机器不可用,则整个集群都不可用,服务可用性大大降低
如果服务器部署为同步双写模式,此缺陷可通过备机自动切换为主避免,不过仍然会存在几分钟服务不可用。(依赖同步双写,主备自动切换,自动切换功能还未实现) 目前已知的应用只有数据库binlog同步强依赖严格顺序消息,其他应用绝大部分都可以容忍短暂乱序,推荐使用普通顺序消息。
Message Queue
在RocketMq中,所有消息队列都是持久化,长度无限的数据结构,所谓长度无限是指队列中的每个存储单元都是定长,访问其中的存储单元使用offset来访问,offset为java long类型,64位,理论上在100年 内不会溢出,所以认为长度无限,另外队列中只保存最近几天的数据,之前的数据会按照过期时间来删除。 也可以认为Message Queue是一个长度无限的数组,offset就是下标。
发布订阅消息是消息中间件的最基本的功能,也是相对于传统的RPC而言
规范中描述的优先级是指在一个消息队列中,每条消息都有不同的优先级,一般用整数来描述,优先级高的消息先投递,如果消息完全在一个内存队列中,那么在投递前可以按照优先级排序,令优先级高的先投递。 由于Rocketmq所有消息都是持久化的,所以如果按照优先级来排序,开销会非常大,因此RocketMq没有特意支持消息优先级,但是可以通过变通的方式实现类似功能,即单独配置一个优先级高的队列,和一个普通 优先级的队列,将不同优先级发送到不同的队列即可。 对于优先级问题可以归纳为2类:
1)只要达到优先级目的即可,不是严格意义上的优先级,通常将优先级划分为高、中、低,或者再多几个级别。每个优先级可以用不同的topic表示,指定不同topic来表示优先级,这种方式可以解决一部分优先级问题, 但是对业务的优先级精确性做了妥协。
2)严格的优先级,优先级用整数表示,例如:0~65535,这种优先级问题一般使用不同topic解决就非常不合适。如果让MQ解决此问题,会对MQ性能造成非常大的影响。这里要确保一点,业务上是否需要这种严格的优先级, 如果将优先级压缩成几个,对业务影响有多大?
消息有序指的是一类消息消费时,能按照发送顺序来消费。例如:一个订单产生了3条消息,分别是订单创建,订单付款,订单完成。消费时,要按照这个顺序消费才能有意义。但是同时订单之间是可以并行消费的。 RocketMq可以严格的保证消息有序。
Broker端消息过滤: 在Broker中,按照Consumer的要求做过滤,优点是减少了对于Consumer无用消息的网络传输。缺点是增加了Broker的负担,实现相对复杂
1)淘宝Notify支持多种过滤方式,包含按照消息类型过滤,灵活的语法表达式过滤
2)淘宝RocketMQ支持按照简单的MessageTag过滤,也支持按照Message Header、body进行过滤
消息中间件通常采用的几种持久化方式:
1)持久化到数据库,例如mysql
2)持久化到kv存储,例如levelDB、伯克利DB等kv存储系统
3)文件记录形式持久化,例如kafka,rocketmq
4) 对内存数据做一个持丽化镜像,例如 beanstalkd,VisiNotify
1)2)3)三种持久方式都具有将内存队列Buffer进行扩展的能力,4)只是一个内存镜像,作用是当broker挂掉重启后仍然能将之前内存的数据恢复出来
Rocketmq参考了kafka的持久化方式,充分利用Linux文件系统内存cache提高性能
影响消息可靠性的几种情况: (1) Broker 正常关闭
(2) Broker 异常 Crash(崩溃)
(3) OS Crash
(4) 机器掉电,但是能立即恢复供电情况。
(5) 机器无法开机(可能是cpu、主板、内存等关键设备损坏)
(6) 磁盘设备损坏。
1)2)3)4)四种情况都属于硬件资源可立即恢复情况,Rocketmq在这四种情况下能保证消息不丢,后者丢失少量数据(依赖刷盘方式是同步还是异步)
5)6)属于单点故障,且无法恢复,一旦发生,在此单点上的消息全部丢失。RocketMQ在这两种情况下,通过异步复制,可保证99%的消息不丢,但是仍然会有极少量的消息可能丢失,通过同步双写技术可以避免单点,同步双写势必会影响性能,适合对消息可靠性要求极高的场合,例如与Money相关的应用。
rocketmq3.0版本支持同步双写
如果在消息没有堆积的情况下,在消息到大broker后,立刻到达Consumer Rocketmq使用长轮询Pull方式,可保证消息非常实时,消息实时性不低于Push
每个消息必须投递一次。RocketMq Consumer先pull消息到本地,消费完成后,才向服务器返回ack,如果没有消费一定不回ack消息,所以Rocket MQ很好的支持此特性
1)发送消息阶段,不允许发送重复的消息
2)消费消息阶段,不允许消费重复的消息
要实现这两点,在分布式系统环境下,不可避免要产生巨大的开销,所以Rocketmq不保证此特性,要求在业务上进行去重,也就是要消费消息做到幂等。
虽然rocketmq不能严格保证不重复,但是正常情况下很少会出现重复推送、消费情况,只有网络异常,Consumer启停等异常情况下会出现消费重复。 此问题的本质原因是网络调用存在不确定性,即既不成功也不失败的第三种状态,所以才产生了消息重复性问题。
Rocketmq中没有内存buffer概念,rocketmq的队列都是持久化磁盘,数据定期清除。
对于此问题解决思路,rocketmq与其他mq不同,rocketmq的内buffer抽象成一个无限长度的队列,不管有多少数据来都能装的下,这个无限是有前提的,broker会定期删除过期的数据。例如brokr只保存3天,那么这个buffer虽然长度无限,但是3天前的数据会被从队尾删除。
回溯消费是指consumer已经消费成功的消息,由于业务上的需求需要重新消费。要支持此功能,broker再向consumer投递成功消息后,消息仍然要保留,并且重新消费一般是按照时间维度。
RocketMQ支持按照时间回溯消费,时间维度精确到毫秒,可以向前回溯,也可以向后回溯。
消息中间件的主要功能是异步解耦,迓有个重要功能是挡住前端的数据洪峰,保证后端系统的稳定性,这就要求消息中间件具有一定的消息堆积能力,消息堆积分以下两种情况:
(1)消息堆积在内存Buffer,一旦超过内存 Buffer,可以根据一定的丢弃策略来丢弃消息,如 CORBA Notification 规范中描述。适合能容忍丢弃消息的业务,这种情况消息的堆积能力主要在于内存 Buffer 大小,而且消息堆积后,性能下降不会太大,因为内存中数据多少对于对外提供的访问能力影响有限。
(2)消息堆积到持久化存储系统中,例如DB,KV存储,文件记录形式。对于消息不能在内存 Cache 命中时,要不可避免的访问磁盘,会产生大量读 IO,读 IO 的吞吐量直接决定了消息堆积后的访问能力。
评估消息堆积能力主要有以下四点:
(1). 消息能堆积多少条,多少字节?即消息的堆积容量。
(2). 消息堆积后,发消息的吞吐量大小,是否会受堆积影响?
(3). 消息堆积后,正常消费的Consumer是否会受影响?
(4). 消息堆积后,访问堆积在磁盘的消息时,吞吏量有多大?
已知的几个分布式事务规范,如:XA,JTA。其中XA规范被各大数据库厂商广泛支持。如:Orcal、Mysql等。
XA 是一个两阶段提交协议,该协议分为以下两个阶段: 第一阶段:事务协调器要求每个涉及到事务的数据库预提交(precommit)此操作,并反映是否可以提交.
第二阶段:事务协调器要求每个数据库提交数据。 Rocketmq实现事务的方式没有通过kv存储,而是通过offset方式来访问消息。存在一个显著缺陷,就是用过offset更改数据,会令系统的脏页过多,需要特别的关注。
定时消息是指消息发送到broker后,不能立刻被Conusmer消费,要到特定的时间点或者等待特定的时间后才能被消费。 Rocketmq支持定时消息,但是不自持任意时间精度,支持特定的level,例如定时5s,10s,1m等。
Consumer消费消息失败后,要提供一种重试机制,令消息再消费一次。 消费消息失败通常认为有以下几种情况:
1)由于消息本身原因,例如反序列化失败,消息数据本身无法处理。这种错误通常需要跳过这条消息,再消费其他消息,而这条失败的消息即使立刻重试消费,99%也不成功所以最好提供一种定时重试机制,即过10s后再重试
2)由于依赖的下游应用服务不可用,例如:db连接不可用,外系网络不可达等。遇到这种情况,即使跳过当前失败的消息,消费其他消息同样也会报错。这种情况建议sleep 30秒再消费下一条消息,这样减轻broker重试消息的压力。
看完上述内容,你们对rocketmq中专业术语、消息队列需要解决的问题有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。