「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」
消息队列
Q:消息队列的应用场景
通过MQ进行 数据分发 ,提高系统处理性能
- 订阅模式-关注一件商品的价格,价格变动通知点击关注了的用户;
- 相当于分布式事务的事务补偿,当订单确认出错,回滚库存和订单状态;
Q:消息队列的模型
三者都注册到类似于注册中心的 nameserver
消息生产者 --> broker --> 消息消费者
broker相当于邮局,所有的消息都要经过这个组件!!
-
broker结构
-
- topic主题,用来区分消息种类吧
-
-
- message queue,是 topic的分区,他可以保证消息的有序
-
消息队列保证消息的可靠性
Q:消息丢失场景和解决?
消息的可靠性 取决于 三方的正确响应顺序;(消息提供者、broker、消息消费者)
疑问
- 消息提供者将消息发送给 broker;
-
- 没有响应或者响应失败,开启重试
- broker先进行刷盘,存储消息,之后响应消息提供者;
- broker将消息发送给消息消费者;
- 消息消费者消费完消息响应给 broker;
- broker判断消息消费成功。
Q:消息存储?
首先 RocketMQ本身就支持消息的硬盘存储的,
不像 RabbitMQ默认不支持消息的硬盘存储,当设置消息硬盘存储后,RabbitMQ的并发量会从 1万,降到 2000左右;
RocketMQ不会出现这样的原因是,它的硬盘存储使用了 MMap的算法,
原来从服务器到服务器的硬盘经过的4次拷贝,减少成了3次,大大提高了数据拷贝的速度。
然后 服务提供者提供消息给 broker后,broker会开启存储消息阶段,即服务刷盘;
之后才发送给生产者响应发送消息成功。
如果 broker是集群的情况,不仅仅写入当前 broker,它的副本也要写入,保证存储的可靠性。
Q:处理重复消息?
首先因为要保证消息的可靠性,会出现重试的机制,无法避免的会产生重复数据;
然后要 RocketMQ进行消息查重会极大的降低效率,所有需要服务消费者来解决消息重复的问题;
解决的方案是保证服务消费的幂等性,保证多次消费不会对原来预期的消费结果产生不同;
比如要更新一条数据的时候添加判断条件,保证修改的数据是通第一次修改的结果一致;或者是判断数据的状态是已经消费过了,不进行处理;
根据实际的业务来保证重复消费不会对预期的消费结果产生影响即可。
服务消费的问题
Q:保证消息的有序性?
比如一个需求是 注销一个用户;
先把用户在除用户模块以外的服务,比如订单的状态、购物车里的状态等先进行处理;
之后才在用户表修改用户的状态;
会用到 broker里 topic主题里的 message queue;
他是队列的形式,可以保证消息的顺序;在代码里就是指定主题的 tag;
Q:解决消息的堆积?
生产者的生产速度与消费者的消费速度不匹配;
可能是生产者反复重试生产消息或消费者消费速度太慢;
首先定位消费满的原因,该改的 bug改掉,改优化的 sql优化;
如果优化后还是慢,就考虑增加消费者了;
而一个 topic里的 message queue对应一个服务消费者;