面试题-RabbitMQ
前言
在面试题系列文章中,笔者本着效率的原则,没有总结RabbitMQ相关的知识,但是当其他知识点都总结完毕后,我发现如果面试中针对我们实际使用的RabbitMQ进行深入原理的提问或者说说框架使用的注意事项,那么我大概率是无法回答出来的。并且到目前为止,针对RabbitMQ的框架,我们项目组仅仅做到基本使用,没有做深入的研究,这篇文章名曰面试题,其实也是借着面试题让我们更加深入的了解RabbitMQ这个伟大的消息队列产品,所以,何乐而不为呢?
RabbitMQ
使用RabbitMQ有什么好处?
- 解耦:无论用redis还是rabbitmq传递分布式系统之间的数据交互,核心目的都是解耦
- 异步:用内存队列还是rabbitmq,通过队列存储不需要立即处理的业务,排队执行,可以加快主流程的响应速度
- 削峰:如果瞬时大量的并发请求都走数据库,对数据库来说是灾难的
使用了消息队列会有什么缺点?
- 系统的可用性降低
- 增加了系统设计的复杂度
RabbitMQ 概念里的 channel、exchange 和 queue 是逻辑概念,还是对应着进程实体?分别起什么作用?
- exchange内部实现为保存着对应关系的查找表;
- queue具有自己的erlang进程;
- channel是实现了路由工作的实体,负责按照rounting_key把消息投递到queue中,在AMQP中规定,channel是建立在真实的TCP/IP连接之上的虚拟连接,为了共享底层的TCP/IP资源,但是需要确定自己唯一的id。
vhost 是什么?起什么作用?
vhost可以理解为一个mini的broker,在实际应用中,不同的业务也会选择创建不同的vhost来实现业务隔离。
消息怎么路由?实际生产中用到的是那种路由方式?
rabbitmq中如果想实现正确的路由,需要定义队列,交换器和绑定的路由键,当发送消息的时候也需指定路由键,然后根据由交换器匹配具体的队列。rabbitmq支持三种方式的路由:
- direct:路由键完全匹配
- fanout:广播到所有绑定队列上
- topic:和direct比,属于通配符匹配,可以匹配多个队列
实际的生产实践中,大部分队列我们使用的是direct方式来进行路由,针对一个生产者多消费者的需求,我们使用fanout路由方式。
如何确保消息正确地发送至RabbitMQ?
RabbitMQ使用发送方确认模式,即将channel设置为confirm模式,这样所有发送过去的消息都会被指派一个唯一ID,发送方需要写一个异步的确认回调方法,处理确认状态和未确认状态的后续业务处理。
实际项目中,因为读写器发送过来的消息大部分是重复的,并且丢失几条对整体的判断区别不大,所以我们没有选择发送方确认模式。
如何确保消息接收方消费了消息?
RabbitMQ的消费者需要针对每条消息做消息确认。
消费者在订阅队列时,可以选择指定autoAck属性,如果为true,消息发送之后自动确认,rabbitmq就会删除消息;如果为false,需要消费者手动确认,并且在连接没有断掉的情况下,rabbtimq没有超时机制,会一直等待确认;如果连接断掉,rabbitmq会将此消息重新入队等待投递给下一个消费者。
除了确认以外,消费者还可以拒绝这条消息或者批量拒绝。
实际业务开发时,考虑到读写器会上传重复的大量数据,所以丢失几条也没关系,所以使用了RabbitListener的自动确认模式。
如何避免消息重复投递或重复消费?
首先需要确定,无论是broker还是consumer都是有可能收到重复的消息的,并且rabbitMQ提供的传递质量标准为至少一次,所以,如果确保重复消息不会影响我们的业务是需要在应用层面进行处理的。
具体的手段就是通过幂等性来解决重复消费的问题
- 利用数据库的唯一约束来实现幂等性(每个消费操作存入数据库,当出现重复数据时,主键会重复,所以无法入库)
- 利用前置条件实现幂等性
消息积压了该如何处理?你们的生产项目中有遇到过消息积压的问题吗?
消息积压,一般来说不是生产者变快了,就是消费者变慢了,我觉得这个问题不仅仅局限于rabbitMQ,使用内存队列也是一样的。当遇到积压问题时,要应该按照上面的思路核查问题。
我们的项目中也遇到过消息队列的积压问题,核心还是在于消费者的消费速度太慢,最后核查消费逻辑中使用redis的部分设计不够合理,针对这部分不太变化的内容,其实可以使用内存实现相同的功能,修改后,单消费线程的处理速度显著提高。另外,为了保证可用性,rabbtimq也支持配置多线程来消费队列的数据。
如何解决丢数据的问题?
丢数据的问题,可以按照消息的流转路径来分析。
- 生产者到broker之间丢了,可以采用confirm机制进行重传
- broker自己挂了,通过配置集群持久化等机制来实现可靠性保证
- 通过设置消费者的手动确认机制来实现可靠性
什么是死信队列?
当以下几种情况发生时,消息就会变成死信:
- 队列已满
- 消息被拒绝,并且无法重新入队
- 消息中过期时间超时
当消息变成死信时,rabbitmq会把消息发送到死信交换器进而投递到死信队列中,我们的程序可以监控这个队列,及时发现异常情况。
你了解延迟队列吗?延迟队列可以用在什么业务场景中?
延迟队列指的是消息发出后,并不想让消费者立即消费,而是等到一定时间后再消费该消息。
虽然我们业务中没有使用到这个延迟队列,但是我大致了解延迟队列的应用场景。比如:
- 延迟30分钟的未支付订单需要进行异常处理
- 用户需要定时操作智能家居,这种也可以使用延迟队列实现
延迟队列可以使用 RabbitMQ的过期时间和死信队列实现,通过设置消息的过期时间,然后投递到普通队列中,超时之后就会被投递到死信队列,真正的消费者监听的是死信队列。
消息队列能否保证消息按时间顺序消费?(线程池如何保证按照时间顺序消费任务?)
这个问题产生的原因是,我们想通过多个消费者提高系统的吞吐量,但是又无法保证消费顺序。
我们可以通过拆分成多个queue,一个queue对应一个消费者,相同id的数据一定会导入到同一个queue中,这样既可以增大吞吐量,又可以保证顺序了。
面试题-RabbitMQ的更多相关文章
- 消息中间件面试题31道RabbitMQ+ActiveMQ+Kafka
消息中间件面试题31道RabbitMQ+ActiveMQ+Kafka 前言 文章开始前,我们先了解一下什么是消息中间件? 什么是中间件? 非底层操作系统软件,非业务应用软件,不是直接给最终用户使用的, ...
- 最全最新java面试题系列全家桶(带答案)
最全最新java面试题系列全家桶(带答案) 置顶 2019年04月06日 22:40:28 青春季风暴 阅读数 14082 文章标签: java面试题技术栈 更多 分类专栏: 面试 版权声明:本文 ...
- 2019年12道RabbitMQ高频面试题你都会了吗?(含答案解析)
RabbitMQ 面试题 1.什么是 rabbitmq 2.为什么要使用 rabbitmq 3.使用 rabbitmq 的场景 4.如何确保消息正确地发送至 RabbitMQ? 如何确保消息接收方消费 ...
- 【面试突击】-RabbitMQ常见面试题(一)
rabbit面试题1.什么是rabbitmq采用AMQP高级消息队列协议的一种消息队列技术,最大的特点就是消费并不需要确保提供方存在,实现了服务之间的高度解耦 2.为什么要使用rabbitmq1.在分 ...
- RabbitMQ面试题集锦(精选)(另附思维导图)
1.使用RabbitMQ有什么好处? 1.解耦,系统A在代码中直接调用系统B和系统C的代码,如果将来D系统接入,系统A还需要修改代码,过于麻烦! 2.异步,将消息写入消息队列,非必要的业务逻辑以异步的 ...
- 消息队列面试题、RabbitMQ面试题、Kafka面试题、RocketMQ面试题 (史上最全、持续更新、吐血推荐)
文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...
- RabbitMQ面试题
1.为什么要引入MQ系统,直接读写数据库不行吗?其实就是问问你消息队列都有哪些使用场景,然后你项目里具体是什么场景,说说你在这个场景里用消息队列是什么? 面试官问你这个问题,期望的一个回答是说,你们公 ...
- 菜鸟刷面试题(二、RabbitMQ篇)
目录: rabbitmq 的使用场景有哪些? rabbitmq 有哪些重要的角色? rabbitmq 有哪些重要的组件? rabbitmq 中 vhost 的作用是什么? rabbitmq 的消息是怎 ...
- RabbitMQ几个常用面试题
以下观点,仅为个人理解的总结,如有错漏,欢迎指正! -------------------------------------------------------------------------- ...
- 【面试突击】-RabbitMQ常见面试题(三)
1.什么是RabbitMQ?为什么使用RabbitMQ? 答:RabbitMQ是一款开源的,Erlang编写的,基于AMQP协议的,消息中间件: 可以用它来:解耦.异步.削峰. 2.RabbitMQ有 ...
随机推荐
- 21. C++快速入门--协程 Coroutine 入门
参考: https://www.cnblogs.com/blizzard8204/p/17563217.html https://www.bennyhuo.com/2022/03/09/cpp-cor ...
- Bogus:.NET的假数据生成利器
我们在项目开发中,为了保证系统功能完整.准确性,我们都需要模拟真实数据进行测试. 今天推荐一个开源库,方便我们制造假数据测试. 01 项目简介 Bogus 是一个开源的 .NET 库,它提供了一个强大 ...
- 前端学习openLayers配合vue3(偏移动画效果,限制范围)
我们原来的偏移感觉比较生硬,我们来学习一下偏移的动画,先列一下这节的知识点 限制经纬度范围和缩放范围(view层) view = new View({ center:[114.305469,30.59 ...
- IdentityServer网页登陆-登陆原理
前言 现代程序开发中身份验证.授权是一件非常非常复杂的事情(各种登陆方式.各种授权需求.各种跳转跳.各种加解密,搞得得头皮发麻),因为事情本身复杂,所以没把这件事理清楚之前,无论你用什么语言.什么框架 ...
- Elasticsearch应用介绍
Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 Luce ...
- KKRT-PSI
KKRT库:https://github.com/osu-crypto/BaRK-OPRF 文章:Efficient Batched Oblivious PRF with Applications t ...
- Java线程的安全问题
当多个线程同时访问同一资源(变量,文件,记录),如果只有读操作,则不会有线程安全问题,如果有读和写操作,则会产生线程安全问题,必须保证共享数据同一时刻只能有同一个线程操作.Java采取的办法是sync ...
- changeServer.sh一键切换服务器脚本
直接看改进版2.0 切换服务器,免密登录vi changeServer.sh #!/bin/bash #authe by wangxp export IFCFG=/etc/sysconfig/netw ...
- Binomial Sum 学习笔记
- 单机麒麟kylin安装
https://archive.apache.org/dist/kylin/ 2.5.0版本 首先启动hadoop.hive.hbase 并记得设置环境变量 #JDK export JAVA_HOME ...