面试官杠上重复消费、消息堆积、消息丢失、顺序消息?

作者&投稿:宁忽 (若有异议请与网页底部的电邮联系)
~

消息队列在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在消息队列的使用和原理方面对小伙伴们进行360 的刁难。

什么,这么多问题啊!别慌,现在就来找找解决方案。

一、 重复消费

现在消息队列一般都能保证at least once的,也就是消息至少一次投递。 在这种情况为什么会出现重复消费的问题呢?通常都是由于网络原因造成的 ,原因如下:通常消息被成功消费后消费者都会发送一个成功标志给MQ,MQ收到这个标志就表示消息已经成功消费了,就不会再发送给其他消费者了。但是如果因为网络这个标志没有送到MQ就丢失了,MQ就认为这个消息没有被成功消费,就会再次发送给其他消费者消费,就造成重复了。

这时我们看这个问题就变成了我们怎么保证消费端的幂等性。

幂等性 是指一个操作其执行任意多次所产生的影响均与一次执行的影响相同,大白话就是你同样的参数调用我这个接口,调用多少次结果都相同。

怎么保证消息队列消费的幂等性

其实还是得结合业务来思考,我在这里给出几个解决方案:

1. 分布式锁 。生产者发送每条数据的时候,里面加一个全局唯一的 id,类似订单 id 之类的东西,然后你这里消费到了之后,先根据这个 id 去比如 Redis 里查一下,之前消费过吗?如果没有消费过,你就处理,然后就是这个 id 写 Redis。如果消费过了,那你就别处理了,保证别重复处理相同的消息即可。

2.唯一键防重 。基于数据库的唯一键来保证重复数据不会重复插入多条。因为有唯一键约束了,重复数据插入只会报错,不会导致数据库中出现脏数据。

3.先查后写。 要写数据库前,先根据主键查一下,如果这数据都有了,你就别插入了,update一下好了。

4. 关闭重试机制 。如果把重试机制关掉的话不显示,虽然解决了重复消费的问题,但是可能会造成丢失消息,不建议这么做。

不同的业务可以选择不同的方案,如果服务的并发量不高,可以考虑唯一键防重或者先查后写的方案;如果并发量较高,追求性能,沐子推荐采用分布式锁实现幂等性(本公司目前采用的方案)

二、 消息堆积

1. 消息堆积的产生原因

消息堆积的原因主要在于两方面,其一为消费的太慢或消费方出现异常,其二为生产方生产的太快,总的来说就是 消息的速度赶不上生产的速度,生产和消费速度不匹配造成的 。

2. 消息堆积的解决方案

1)生产端:一般当生产端发生积压(Broker正常的情况下)就要查看你的业务逻辑是否有异常的耗时步骤导致的,是否需要改并行化操作等。

Broker端:当Broker端发生积压我们首先要查看,消息队列内存使用情况, 如果有分区的的话还得看每个分区积压的消息数量差异。当每个分区的消息积压数据量相对均匀的话,我们大致可以认为是流量激增。需要在消费端做优化,或者同时需要增加Broker节点(相当于存储扩容),如果分区加压消息数量差异很大的话(有的队列满了,有的队列可能还是空闲状态),我们这时候就要检查我们的路由转发规则是否合理。

2) 增加消费者 ,多部署几台消费者机器(横向扩展),提升消费者的消费能力。

3)此种情况可以将这些 消费不成功的消息转发到其它队列里去(类似死信队列) ,后面再慢慢分析死信队列里的消息处理问题。

4) mq 中的消息过期失效了。可以采取一个方案,就是批量重导 ,这个我们之前线上也有类似的场景干过。就是大量积压的时候,我们当时就直接丢弃数据了,然后等过了高峰期以后,将丢失的那批数据,写个临时程序,一点一点的查出来,然后重新灌入 mq 里面去,把白天丢的数据给他补回来。

总之,上面说到消息积压的问题,我们需要查看是否有无限重发的消息或者有进入死锁的程序等等,当确定是流量激增的话,我们需要评估是否需要增加资源还是通过限流的方式解决,当短时间大量消息需要处理时,在资源允许的情况下,我们可以新启一批消费者与消息队列,将原来的消费者中的消息直接作为生产者转发到临时应急队列中,这样大概率的能够快速解决消息积压。与其事后处理不如我们在设计之初就要把积压考虑进来,对于数据量非常大,但是实时性要求不高的场景,可以设计出批量消息发送,当队列积累到一定阀值再做批量消费消费,这里需要注意的就是重复消费带来的影响,设计不好就是一场灾难。

三、 消息丢失

一般来讲消息丢失的途径有三个: 生产者弄丢数据、消息队列弄丢数据、消费者弄丢数据 。

1. 生产者弄丢数据

a、丢失的原因:因为网络传输的不稳定性,当生产者在向MQ发送消息的过程中,MQ没有成功接收到消息,但是生产者却以为MQ成功接收到了消息,不会再次重复发送该消息,从而导致消息的丢失。

b、解决办法:有两个解决办法,第一个方法: 向broker发送消息时,如果由于网络抖动等原因导致消息发送失败,可以设置 失败重试次数让消息重发 。
第二个方法: 事务机制和confirm机制,最常用的是confirm机制 ;

事务机制和 confirm 机制最大的不同在于,事务机制是同步的,你提交一个事务之后会阻塞在那儿,但是 confirm 机制是异步的,你发送个消息之后就可以发送下一个消息,然后那个消息 MQ 接收了之后会异步回调你的一个接口通知你这个消息接收到了。

2. MQ弄丢数据

a、丢失的原因:MQ接收到生产者发送过来的消息,是存在内存中的,如果没有被消费完,此时MQ宕机了,那么再次启动的时候,原来内存中的那些消息都丢失了。

b、解决办法: 开启MQ的持久化 。结合上面的说到的confirm机制,只有当消息成功持久化磁盘之后,才会回调生产者的接口返回ack消息,否则都算失败,生产者会重新发送。存入磁盘的消息不会丢失,就算MQ挂掉了,重启之后,他会读取磁盘中的消息,不会导致消息的丢失。

注意,哪怕是你给 MQ 开启了持久化机制,也有一种可能,就是这个消息写到了MQ 中,但是还没来得及持久化到磁盘上,结果不巧,此时MQ挂了,就会导致内存里的一点点数据丢失。

所以,持久化可以跟生产者那边的 confirm 机制配合起来,只有消息被持久化到磁盘之后,才会通知生产者 ack 了,所以哪怕是在持久化到磁盘之前,MQ 挂了,数据丢了,生产者收不到 ack,你也是可以自己重发的。

3. 消费者弄丢数据

a、丢失的原因:如果MQ成功的把消息发送给了消费者,那么MQ的ack机制会自动的返回成功,表明发送消息成功,下次就不会发送这个消息。但如果就在此时,消费者还没处理完该消息,然后宕机了,那么这个消息就丢失了。

b、解决的办法:1)简单来说,就是必须关闭 MQ 的自动提交,把 自动提交改为手动提交 ,也就是说当我消费成功后才会进行提交。

2)消费者端已经正常接收到消息但是在执行后续消息处理时发生了异常,最终返回处理失败。 重试-进行重新消费问题,如果一直这样重复消费都持续失败到一定次数,可以投递到 DLQ 死信队列,应用可以监控死信队列来做人工干预 。

四、 顺序消费

比如一个电商的下单操作,下单后先减库存然后生成订单,这个操作就需要顺序执行的。队列本身是有顺序的,但是为什么还要保证顺序消费呢,主要是因为生产环境服务实例一般都是集群,当消费者是多个实例时,队列中的消息会分发到所有实例进行消费(同一个消息只能发给一个消费者实例),这样就不能保证消息顺序的消费,因为你不能确保哪台机器执行消费端业务代码的速度快。

保证每次只有单个消费实例消费

所以对于需要保证顺序消费的业务,我们可以只部署一个消费者实例,然后设置MQ 每次只推送一个消息,再开启手动 ack 即可。这样MQ 每次只会从队列推送一个消息过来,处理完成之后我们 ack 回应,再消费下一个,就能确保消息顺序性。

这样MQ 每次只会从队列推送一个消息过来,处理完成之后我们 ack 回应,再消费下一个,就能确保消息顺序性。

但是这样的操作也会降低消费者的性能, 一个消费者消费消息时,其他消费者会阻塞,所以很多场景下可能并不会采用这样的方案。

所以一般会根据场景,制定一定的策略来解决消费顺序问题。

多线程并发抢占出现消费乱序问题

当MQ采用简单队列模式的时候,如果消费者采用多线程的方式来加速消息的处理,此时也会出现消息乱序的问题。

多线程并发抢占出现消费乱序问题,将消息ID进行hash计算,将相同值放入同一个内存队列,让指定线程执行,即可解决顺序消费问题。

在多个分区中保证消息顺序和消息处理效率

首先使用多个分区,消息可以被发送端发送至多个分区,保证消息发送的效率。然后在消费端在拉消息时使用ConutdownLunch来记录一组有序消息的个数。如果达到个数,说明已拉取到完整的一组有序消息。然后在消费端根据消息序号进行排序,消费端将排好序的消息发到内存队列(可以搞多个),一个内存队列开启一个线程顺序处理消息。即可最大程度上既保证顺序又保证效率!

RocketMQ作为阿里开源的一款高性能、高吞吐量的消息中间件,支持顺序消息,所以如果有这种场景或者要使用MQ,我建议你直接使用RocketMQ即可。

我们说了一些处理与分析问题的方法,这里有一个最重要的点就是我们需要有一套实用的监控发现工具或者方式,在问题第一时间发现才是王道,不然我们上面所说的都空谈,当问题发现的时候损失已经无法挽回。所以我们要在设计系统之初需要要为监控系统或者程序提供完备或者必须的日志,接口,数据等,这要才是一个合理的设计。当没有监控系统的情况下我们必须自己设计一套简单分析接口。

最后, 如果我的文章对你有所帮助或者有所启发, 欢迎关注公众号(微信搜索公众号:首席架构师专栏),里面有许多技术干货,也有我对技术的思考和感悟,还有作为架构师的验验分享;关注后回复 【面试题】,有我准备的面试题、架构师大型项目实战视频等福利 , 我会带着你一起学习、成长,让我们一起加油!!!




轻松搞定面试官的招数
面试开始时,注意用眼睛注视面试官,面露微笑,就像平时碰到一个很久不见的熟人一样。这个简短、有效的举动,让人觉得你很容易相处,打破面试开始时的尴尬。 2、简洁有序 进行自我介绍的时候,不要一味重复简历上的内容,而是挖出有可谈性的、有实质内容的东西来,一是让面试官认识自己,二是可以让面试官有话可说。

试官造句用试官造句
试官造句 “试官”的解释 试官[shì guān] 试官 词语解释 (1).出任官职。《史记·日者列传》:“初试官时,倍力为巧诈,饰虚功执空文以誷主上,用居上为右;试官不让贤陈功,见伪增实,以无为有,以少为多,以求便势尊位。” (2).主持考试的官吏。 唐 薛用弱 《集异记·王维》:“...

为什麼去面试的时候,面试官这麼跟我说,他们不招花瓶,要招能吃苦的,还...
首先,说这话并不是针对你,而是概括了他们公司的企业文化。其次,嗯~我不得不说这个面试官情商不高,不太懂谈话的艺术。或者说,他自认为高高在上,俯视着应聘者,所以语气、态度、眼神什么的都很骄傲。最后,再分析他说的“不招花瓶,要招能吃苦的,公司基本上都来自农村”,其实另一个层面是:...

为什么很多面试官很讨厌求职者一上来就谈薪资待遇?
其次人家还不知道你有几斤几两,你一上来就谈薪资,人家就会觉得你是一个很冒失的人,会认为你拎不清自己,这种行为就跟古代的时候你还没有打仗就向皇帝讨要功劳是一样的性质,所以试想一下别人怎么可能会喜欢你,不把你直接打发走就已经很给你面子了,对于一些脾气暴躁的面试官来说,有可能会当场把...

"秀才剌,试官刷"是什么?
说的是,你秀才的文章违背事理,我考官就把你刷掉 起因是,嘉佑年间,书生刘几多次在国子监考试中中得第一,屡屡做出诡谲险怪的文句,引得众学子纷纷效仿,形成一时风气,后来整肃文风被欧阳修整治,这一句就是欧阳修嘉佑二年给刘几的考卷上的评语,还被作为当年科考的大热门刷过,除了这批语,欧阳修...

在面试的过程中,如果没有听清面试官的话,可以要求重复吗?
当然可以重复,这些小事情更能够体现个人的细节,如果没有清晰听清楚面试官所问的问题,自己盲目去回答,那显得更笨。要是有任何不懂的问题,都可以及时向面试官请教,表现出自己谦虚的和爱学习的态度。如果不懂也不问,盲目去解释,会给面试官一个非常不好的印象,在某种程度上也反映出应聘者未来的...

请问:怎样对付面试官?
如题!面试官一般会问到哪些问题?怎样回答才好?(现实点、不要说得太假)…如:面试官说看我的样子好像不会吃苦?该怎样回答?还问我有什么问题要问他?…晕、我没经验、各位大哥大... 如题!面试官一般会问到哪些问题?怎样回答才好?(现实点、不要说得太假)…如:面试官说看我的样子好像不会吃苦?该怎样回答?

作为一名优秀的面试官,需要具备什么素质
一个优秀的职场面试官需要具备哪些特质? 经历了好多次的面试,面过别人,也被人面过,也和很多人交流过面试的经验。不过感到遗憾的是,很多面试问题太浅显易懂,对我这样的面试油子很难杀伤! 这里给大家汇集的问题,是和一些面试高手切磋学到的。如果你是面试官,可以借鉴一下如何提问,如果你是候选人,可以试试如何回...

资深hr找工作,面试官会问什么问题
场景3一些面试官问完学历后就开始问一些经济专业的问题。如“财务管理有哪些内容?”,或者一些专业名词,有些学生没听过那个名词,面试官重复了几次她就说,...的时代,职业人的思维、脚步必须与时代同步,从发展趋势来说,将会根据环境的变化、竞争的改变和和消费行为的改变与时俱进,以竞争为导向,在新的层次上概括新...

面试财务时,面试官问你还有什么问题要问的时候,通常问什么最好呢?_百...
这个问题,面试官不会在面试的时候告诉你,需要你自己询问,但是这个问题很关键,如果面试官愿意,他会把你在试用期期间要做出什么样的业绩,达到什么样的要求很详细的和你说出,对于将来你怎样转正有很大的帮助,同时也会让面试官认为你是一个很认真的人。 这个职位在贵公司的发展前景是怎么样的?有何种晋升机制?在什...

海淀区15717837621: 面试技巧:如何在面试中获得HR的高分印象 -
尔卷奥硝: 法则一、我是不二人选 面对堆积如山的简历,HR经理往往以排除法进行初选.如果能重点突出自己的优势,给HR经理留下良好的第一印象,这就需要准确表达“我是这份工作的不二人选”.在面试中,学历、专业、工作经验固然重要,但HR...

海淀区15717837621: 坐飞机去上海自助游3天2晚,哪些地方好玩?只在上海区域,不去周边旅游 -
尔卷奥硝: 第一天:新天地、人民广场、南京路步行街、外滩、豫园 第二天:东方明珠、滨江大道、上海科技馆、世纪公园 第三天:七宝、徐家汇、原世博园区住宿可以考虑南京路或者外滩周边的快捷连锁酒店.如家、汉庭、锦江之星等.

海淀区15717837621: 重复消费是什么?
尔卷奥硝: 广义理解:就是多重消费和反复消费. 要根据具体的消费形式而定: 如果是产品:就是可以反复使用或利用,也可以再次小额购买消费;简单点说就是,一个东西用了会折旧或淘汰,而必须再次购买或者维修,可以理解为财富消费; 如果是服务:意思是一次服务,会带来衍生或者相关服务,或多次服务,理解为服务性再次消费.

海淀区15717837621: 复消什么意思? -
尔卷奥硝: 顾名思义,就是重复消费.望采纳,谢谢

海淀区15717837621: 逆战测试服开G会封号吗? -
尔卷奥硝: 像腾讯集团所有游戏的体验服,测试服都是关闭安检,不接受投诉的,所以你才能开这么爽的外G,不过,还是要劝告楼主,绿色游戏,杜绝外挂,这样才能换得所有人的较好的游戏体验.

海淀区15717837621: 报纸广告的特性有那些? -
尔卷奥硝: 在传统四大媒体中,报纸无疑是最多、普及性最广和影响力最大的媒体.报纸广告几乎是伴随着报纸的创刊而诞生的.随着时代的发展,报纸的品种越来越多,内容越来越丰富,版式更灵活,印刷更精美,报纸广告的内容与形式也越来越多样化...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网