【消息队列面试】1-5:可靠传输(不多、不少)、作用、不重复消费、优缺点和使用场景、死信队列、延时队列
一、消息队列如何保证消息可靠传输?☆☆☆☆☆
两方面:不多、不少
1、为了保证不多:生产者、消费者不能多生产/重复消费消息
(即使生产者多发消息)消费者避免重复消费:应当实现幂等性
2、保证不少:消息不丢失
生产者发送消息时,保证broker能收到并持久化这条消息
rabbitMQ的confirm机制,kafka的ack机制
都可以保证生产者将消息发送到broker
等到消费者真正消费完消息,broker才会删除存盘的消息【消费者的ack机制】
二、消息队列有哪些作用
解耦:作为两系统之间的通讯方式,从而两个系统之间就不需要相互依赖了
异步:系统发送完消息后,就可以做其他的操作
流量削峰:使用消息队列的方式调用某个系统,消息将会在消息队列中排队,消费者自己控制消费速度
三、如何保证消息不被重复消费☆☆☆☆☆【站在程序的角度,而不是站在MQ的角度】【幂等性】
1、ack或offset方式,无法避免重复消费
0MQ是否知道C的消费情况
可以使用ack机制或offset提交的方式
但上述方式保证不了重复消费
有可能处理完了,ack提交失败/没有来得及提交/除了网络问题,offset一样
MQ无法感知到消息是否成功消费,有可能会产生重复消费的问题
2、如何解决
不管是poll还是push,都需要由client客户端控制消息不被重复消费
要保证C端消费的幂等性,不会因此次数增加导致结果发生变化
3、如何保证消费的幂等性【根据业务,看哪个适用】【实际上就是一个去重】
如果是redis,使用set操作,具有天然的幂等性【要注意超时事件expire time会后延,导致超时事件不准确】
发送消息时,在消息体内携带一个唯一标识uuid,存入内存/redis,如果查到,可以直接拒绝此消息
往数据库做插入,可以借助数据库的主键,保证数据不会被重复插入
四、消息队列的优缺点和使用场景
1、优点
解耦:降低系统之间的依赖,使用A-MQ-B,A不强依赖B,异步调用,无需考虑熔断、服务降级等操作
异步处理:不需要同步等待,A调用B10次,可以部署多个B,消费者吞吐量和处理能力增强
削峰填谷:峰值流量大,平时流量小,流量突增情况下,B可能会被压垮,使用MQ后,流量激增,由B慢慢处理
2、缺陷
(1)增加了系统的复杂度,2个系统变3个系统,附加与mq交互的逻辑,也有可能带来重复消费的问题【幂等机制】,可能存在消息丢失的问题
(2)降低了系统的可用性,此前可用性取决于AB,加入MQ,可用性屈居于ABQ,设计MQ的高可用HA
(3)一致性:消息可能会丢失,消费者也可能会消费失败【回调增加复杂度】
3、使用场景
日志采集:避免影响业务,可以异步发送【可以容忍重复和丢失】
发布订阅:对事件感兴趣的,自己来消费,类似于Java的监听器;A调多个系统,BCD各自接收消息,执行对应的逻辑
五、死信队列是什么?延时队列是什么?
1、死信队列
用于存放没有成功消费的消息
消费者消费失败,且超过重试次数后,才会进入死信队列
2、延时队列
一般消息,立马消费
延时队列,会等到指定时间之后,再进行处理【订单超过3分钟未支付,取消订单】
本文来自博客园,作者:哥们要飞,转载请注明原文链接:https://www.cnblogs.com/liujinhui/p/15790234.html