| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> 消息中间件面试题总结(基于RabbitMQ的各种常见问题) -> 正文阅读 |
|
[大数据]消息中间件面试题总结(基于RabbitMQ的各种常见问题) |
什么是消息队列?
消息队列是一种异步的服务间通信方式,是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。使用较多的消息队列有RocketMQ、RabbitMQ、Kafka等。 为什么使用消息队列? 使用消息队列有三个好处: 解耦 耦合性:后台各个系统相互依赖,如果一个系统挂掉了,其他也会导致无法运行 于是消息队列就进行解耦,加入了消息队列之后,不同的后台只需要将自己的数据写进消息队列即可,一个系统挂掉了,他在消息队列中的数据依旧存在,不用担心出现整体无法运行的情况 异步 异步提速:比如说我们原本有3个后台系统要向前端输出数据,每个后台都需要300ms,还要加上访问数据库的时间,如果一个用户访问的后台较多,那么访问的时间也会变得很久,用户体验较差 但如果使用了消息队列的话,不管要访问多少个后台数据,所有的后台只需要把数据都压进消息队列里面就可行了,如何用户再根据自己的需求从消息队列拿,大大减少所需时间 削峰 如果我们有一段时间的请求量非常大,就好比双11的时候,我们的后台只能接受1000个,但一下发过来3000个,这时候后台扛不住,就会崩溃 但是如果使用了消息队列,消息队列会把加载不了的信息丢到消息队列里面去,等后台持续性的加载,这样就不会出现系统崩溃的问题,顶多也只是慢一点 消息队列有什么优点和缺点? 优点就是上面所说的三个: 解耦,异步,削峰 缺点: 系统的可用性降低:我系统引入的外部依赖越多,消息队列就越容易挂掉,不加消息队列之前,我们虽然有耦合的问题,2个系统可能互相关联,一方挂掉导致其他一个也无法正常使用,但是如果加了消息队列,消息队列一旦挂掉,那么所有的系统都会挂掉 系统复杂性变高:硬生生加个 MQ 进来,你怎么保证消息没有重复消费?怎么[处理消息丢失的情况]?怎么保证消息传递的顺序性?头大头大,问题一大堆,痛苦不已 Kafka ,ActiveMQ ,RabbitMQ ,RocketMQ 都有什么优点和缺点? ? 如何保证消息队列的高可用? 先了解Rabbit的三种工作模式 rabbitmq有3种模式,但集群模式是2种
如何保证消息的可靠性传输?(如何处理消息丢失的问题) 生产者没有成功把消息发送给消息队列 a、丢失的原因:因为网络传输的不稳定性,当生产者在向MQ发送消息的过程中,MQ没有成功接收到消息,但是生产者却以为MQ成功接收到了消息,不会再次重复发送该消息,从而导致消息的丢失。 b、解决办法: 有两个解决办法:事务机制和confirm机制,最常用的是confirm机制。 事务机制: RabbitMQ 提供了事务功能,生产者发送数据之前开启 RabbitMQ 事务 confirm机制: RabbitMQ可以开启 注意:RabbitMQ的事务机制是同步的,很耗型能,会降低RabbitMQ的吞吐量。confirm机制是异步的,生成者发送完一个消息之后,不需要等待RabbitMQ的回调,就可以发送下一个消息,当RabbitMQ成功接收到消息之后会自动异步的回调生产者的一个接口返回成功与否的消息。 RabbitMQ接收到消息之后丢失了消息 a、丢失的原因:RabbitMQ接收到生产者发送过来的消息,是存在内存中的,如果没有被消费完,此时RabbitMQ宕机了,那么再次启动的时候,原来内存中的那些消息都丢失了。 b、解决办法:开启RabbitMQ的持久化。当生产者把消息成功写入RabbitMQ之后,RabbitMQ就把消息持久化到磁盘。结合上面的说到的confirm机制,只有当消息成功持久化磁盘之后,才会回调生产者的接口返回ack消息,否则都算失败,生产者会重新发送。存入磁盘的消息不会丢失,就算RabbitMQ挂掉了,重启之后,他会读取磁盘中的消息,不会导致消息的丢失。 c、持久化的配置:
注意:持久化要起作用必须同时设置这两个持久化才行,RabbitMQ 哪怕是挂了,再次重启,也会从磁盘上重启恢复 queue,恢复这个 queue 里的数据。 消费者弄丢消息 a、丢失的原因:如果RabbitMQ成功的把消息发送给了消费者,那么RabbitMQ的ack机制会自动的返回成功,表明发送消息成功,下次就不会发送这个消息。但如果就在此时,消费者还没处理完该消息,然后宕机了,那么这个消息就丢失了。 b、解决的办法:简单来说,就是必须关闭 RabbitMQ 的自动 如何保证消息不被重复消费? (如何保证消息消费的幂等性) 先说为什么会重复消费:正常情况下,消费者在消费消息的时候,消费完毕后,会发送一个确认消息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除;但是因为网络传输等等故障,确认信息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将消息分发给其他的消费者。 解决思路是:保证消息的唯一性,就算是多次传输,不要让消息的多次消费带来影响;保证消息等幂性;
这个问题针对业务场景来答分以下几点:
如何保证消息的顺序性? mysql的binlog同步。你再mysql里增删改3条binlog。接着这三条binlog发送到MQ里面。到消费出来依次执行。起码要保证人家是按照顺序来的吧。不然本来是增加、修改、删除。你愣是给更改了顺序,换成了删除、修改、增加。这就乱了。 搞3个Queue,每个消费者就消费其中的一个Queue,把需要保证顺序的数据发到1个Queue里去 如何解决消息队列的延迟以及过期失效的问题? 过期失效就是TTL。如果消息在Queue中积压超过一定的时间就会被RabbitMQ给清理掉。这个数据就没了。这就不是数据积压MQ中了,而是大量的数据会直接搞丢。 在这种情况下,增加consume消费积压就不起作用了。此时,只能将丢失的那批数据,写个临时的程序,一点一点查出来,然后再灌入MQ中,把白天丢失的数据补回来。 消息队列满了之后该如何解决? 如果消息积压在 mq 里,你很长时间都没有处理掉,此时导致 mq 都快写满了,咋办?这个还有别的办法吗?没有,谁让你第一个方案执行的太慢了,你临时写程序,接入数据来消费,消费一个丢弃一个,都不要了,快速消费掉所有的消息。然后走第二个方案,到了晚上再补数据吧。 有几百万消息持续积压几小时,说说该怎么解决? 在日常工作中使用RabbitMQ偶尔会遇不可预料的情况导致的消息积压,一般出现消息积压基本上分为几种情况:
? 几千万条数据在MQ里,积压了七八个小时。这个时候就是恢复consumer的问题。让它恢复消费速度,然后傻傻地等待几个小时消费完毕。这个肯定不能再面试的时候说。1个消费者1秒时1000条,1秒3个消费者是3000条。1分钟是18万条。1个小时是1000多万条。如果积压了上万条数据,即使消费者恢复了,也大概需要1个多小时才能恢复过来。 原来3个消费者1个小时。现在30个消费者,需要10分钟搞定。 一般情况下,这个时候只能做临时扩容了。具体操作步骤和思路如下: ① 先修改consumer的问题,确保其恢复消费速度,然后将现有consumer都停掉。 ② 新建1个topic,partition是原来的10倍,临时建立好原来10倍或者20倍的Queue。 ③ 然后写一个临时的分发数据的consumer程序,这个程序部署上去,消费积压的数据。消费之后,不做耗时的处理。直接均匀轮训写入临时建立好的10倍数量的Queue。 ④ 接着征用10倍的机器来部署consume。每一批consumer消费1个临时的queue。 ⑤ 这种做法,相当于将queue资源和consume资源扩大10倍,以10倍的速度来消费数据。 ⑥ 等快速消费完积压数据之后,恢复原来的部署架构,重新用原先的consumer来消费消息。 如果让你写一个消息队列,该如何进行架构设计?说说你的思路? 1、首先MQ得支持可伸缩性吧。就是需要的时候增加吞吐量和容量? 2、其次,需要考虑一下MQ的数据是不是要持久化到磁盘 3、再次,考虑一下MQ的可用性。 4、最后,考虑一下能不能支持数据零丢失 首先这个mq得支持可伸缩性吧,就是需要的时候快速扩容,就可以增加吞吐量和容量,那怎么搞?设计个分布式的系统呗,参照一下kafka的设计理念,broker -> topic -> partition,每个partition放一个机器,就存一部分数据。如果现在资源不够了,简单啊,给topic增加partition,然后做数据迁移,增加机器,不就可以存放更多数据,提供更高的吞吐量了? 其次你得考虑一下这个mq的数据要不要落地磁盘吧?那肯定要了,落磁盘,才能保证别进程挂了数据就丢了。那落磁盘的时候怎么落啊?顺序写,这样就没有磁盘随机读写的寻址开销,磁盘顺序读写的性能是很高的,这就是kafka的思路。 (3)其次你考虑一下你的mq的可用性啊?这个事儿,具体参考我们之前可用性那个环节讲解的kafka的高可用保障机制。多副本 -> leader & follower -> broker挂了重新选举leader即可对外服务。 能不能支持数据0丢失啊?可以的,参考我们之前说的那个kafka数据零丢失方案 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 4:45:10- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |