当前位置:   article > 正文

消息队列之如何避免消息丢失_消息队列如何保证消息不丢失

消息队列如何保证消息不丢失

写在前面

记得之前面试找工作时就被问到这个问题,但是最后自己回答的并不是很好,最后等到了几个字回去等通知吧!,希望下次再被问到这个问题,能够给出让面试官满意的答案,下面我们就一起来看下吧!

正文

在系统设计时,我们往往为了解决以下的问题,而会考虑引入消息队列:

服务解耦:解耦带来的好处是,可以避免因为边缘业务的问题而影响到主业务功能。
流量削峰填谷:如果出现流量激增的情况,可以通过通过消息队列的削峰填谷功能进行缓冲,防止直接冲垮业务系统。
  • 1
  • 2

其中服务解耦,考虑这样的场景,比如购物,在用户购物时使用了优惠券,积分等来抵扣现金,用户扣款成功后需要对相应的优惠券作废处理,积分做减少处理,像这种扣款成功后的操作,我们可以称之为是边缘业务,为了避免因为其出现问题,而导致用户无法正常付款,就可以考虑引入消息队列,来进行解耦。

对于流量削峰填谷,考虑这样的场景,双十一来了,公司也想要蹭一波热度,来个秒杀活动,凌晨十二点整,原价1599的茅台酒,只要9.9大概率是假酒,不要买!!!,可以想象此时流量会有一个激增,下游服务因为处理能力到达极限,数据会被暂存在消息中间件,而不至于冲垮服务。

前面提到了解耦,即程序不是运行在同一个应用中,那么此时就出现了数据一致性的问题,什么意思呢,如果上游服务处理成功了,但是下游服务并没有处理成功上游服务的消息,此时上有服务和下游服务数据一致性就出现问题了,换句话说,就是如何保证消息不丢失。想要保证消息不丢失必须分析清楚消息的流转都经过了哪些环节,如下:

1:生产者生产消息
2:消息中间件存储消息
3:消费者消费消息
  • 1
  • 2
  • 3

对于1:生产者生产消息如何保证消息不丢失呢,比较简单,在程序中只有收到了消息中间件的ACK,才认为消息已经成功发送。对于2:消息中间件存储消息需要设置消息中间件何时发送ACK给生产者才会保证消息不丢失,如设置消息至少同步到2个节点的副本才发送ACK。对于3:消费者消费消息,消费者只有在真正的成功消费了消息后,才发送ACK给消息中间件。结合这三者理论上就能够保证消息不丢失了。

但是这可能还不够,以上的做法还只是纯粹依靠软件本身,还不能做到百分百可靠,那怎么办呢?可以考虑给每个消息生成一个全局唯一的GID,而这个GID如何添加呢?比较好的方案是通过拦截机制,消息发送方发送消息前被拦截,添加GID,并记录消息的生产状态,消息消费方消费消息前被拦截,记录消息的消费状态,在结合一个第三方的任务去检测对比双方的GID就可以知道是否有消息丢失了,另外有了这个GID不仅仅能够解决消息丢失的问题,也能够解决消息重复消费的问题,利用其实现消费方消费消息的幂等性。

参考文章列表

使用MQ的时候,怎么确保消息100%不丢失?

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/826303
推荐阅读
相关标签
  

闽ICP备14008679号