文章目录
一、rocketmq作用
流量削峰:延时消费
数据采集:日志等数据的采集
异步解耦:系统之间解耦
二、rocketmq工作原理
消息的生产
路由表:实际是一个map,Key为topic名称,value是一个QueueData列表。简单说,路由表的key为topic名称,value为所有涉及该topic的BrokerName列表。
三、rocketmq的应用
发送消息
发送消息的三种方式
同步发送
异步发送
需要指定一个回调函数
单向发送:只发不收,效率最高,可靠性差
消息发送的四种状态
SEND_OK 发送成功
FLUSH_DISK_TIMEOUT 刷盘超时 刷盘策略为同步才会出现
FLUSH_SLAVE_TIMEOUT 主从同步超时 master-slave模式下才会出现
SLAVE_NOT_AVAILABLE 没有可用的从机 master-slave模式下才会出现
消费消息
消息消费者举例
消息消费的方式
广播模式
所有consumer都消费全部的消息
集群模式
每个consumer只消费自己需要的消息(默认模式)
顺序消费
问题描述
默认情况下,生产者会把消息以RoundRobin轮询方式发送到不同的queue分区队列;而消费消息时会从多个queue上拉取消息,这种情况下,生产和消费的顺序就得不到保证了。如果只将消息生产到一个队列,然后消费也只从一个队列取消息消费,则可以保证顺序。
有序分类
全局有序
当发送和消费参与的queue只有一个时,保证的有序是整个topic的有序,称为全局有序。
也就是一个topic只有一个queue。
分区有序
如果有多个queue参与,其仅可保证在该分区队列queue上的有序性,称为分区有序。
如何实现queue的选择
在定义Producer时我们可以指定消息队列选择器,而这个选择器是我们自己实现了MessageQueueSelector接口定义的。
在定义选择器的选择算法时,一般需要使用选择key。这个选择key可以是消息key,也可以是其他数据,但必须是唯一的。
一般性的选择算法是,让选择key(或其hash值)与该topic所包含的queue数量取模,其结果即为选择的Queue的QueueId。 一般性的作法是,从消息中获取到选择key,对其进行判断,若是当前Consumer需要消费的消息,则消费,不是则不做处理。
不属于那个Consumer的消息被拉取走了,那么应该消费这条消息的Consumer还能否拿到这条消息吗?同一个Queue中的消息,不可能被同一个Group中的不同Consumer消费。所以消费同一个Queue的不同选择key的消息的Consumer一定属于不同的Group,而不同的Group中的Consumer之间的消费是相互隔离的,互不影响的。
示例
producer:
rocketmq如何保证有序总结
首先单个分区(queue)是有序的,但多个分区,就无法保证consumer能顺序去取消息消费。此时需要在生产者的生产消息上加一个选择器selector,(此处举例订单号)对订单号取模投放分区,就能保证同一个订单的相关消息都投送到同一个分区,同一个分区的消息是有序的,所以此时consumer去消费就是有序的了。
如果consumer是集群分布的,那么就会有多个一样的consumer去消费同一个分区,此时就需要对分区加锁,来保证同时只能有一个consumer进入分区消费。
延时消费
概念
当消息写入到broker后,在经过指定时长后才会被消费的消息,称为延时消息。
采用rocketMQ的延时消息实现定时任务的功能,而无需使用定时器。典型的应用场景是,电商交易中超时未支付关闭的场景,12306订单超时未支付取消订票的场景。
在电商平台中,订单创建会发送一条延时消息,在30分钟后去后台业务系统(consumer),如果该条订单已经关闭,则不做处理;如果未关闭(未完成支付),则商品返回库存,关闭订单。
延时等级
延时消息的延时时长并不支持任意时长的延迟,而是按照等级划分的。延时等级定义在rocketMQ服务端的MessageStoreConfig类中。
即延时等级为1代表1s,延时等级为3代表10s
延时消息producer举例
与普通发送消息的区别就是加了一个延时等级。
事务消息
一个场景的解决方案
在这样一个场景中,如果1,2,3步都成功,也就是工行系统已经成功扣款后,而5失败了,那A用户已经少了钱,而B用户没有加钱,是否就会出现数据不一致呢?
此时就需要事务消息了。
基础概念
分布式事务
事务消息
RocketMQ提供了类似X/Open XA的分布式事务功能,通过事务消息能达到分布式事务的最终一致。XA是一种分布式事务的解决方案,一种分布式事务处理模式。
半事务消息
暂不能投递的消息,发送方已经成功将消息发给了broker,但是broker没有收到最终确认指令,此时该消息被标记为“暂不能投递”状态,即不能被消费者看到。处于该种状态下的消息称为“半事务消息”。
消息回查
消息回查,即重新查询本地事务的执行状态,本例就是重新到DB中查看预扣款操作是否成功。
XA模式三剑客
XA是一种分布式事务解决方案,分布式事务处理模式,基于XA协议。
XA中有三个重要组件:TC,TM,RM
TC
Transaction Coordinator,事务协调者。维护全局和分支事务的状态,驱动全局事务提交或回滚。
RocketMQ中broker充当着TC
TM
Transaction Manager,事务管理器。定义全局事务的范围,开始全局事务,提交或回滚全局事务。它实际是全局事务的发起者。
RocketMQ中producer充当着TM
RM
Resource Manager,资源管理器。管理分支事务处理的资源,驱动分支事务的注册和回滚。
RocketMQ中broker和producer均是RM
XA模式架构
执行原理
- TM向TC发起指令,开启一个全局事务
- 根据业务要求,RM会逐个向TC注册分支事务,TC会逐个向RM发送预执行指令
- RM在接收到预执行指令后,会在进行本地事务预执行
- RM将预执行结果返回给TC,当然可能成功也可能失败
- TC在接收到各个RM的预执行结果后,汇总给TM,TM根据汇总结果给TC下达指令。如果各个RM的预执行结果都成功,则发送global commit指令,如果有一个失败,则发送global rollback
- TC在接受到指令后,再次向RM发送确认指令
**注意:
- 事务消息不支持延时
- 事务消息要做好幂等性,因为事务消息可能不止一次被消费(因为存在回滚后再提交的情况)
代码示例
事务监听器: