为什么要引入MQ?
如下图所示,在一个订单系统中,一笔订单会引发几百个下游业务的关注,包括购物车、下单、库存、积分、评价等,如果订单系统直接和这些相关子业务进行交互,这个交互过程中的数据是无比庞大的,架构设计稍有不慎或者出现一些其它宕机行为,将会影响到整个业务的连续性。另外,这种模式的耦合性也非常高,增加一个下游业务,很可能会影响到其他业务的正常使用
此时引入MQ的概念无疑是个明智之举,订单系统将需要消费的数据存放在MQ中,无需关注MQ中的消息是否被消费了,下游业务从MQ中提取出需要消费的消息进行消费处理,消费者之间对消息的消费互不干扰或者干扰性非常低,即使引入新的业务模块,对于其它业务来说,影响也是非常小的,这样极大地降低了业务模块之间的耦合性,也大大提高了数据处理的速度,减轻服务器的压力
MQ的适用场景:秒杀、抢红包、数据一致性要求极高的业务(银行存储)等
目前比较常用的几种消息中间件:RabbitMQ、RocketMQ、Kafka
从上图可看出,kafka和RocketMQ在各种性能上相比较RabbitMQ更胜出,相比较kafka的吞吐量百万级别,RocketMQ的吞吐量虽然仅达到了十万级别,但是对于目前国内存在的系统已经足够使用了,并且RocketMQ还支持定时消息、事务消息、消息重试、死信队列等等
RocketMQ:
消息队列RocketMQ基于高可用分布式集群技术,提供消息订阅和发布、消息轨迹查询以及定时(延时)消息等一系列消息服务,为分布式应用系统提供异步解耦、削峰填谷的能力,它同时具备海量消息堆积、高吞吐、可靠重试等互联网所需的特性:
- 集群消息:一个Group ID 所标识的所有Consumer平均分摊消费信息
- 广播消息:允许一个Group ID 所标识的所有consumer都各自消费某条消息一次
- 顺序消息:允许消息消费者按照消息发送的顺序对消息进行消费
- 事务消息:达到事务最终一致性状态
- 定时消息:允许消息生产者指定消息进行定时投递,最长支持40天
- 消息轨迹:通过消息轨迹,定位出消息从发布者发出,经由消息队列RocketMQ服务器,投递给消息订阅者的完整链路,方便定位排查问题
- 重置消费进度:根据时间重置消费进度,允许用户进行消息回溯或者丢弃堆积消息
- 死信队列:将无法正常消费的消息存储到特殊的死信队列供后续处理
- 大消息:支持最大4MB消息
RocketMQ的消费流程
- Name Server 名称注册服务器:充当路由提供者,负责存储Broker Server 注册的IP地址,生产者或者消费者通过名称查找到相应的Broker Server 的IP,进而连接上Broker Server
- Broker Server 代理服务:消息中转角色,负责消息的存储和发送。接收RocketMQ中生产者产生的消息,并进行存储,为消费者发出请求调用消息做准备,也会存储消息的元数据,包括包括消费者组、消费进度偏移和主题和队列消息等
- Productor 生产者:负责消息的生产,一般是业务系统,在业务应用系统产生消息后,将相应的消息发送到Broker中,一般有三种发送方式:异步发送、同步发送、单向发送
可靠同步发送:消息生产者向服务器发送消息,服务器接收到消息后回复,消息生产者再发送消息
可靠异步发送:消息生产者向服务器发送消息,不需要等待服务器响应后发送消息,可直接再次发送消息
单向发送:消息生产者只给服务器发送消息,服务器无需响应
- Consumer 消费者:负责消费消息,主要是后台系统,从Broker中提取消息发送到应用程序进行使用。
- Topic 消息主题:表示一类消息的集合,一个主题包含若干条消息,一条消息只能属于某个主题,是消息订阅的基本单位
- Tag 标志:用来区分一个topic下的不同消息,来源于同一个业务单元的消息可根据不同的业务场景在一个topic下设置不同的tag进行标志
- MessageQueue 消息队列:对于每个Topic都可以设置一定数量的消息队列用来进行数据的读取
RocketMQ集群部署结构:
RocketMQ消费流程:
RockerMQ消费模式:
集群模式(默认):一条消息只能被消费一次
广播模式:一条消息可被多个服务进行消费
RocketMQ消费方式:
推动消费:消费者在线,生产者生产消息后,消费者自动获取消息
抽取消费:当生产者生产消息后,消费者启动,自动获取未被消费的信息
两种消息类型:
定时消息:在之后的某一个特定时间投递消息
延时消息:当前时刻延迟一定时间后投递消息
RocketMQ管理工具:
1.开源web控制台(RocketMQ Console):支持topic管理、生产者管理、消费者管理、消息查询、消息轨迹展示和查询
2.OpenAPI:提供API便于将消息队列RocketMQ管理工具集成到自己的控制台
3.mqadmin:提供一套丰富的管理命令集,以命令方式对消息队列RocketMQ服务进行管理
重试队列:1、如果Consumer端因为各种类型异常导致本次消费失败,为防止该消息丢失而需要将其重新回发给Broker端保存,保存这种因为异常无法正常消费而回发给MQ的消息队列称之为重试队列
2、%RETRY%+consumerGroup
死信队列:1、由于有些原因导致Consumer端长时间的无法正常消费从Broker端Pull过来的业务消息,为了确保消息不会被无故的丢弃,那么超过配置的“最大重试消费次数”后就会移入到这个死信队列中
2、%DLQ%+consumerGroup
RocketMQ应用场景:
- 系统间异步解耦
- 分布式事务(事务消息)
- IM实时通信
- 实时计算分析(数据收集)
- 流量削峰(大促期间减少服务器压力)
- 大规模机器缓存同步(利用广播消费机制)
- 日志服务
测试关注点:
1、消息是否正确推送到预期队列中
2、消息是否推送到正确的topic下
3、重复发送同一条消息是否被接收
4、消息发送数量超过队列总长度是数据的处理方法
5、消息推送到每个topic下的queue如何分布
1、消费者消费模式是否与预期相符
2、消费者是否从预期队列中消费数据
3、消费者设定的topic的消费队列策略
4、消息被消费后是否被及时删除(看是否允许重复消费)
5、消费消息数量赶不上消息生产速度情况
6、pull与push消费类型测试
1、不同MQ对消息的持久化方式不一样
1、Broker正常关闭
2、订阅与广播消息的消费是否符合预期
3、集群中任何一个节点故障情况