本期分享呢,知识经验上的分享,如果有些同学对于 MQ 还陌生的话,请先行去学习基础篇,这里是应用经验上的分享,前提是 解耦、异步、消峰 你都知道的前提下阐述的。
1、MQ 集群架构图
image.pngNameServer、Broker、Producer、Consumer之间如何进行通信,如何工作:
image.png2、MQ 如何保证消息幂等性问题?
1、业务场景,先查询 数据库,如果已经存在了,就丢弃掉。
2、记录消费日志,每成功一次,就把 messageKey 保存下来。
注意:
MQ 如果是 代码错误 就不需要做重试了,
只有 链接超时 数据库暂时链接不上才用重试机制
总结: 基本上就这么几个套路,真正应用到实际中还是得看具体业务细节。
3、如何保证消息不丢失?
就我们市面上常见的消息队列而言,只要 配置得当,我们的消息就不会丢。
image.png可以看出一共分为三个阶段,分别是 生产消息、存储消息和消费消息。我们从三个阶段分别入手来看看如何确保消息不丢失。
生产消息方面:
生产者发送消息至Broker
,需要处理Broker
的响应,不论是同步还是异步发送消息,同步和异步回调都需要做好try-catch
,妥善的处理响应,如果Broker
返回写入失败等错误消息,需要重试发送。当多次发送失败需要作报警,日志记录等。
存储消息方面:
存储消息阶段需要在消息刷盘之后再给生产者响应,假设消息写入缓存中就返回响应,那么机器突然断电这消息就没了,而生产者以为已经发送成功了。
如果Broker
是集群部署,有多副本机制,即消息不仅仅要写入当前Broker
,还需要写入副本机中。那配置成至少写入两台机子后再给生产者响应。这样基本上就能保证存储的可靠了。
消费消息方面:
消费者应该在 消费者真正执行完业务逻辑之后,再发送给Broker
消费成功的确认消息,这才是真正的消费了。
总结一下就是:
保证消息的可靠性需要三方配合。
生产者
需要处理好 Broker
的响应,出错情况下利用重试、报警等手段。
Broker
需要控制响应的时机,单机情况下是消息刷盘后返回响应,集群多副本情况下,即发送至两个副本及以上的情况下再返回响应。
消费者
需要在执行完真正的业务逻辑之后再返回响应给Broker
。
但是要注意消息可靠性增强了,性能就下降了,等待消息刷盘、多副本同步后返回都会影响性能。因此还是看业务,例如日志的传输可能丢那么一两条关系不大,因此没必要等消息刷盘再响应。
4、 MQ 如何保证消息的有序性。
有序性分为两种:全局有序和部分有序。
全局有序:
如果要保证消息的全局有序,首先只能由一个生产者往Topic
发送消息,并且一个Topic
内部只能有一个队列(分区)。消费者也必须是单线程消费这个队列。这样的消息就是全局有序的!
部分有序:
因此绝大部分的有序需求是部分有序,部分有序我们就可以将Topic
内部划分成我们需要的队列数,把消息通过特定的策略发往固定的队列中,然后每个队列对应一个单线程处理的消费者。这样即完成了部分有序的需求,又可以通过队列数量的并发来提高消息处理效率。
5、 如何处理消息的堆积?
消息的堆积往往是因为生产者的生产速度与消费者的消费速度不匹配。有可能是因为消息消费失败反复重试造成的,也有可能就是消费者消费能力弱,渐渐地消息就积压了。
因此我们需要先定位消费慢的原因,如果是bug
则处理 bug
,如果是因为本身消费能力较弱,我们可以优化下消费逻辑,比如之前是一条一条消息消费处理的,这次我们批量处理,比如数据库的插入,一条一条插和批量插效率是不一样的。假如逻辑我们已经都优化了,但还是慢,那就得考虑水平扩容了,增加Topic
的队列数和消费者数量,注意队列数一定要增加,不然新增加的消费者是没东西消费的。一个Topic中,一个队列只会分配给一个消费者。
今天就到这里啦,如果觉得好的话,多多评论、点赞和关注呦~
网友评论