rabbitmq的常见面试题,例如有那些工作模式,消息的重复消费,消息堆积,确保消息不丢失,延迟订单怎么实现的...

目录

1.说一下mq的工作模式,分别有什么特点,还有说一下mq的交换机有哪几种

2.说一下消息的重复消费跟解决方法

3.说一下怎么确保消息不会丢失

4.说一下消息的顺序消费问题

5.说一下消息的堆积问题,怎么处理

6.说一下mq的过期时间

7.说一下死信队列

8.在系统中用到mq的是哪一些场景

9.你的延迟订单是怎么实现的


1.说一下mq的工作模式,分别有什么特点,还有说一下mq的交换机有哪几种

mq的工作模式主要有五种:

        简单模式,工作模式,路由模式,主题模式,发布订阅模式

简单模式的特点就是一个生产者对应一个消费者

工作模式的特点就是一个生产者对应多个消费者 

路由模式的特点就是根据路由规则为导向,把消息推送到符合路由规则的队列中

主题模式的特点就是跟路由模式差不多,只不过这个是模糊匹配的方式

发布订阅模式的特点就是把消息推送到绑定了该交换机的所有队列中


交换机也有五种,分别是直连交换机,主题交换机,扇形交换机,首部交换机,默认交换机

比较常用的是前面三种,然后路由模式中对应的是直连交换机,主题模式用的是主题交换机,发布订阅模式用的是扇形交换机

2.说一下消息的重复消费跟解决方法

先说一下造成重复消费的原因,首先就是消费者在成功消费消息之后,在返回ack的过程中,因为网络问题的原因,导致了mq收不到ack,然后mq那边就没有把消息给删除掉,这样就造成了重复消费,
       解决方法:

在消费者消费消息之前,把这消息对应的id通过redis的setnx方法保存起来,然后设置一个值为0,表示正在消费,然后等待消费者成功把消息消费之后,把0给改成1,表示已经成功消费,然后再返回ack,这个时候就已经可以确保消息不会被重复消费了,因为就算返回的ack不成功,在第二次消费的时候,因为消息对应的id在redis已经存在,所以使用setnx方法的时候,是set不进去的,这个时候就可以获取对应的值,来做处理,如果值为0表示有消费者正在处理消息,就不做任何操作,如果是1就表示该消息已经处理完成了,这个时候就直接返回ack

3.说一下怎么确保消息不会丢失

        在生产者生成消息的时候,去开启confirm模式,写一个ben对象去实现confirmcallback接口,这样交换机是否成功收到消息都会触发回调方法,然后在声明交换机,声明队列,以及发送一些比较重要的消息的时候,做持久化处理,然后开启消息的回退模式,写一个ben对象去实现returncallback接口,这样当交换机推送消息给队列时,如果失败就会触发回调方法,在消费者这边,开启手动ack机制,确保消息正常执行完毕之后再返回ack,然后还可以去配置备用队列跟死信队列,这样就可以基本上确保mq的消息不会丢失了

4.说一下消息的顺序消费问题

        当有多个消费者去监听同一个队列的时候,虽然数据在队列中是有序的,但是我们无法保证先拿到消息的消费者会先执行完毕,所以这样就会导致消息的顺序消费问题.
        解决方案是生产者在投递消息的时候,先做好消息类型的分类,然后再按照类型去推送到对应的队列里面去,每一个队列就只用一个消费者去监听

5.说一下消息的堆积问题,怎么处理

        消息的堆积问题,多数情况下指的是生产者生成消息的速度大于消费者消费消息的速度,一般的解决方法是减低生产者生产消息的速度,然后提高队列的容量,在消费者端,可以做消费者集群处理,还能在消费者里面使用线程池来快速处理消息,如果开启了手动返回ack模式的,在消息出现异常并且多次入队的时候,就需要加个判断,重复入队达到一定次数的时候需要移除到死信队列,要不然会造成阻塞

6.说一下mq的过期时间

        mq的消息过期时间可以在队列中设置,也可以在消息中单独设置,如果两个都设置的了话,就按照时间短的为准,如果这个队列没有设置死信队列,那么过期的消息会被丢失,一般来说消息过期都会配合死信队列来使用

7.说一下死信队列

        死信队列跟普通队列差不多,但是进入死信队列的消息有三种情况,第一种是消息的过期时间已经达到,第二种是消息被拒绝消费,第三种是队列的长度超出限制,然后超出的限制的消息会被转送到死信队列,死信队列跟消息的过期时间来配合使用可以达到延迟队列的效果

8.在系统中用到mq的是哪一些场景

        仅供参考:有用过mq来实现,在新用户注册成功之后,发送短信,邮箱,然后写入到注册日志里面,还有就是用户登录成功的时候也要写入到登录日志中,还有发微信公众号通知,下载一些数据量比较大的ex表格的时候,都可以用mq来做异步处理,还有就是在用户注册之后两天内没上线,就发送邮箱给用户通知一下,或者在下单之内20分钟不支付就取消订单

9.你的延迟订单是怎么实现的

       就是用户下单之后,把订单消息的过期时间设为15分钟,然后放到一个消息队列里面,然后这个队列就去绑定一个死信交换机跟死信路由键,再用一个消费者去监听死信队列,在15分钟之内,无论这个订单是否由支付,只要消息的过期时间到了,就会被监听死信队列的消费者消费消息,然后拿到这个订单的消息去判断该订单是否已经支付,如果没有支付,那就把这个订单的状态设置为已过期,如果订单的状态是以支付,那就不用管了,大体的思路就是这样

猜你喜欢

转载自blog.csdn.net/qq_26112725/article/details/129167026
今日推荐