队列mq 相关

1. 队列相关

什么是消息队列

消息队列是一种异步的通信方式, 用于在分布式系统中管理消息传递。
采用了生产者消费者模式,生产者将消息发送到队列,消费者负责从队列接收消息

队列的好处

使用队列的核心好处主要有3个,分别是 解耦、异步和削峰

2. rocket 相关

2.1 rocket mq 如何做到消息不丢失

1. 刷盘机制 
rocketMq 中的消息分为内存消息和磁盘消息,内存消息在broker 内存中进行读写,磁盘消息则保存在磁盘上
rocket 支持同步刷盘和异步刷盘两种,通过刷盘机制可以确保broker 宕机时数据不会丢失. 
在同步刷盘模式下,消息写入磁盘会等待磁盘的写入完成才返回写入成功的响应
在异步刷盘模式下,消息写入磁盘后立即返回写入成功的响应,但是不等待磁盘写入完成
2. ACK机制
在 rocketMq 中, producer 发送消息后,broker会返回ACK确认信号,表示消息已经发送成功,如果broker 没有收到确认信号,就会尝试重新发送该消息,直到消息被确认为止
rockerMq 采用主动复制机制,每个消息队列都有一个主节点和多个从节点,主节点负责消息的写入和读取,从节点负责备份数据,当主节点宕机时,从节点会自动接管主节点的工组,确保消息不会丢失
3. 消息存储机制
rocketMq 默认使用双写模式来存储消息,即将消息同时写入内存和磁盘中,然后再将内存中的消息异步刷盘到磁盘中,这种方式可以保证消息的可靠性,即时系统宕机,也能够尽可能的保证消息不会丢失
除此之外,rocketmq 还提供了多种机制来保证消息不丢失,如事务消息,延迟消息,顺序消息等
为了确保消息的可靠性,rocketMq 的发送消息的速度可能会受到一定的限制,需要在消息的可靠性和西能之间进行权衡

2.2 rocket mq 消息如何存储

1. rocket 的消息存储主要涉及了四个部分, 消息存储文件,消息索引,文件组织管理以及数据结构
2. 首先是消息存储文件, rocket 主要使用commitLog 文件来存储实际的消息数据, commitLog 是顺序写的文件,可大大提高写入性能
3. 为了快速查找消息,rocketmq 使用了consumerQueue 和 indexFile 两种索引文件, consumerQueue 是基于Topic和Queue 纬度的索引, 存储了消息在commitLog 中的偏移量等信息, indexFile 则是基于消息key的索引,方便根据key 来快速查找消息
4. rocketMq 采用固定大小的文件存储方式,当一个文件写满后,会创建新的文件继续写入,同时会有后台线程定期清理过期或不在使用的文件,以释放存储空间
5. 在存储消息时,会使用特定的数据结构来优化存储和读取效率,例如采用字节数组来存储消息内容

当一条消息发送到rocketMq 时,它首先被顺序写入到commitLog 文件中,同时相关的索引信息会被更新到对应的ConsumerQueue 和可能的indexFile 中,
当消费者需要获取消息时,先通过consumerQueue 快速定位消息在commitLog 中的位置,然后从commitLog 中读取具体的消息内容, 通过这种方式,rocketMq 能够保证在高性能写入的同时,提供高效的消息查询和消费功能

2.3 rocket Mq 如何保证消息顺序

1. 生产者将要保证顺序的消息发送到同一个messageQueue 中,通过特定的路由策略,会将具有顺序关联的消息路由到同一个队列
2. messageQueue 中的消息,是按照发送的先后顺序进行存储的
3. 消费者在消费指定的messageQueue时,采用单线程顺序消费的方式,确保同一个messageQueue 中的消息按照发送顺序被处理

2.4 消息大量积压怎么解决

1. 当消息出现大量积压时,首先需要检查消费者,确认消费者是否正常启动运行,查看消费者日志,是否报错或者异常,消费逻辑上是否存在缓慢、死循环或者其他逻辑问题
2. 对比正常情况下的消费速度和当前的消费速度,是否有明显的下降,检查消费者的配置,例如线程数、批量消费大小是否合理
3. 检查生产者的发送速度是否异常增加,查看生产者的日志是否有发送失败或者重试记录
4. 监控 Broker 资源,查看所在服务器的cpu、内存、网络、磁盘IO等资源的使用情况,是否存在资源瓶颈,检查broker 的配置,如内存,存储等是否满足业务需求
5. 确定哪些队列中的消息出现了积压,分析这些队列对应的主题和业务,是否存在异常的流量模式
6. 

3. rocket 的使用

3.1 rocket 生产者

1. 创建一个common 类, 引入rocket 相关依赖(rocketMq-springboot),
2. 创建 MqProduceService 类, 主要用于统一发送消息的格式, 不需要关注mqTemplate
3. 针对需要使用mq 的项目,引入 common-mq 依赖, 同时配置其所需信息, 如 name-server、producer.group 等
4. 针对需要发送的消息,直接调用mqProduceService 进行消息发送,需要指定其 topic 与 tag , 同时topic 应当与消费者的topic 以及 tag 相同

3.2 rocket消费者

1. 引入 common-mq 依赖,配置name-server 地址
2. 创建一个component 类, 实现RockerMQListener , 重写 onMessage 方法 ,同时在类上添加 @RocketMQMessageListener 注解,同时指定其topic 以及 consumerGroup 
3. 在配置文件中, 通过consumer.listeners 来配置对某个消费分组的监听, 是否监听指定的topic, 不配置默认监听

3.3 rocket 事务消息

事务消息主要分为两个流程
1. 生产者发送半消息到broker 服务端
2. broker 服务端将消息持久化之后,给生产者响应写入结果, 即ack 响应
3. 生产者根据发送结果执行本地事务逻辑, 如果写入失败, 此时半消息对业务不可见,本地逻辑不执行
4. 生产者根据本地事务执行结果向broker 服务端提交二次确认(commit 或者 rollback), broker 服务端收到commit 状态将半事务消息标记为可投递, 订阅方最终收到该消息,broker 服务端收到rollback 状态则删除该半事务消息,订阅方将不会接受该消息
5. 在网络闪断或者应用重启的情况下,可能会导致生产者发送的二次确认消息未能到达broker服务端, 经过固定时间后, broker 服务端会对没有commit/rollback 的事务消息进行回查
6. 生产者收到回查消息后,检查回查消息对应的本地事务执行的最终结果
7. 生产者根基本地事务状态,再次提交二次确认给broker ,然后Broker 重新对半事务消息commit或者rollback

3.3.1 rocket 事务消息的使用

1. 需要定义事务消息监听器, 实现transactionListener 接口,重写 执行本地事务接口以及回查本地事务状态接口
2. 创建事务类型的生产者 transactionMqProducer ,调用其setTransactionListener 设置事务监听器,使用sendMessageInTransaction 方法以事务方式发送消息
3. 创建事务类型的消费者,用于处理后续事务消息,以保证事务的最终一致性,对于事务半消息, 明确回滚的,不会被消费者所消费, 即被消费者消费的消息都是本地事务成功的消息

posted on   antor  阅读(16)  评论(0编辑  收藏  举报

点击右上角即可分享
微信分享提示