首页 > 其他分享 >RabbitMQ面试相关

RabbitMQ面试相关

时间:2023-09-04 21:44:08浏览次数:36  
标签:持久 rabbitmq queue 面试 实例 RabbitMQ 相关 数据 消息

1.如何保证消息队列的高可用啊?

  • RabbitMQ是比较有代表性的,因为是基于主从做高可用性的,我们就以他为例子讲解第一种MQ的高可用性怎么实现。
    rabbitmq有三种模式:单机模式,普通集群模式,镜像集群模式
    (1)单机模式
    (2)普通集群模式
    意思就是在多台机器上启动多个rabbitmq实例,每个机器启动一个。但是你创建的queue,只会放在一个rabbitmq实例上,但是每个实例都同步queue的元数据。完了你消费的时候,实际上如果连接到了另外一个实例,那么那个实例会从queue所在实例上拉取数据过来。
    这种方式确实很麻烦,也不怎么好,没做到所谓的分布式,就是个普通集群。因为这导致你要么消费者每次随机连接一个实例然后拉取数据,要么固定连接那个queue所在实例消费数据,前者有数据拉取的开销,后者导致单实例性能瓶颈。而且如果那个放queue的实例宕机了,会导致接下来其他实例就无法从那个实例拉取,如果你开启了消息持久化,让rabbitmq落地存储消息的话,消息不一定会丢,得等这个实例恢复了,然后才可以继续从这个queue拉取数据。所以这个事儿就比较尴尬了,这就没有什么所谓的高可用性可言了,这方案主要是提高吞吐量的,就是说让集群中多个节点来服务某个queue的读写操作。
    3)镜像集群模式
    这种模式,才是所谓的rabbitmq的高可用模式,跟普通集群模式不一样的是,你创建的queue,无论元数据还是queue里的消息都会存在于多个实例上,然后每次你写消息到queue的时候,都会自动把消息分发到多个实例的queue里进行消息同步。这样的话,好处在于,你任何一个机器宕机了,没事儿,别的机器都可以用。坏处在于,第一,这个性能开销也太大了吧,消息同步所有机器,导致网络带宽压力和消耗很重!第二,这么玩儿,就没有扩展性可言了,如果某个queue负载很重,你加机器,新增的机器也包含了这个queue的所有数据,并没有办法线性扩展你的queue.

    那么怎么开启这个镜像集群模式呢?我这里简单说一下,避免面试人家问你你不知道,其实很简单rabbitmq有很好的管理控制台,就是在后台新增一个策略,这个策略是镜像集群模式的策略,指定的时候可以要求数据同步到所有节点的,也可以要求就同步到指定数量的节点,然后你再次创建queue的时候,应用这个策略,就会自动将数据同步到其他的节点上去了。

2.如何保证消息不被重复消费啊(如何保证消息消费时的幂等性)?

(1)比如你拿个数据要写库,你先根据主键查一下,如果这数据都有了,你就别插入了,update一下好吧
(2)比如你是写入到redis,那没问题了,反正每次都是set,天然幂等性
(3)比如你不是上面两个场景,那做的稍微复杂一点,你需要让生产者发送每条数据的时候,里面加一个全局唯一的id,类似订单id之类的东西,然后你这里消费到了之后,先根据这个id去比如redis里查一下,之前消费过吗?如果没有消费过,你就处理,然后这个id写redis。如果消费过了,那你就别处理了,保证别重复处理相同的消息即可。
(4)还有比如基于数据库的(唯一键)来保证重复数据不会重复插入多条,我们之前线上系统就有这个问题,就是拿到数据的时候,每次重启可能会有重复,因为kafka消费者还没来得及提交offset,重复数据拿到了以后我们插入的时候,因为有唯一键约束了,所以重复数据只会插入报错,不会导致数据库中出现脏数据.

3.如何保证消息的可靠性传输(如何处理消息丢失的问题)?

  • 这个丢数据,mq一般分为两种,要么是mq自己弄丢了,要么是我们消费的时候弄丢了。咱们从rabbitmq分别来分析一下吧
    rabbitmq这种mq,一般来说都是承载公司的核心业务的,数据是绝对不能弄丢的.

    1)生产者弄丢了数据
    如果你要确保说写入rabbitmq的消息别丢,可以开启confirm模式,在生产者那里设置开启confirm模式之后,你每次写的消息都会分配一个唯一的id,然后如果写入了rabbitmq中,rabbitmq会给你回传一个ack消息,告诉你说这个消息ok了。如果rabbitmq没能处理这个消息,会回调你一个nack接口,告诉你这个消息接收失败,你可以重试。而且你可以结合这个机制自己在内存里维护每个消息id的状态,如果超过一定时间还没接收到这个消息的回调,那么你可以重发。

    2)rabbitmq弄丢了数据
    就是rabbitmq自己弄丢了数据,这个你必须开启rabbitmq的持久化,就是消息写入之后会持久化到磁盘,哪怕是rabbitmq自己挂了,恢复之后会自动读取之前存储的数据,一般数据不会丢。除非极其罕见的是,rabbitmq还没持久化,自己就挂了,可能导致少量数据会丢失的,但是这个概率较小。
    (设置持久化有两个步骤,第一个是创建queue的时候将其设置为持久化的,这样就可以保证rabbitmq持久化queue的元数据,但是不会持久化queue里的数据;第二个是发送消息的时候将消息的deliveryMode设置为2,就是将消息设置为持久化的,此时rabbitmq就会将消息持久化到磁盘上去。必须要同时设置这两个持久化才行,rabbitmq哪怕是挂了,再次重启,也会从磁盘上重启恢复queue,恢复这个queue里的数据。
    而且持久化可以跟生产者那边的confirm机制配合起来,只有消息被持久化到磁盘之后,才会通知生产者ack了,所以哪怕是在持久化到磁盘之前,rabbitmq挂了,数据丢了,生产者收不到ack,你也是可以自己重发的。
    哪怕是你给rabbitmq开启了持久化机制,也有一种可能,就是这个消息写到了rabbitmq中,但是还没来得及持久化到磁盘上,结果不巧,此时rabbitmq挂了,就会导致内存里的一点点数据会丢失。)

    3)消费端弄丢了数据
    rabbitmq如果丢失了数据,主要是因为你消费的时候,刚消费到,还没处理,结果进程挂了,比如重启了,那么就尴尬了,rabbitmq认为你都消费了,这数据就丢了。
    这个时候得用rabbitmq提供的ack机制,简单来说,就是你关闭rabbitmq自动ack,可以通过一个api来调用就行,然后每次你自己代码里确保处理完的时候,再程序里ack一把。这样的话,如果你还没处理完,不就没有ack?那rabbitmq就认为你还没处理完,这个时候rabbitmq会把这个消息分配给别的consumer去处理,消息是不会丢的。

4.如何保证消息的顺序性?

  • rabbitmq:拆分多个queue,每个queue一个consumer,就是多一些queue而已,确实是麻烦点;或者就一个queue但是对应一个consumer,然后这个consumer内部用内存队列做排队,然后分发给底层不同的worker来处理

  

 

标签:持久,rabbitmq,queue,面试,实例,RabbitMQ,相关,数据,消息
From: https://www.cnblogs.com/wtyhbh/p/17678166.html

相关文章

  • Linux运维工程师面试题(6)
    Linux运维工程师面试题(6)祝各位小伙伴们早日找到自己心仪的工作。持续学习才不会被淘汰。地球不爆炸,我们不放假。机会总是留给有有准备的人的。加油,打工人!1数据库事务的四个特性及含义数据库事务的4个特性:原⼦性、持久性、⼀致性、隔离性原⼦性:整个事务中的所有操作要么......
  • 电商类面试问题--02针对商品排行榜,你是怎么实现的
    02-针对商品排行榜,你是怎么实现的背景描述当时产品提出了每日热销排行榜在零点进行变更的需求。在我接到这个需求后,我立即想到了使用Redis的有序集合(ZSET)来实现这个功能,并与我们的技术负责人进行了沟通。经过与技术负责人的讨论和确认,我们一致认为使用有序集合是一个可行的解决......
  • ZROI 学习笔记之图论相关
    都别催!!!等我有时间了例题和详细讲解都会补回来的!!!8.10-基础图论本部分涉及的内容绝大部分在笔者的另一篇博客图论相关中都有详细讲解,可以参考这篇博客。1.图的遍历......
  • 面试题:spring中有两个id相同的bean对象会报错吗?
    一个xml文件声明两个beanid相同的对象,在项目启动时就会报错(对xml解析)。要求beanId唯一,该beanId元素标签已经被使用。两个xml文件声明相同beanId的对象,项目启动是没有问题的。使用时,属性值是后加载的对象值(先加载的会被后加载的覆盖)@Configuration注解+@Bean注解声明的相同......
  • 硬核!2023版Android面试指南,涵盖Android所有核心技能
    前言今年能明显感受到各行各业的不景气,互联网行业也是首当其冲。最近,大家反馈面试越来越难了,面试八股文也考察的越来越细,越来越底层,面试机会也肉眼可见的变少。这里,给大家总结一下面试小技巧!面试没准备好,不要随便面试,一些大厂都会有面试评价记录,太多差评影响以后的面试,同时面完之后......
  • 排序算法知识点和常见面试题
    查找和排序算法知识点和常见面试题查找二分查找排序算法知识点冒泡排序插入排序选择排序快速排序二分思维+递归思维#include<stdio.h>intFindPos(int*a,intlow,inthigh);voidQuickSort(int*a,intlow,inthigh);intmain(void){ inta[6]={-2,1,......
  • Less css了解与相关心得
    一个css的预处理器.粗略看了一下,实际上就是提供开发者另外一种编写css的方式,比原来更加灵活。实现的原理也不难,主要是字符串替换完成。less语法的css以.less结尾,具体解析方法,是在页面中引入less.js进行字符串解析。类似的思路,我们在工作中也想到过。比如前端js组件的开发,如果用js字......
  • Android并发编程高级面试题汇总(含详细解析 十六)
    Android并发编程高级面试题汇总最全最细面试题讲解持续更新中......
  • 前端面试题(文本与语音播放mpv3),上传喜马拉雅,便于随身听
    喜马拉雅播放地址(简介可看相关文字):https://www.ximalaya.com/album/77822188线上可下载文本与MP3文件:https://gitee.com/yoonaLin/FE_Interview_questions......
  • rabbitmq发布确认高级
    前言在之前的发布确认中,生产者发送消息到mq中,消费者在从mq中取出消息满足持久化的.发布确认是一个保证RabbitMQ可靠性的一个机制  保证生产者将信息成功的发送到RabbitMQ的server端了,那么broker就会回一个确认,如果没有收到或者收到拒绝信息,那么说明可能网络不好没有发送成......