最近刚学完RabbitMQ,趁机整理了一下常用的口试题伊伊系列,用于总结跟追思,也供诸君大佬参考,如有差别的所在,接待指出哈!
1、为什么要使用MQ1、流量消峰举个例子:如果订单系统最多能处理一万次订单,这个处明智商应付平日时段的下单时绰绰多余,平日时段咱们下单一秒后就能复返收尾。然则在岑岭期,如果有两万次下单操作系统是处理不了的,只可放荡订单跨越一万后不允许用户下单。使用音书队伍作念缓冲,咱们不错取消这个放荡,把一秒内下的订单分散成一段技术来处理,这时有些用户可能不才单十几秒后才略收到下单凯旋的操作,然则比不可下单的体验要好。
2、应用解耦以电商应用为例,应用中有订单系统、库存系统、物流系统、支付系统。用户创建订单后,如果耦合调用库存系统、物流系统、支付系统,任何一个子系统出了故障,齐会酿成下单操作特殊。当转机成基于音书队伍的表情后,系统间调用的问题会减少许多,比如物流系统因为发生故障,需要几分钟来开拓。在这几分钟的技术里,物流系统要处理的内存被缓存在音书队伍中,用户的下单操作不错平日完成。当物流系统复兴后,连续处理订单信息即可,中单用户感受不到物流系统的故障,擢升系统的可用性。
图片
3、异步处理有些处事间调用是异步的,举例 A 调用 B,B 需要花费很长技术执行,然则 A 需要知谈 B 什么时候不错执行完,已往一般有两种表情:
A 过一段技术去调用 B 的查询 api 查询
A 提供一个 callback api, B 执行完之后调用 api 见知 A 处事。
这两种表情齐不是很优雅,使用音书总线,不错很便捷科罚这个问题,A 调用 B 处事后,只需要监听 B 处理完成的音书,当 B 处理完成后,会发送一条音书给 MQ,MQ 会将此音书转发给 A 处事。这么 A 处事既不必轮回调用 B 的查询 api,也不必提供 callback api。不异 B 处事也不必作念这些操作。A 处事还能实时的得到异步处理凯旋的音书。
图片
2、什么是RabbitMQRabbitMQ是一个音书中间件:它接受并转发音书。你不错把它看成念一个快递站点,当你要发送一个包裹时,你把你的包裹放到快递站,快递员最终会把你的快寄递到收件东谈主那儿,按照这种逻辑RabbitMQ是一个快递站,一个快递员帮你传递快件。RabbitMQ与快递站的主要区别在于,它不处理快件而是经受,存储和转发音书数据。
3、RabbitMQ各组件的功能Server:经受客户端的贯穿,杀青AMQP实体处事。
Connection:贯穿,应用设施与Server的收集贯穿,TCP贯穿。
Channel:信谈,音书读写等操作在信谈中进行。客户端不错建立多个信谈,每个信谈代表一个会话任务。如果每一次拜谒 RabbitMQ 齐建立一个 Connection,在音书量大的时候建立 TCP Connection 的支出将是强大的,恶果也较低。Channel 是在 connection 里面建立的逻辑贯穿,如果应用设施维持多线程,持续每个 thread 创建单独的 channel 进行通信,AMQP method 包含了 channel id 匡助客户端和 message broker 识别 channel,是以 channel 之间是实足停止的。Channel 作为轻量级的
Connection极大减少了操作系统建立TCP connection的支出
Message:音书,应用设施和处事器之间传送的数据,音书不错相称简便,也不错很复杂。由Properties和Body构成。Properties为外包装,不错对音书进行修饰,比如音书的优先级、延长等高等特色;Body即是音书体本色。
Virtual Host:编造主机,用于逻辑停止。一个编造主机里面不错有些许个Exchange和Queue,归并个编造主机里面不可有调换称号的Exchange或Queue。
Exchange:交换器,经受音书,按照路由司法将音书路由到一个或者多个队伍。如果路由不到,或者复返给坐褥者,或者径直丢弃。RabbitMQ常用的交换器常用类型有direct、topic、fanout、headers四种,后头扎眼先容。
Binding:绑定,交换器和音书队伍之间的编造贯穿,绑定中不错包含一个或者多个RoutingKey,Binding 信息被保存到 exchange 中的查询表中,用于 message 的分发依据
RoutingKey:路由键,坐褥者将音书发送给交换器的时候,会发送一个RoutingKey,用来指定路由司法,这么交换器就知谈把音书发送到哪个队伍。路由键持续为一个“.”分割的字符串,举例“com.rabbitmq”。
Queue:音书队伍,用来保存音书,供消费者消费。
3、RabbitMQ使命旨趣不得不看一下经典的图了,如下👇
图片
AMQP 公约模子由三部分构成:坐褥者、消费者和处事端,执行历程如下:
坐褥者是贯穿到 Server,建立一个贯穿,开启一个信谈。
坐褥者声明交换器和队伍,设立联系属性,并通过路由键将交换器和队伍进行绑定。
消费者也需要进行建立贯穿,开启信谈等操作,便于经受音书。
坐褥者发送音书,发送到处事端中的编造主机。
编造主机中的交换器证据路由键聘用路由司法,发送到不同的音书队伍中。
订阅了音书队伍的消费者就不错获取到音书,进行消费。
4、RabbitMQ 上的一个 queue 中存放的 message 是否稀有量放荡?不错合计是无放荡,因为放荡取决于机器的内存,然则音书过多会导致处理恶果的下落。
5、RabbitMQ 允许发送的 message 最大可达多大?证据 AMQP 公约司法,音书体的大小由 64-bit 的值来指定,是以你就不错知谈到底能发多大的数据了
6、RabbitMQ的使命形态1、simple形态(即最简便的收发形态)图片
音书产生音书,将音书放入队伍
音书的消费者(consumer) 监听 音书队伍,如果队伍中有音书,就消费掉,音书被拿走后,自动从队伍中删除(隐患 音书可能莫得被消费者正确处理,依然从队伍中灭绝了,酿成音书的丢失,这里不错设立成手动的ack,但如果设立成手动ack,处理完后要实时发送ack音书给队伍,不然会酿成内存溢出)。
2、Work Queues(使命队伍)图片
音书产生者将音书放入队伍消费者不错有多个,消费者1,消费者2同期监听归并个队伍,音书被消费。C1 C2共同争抢刻下的音书队伍本色,谁先拿到谁认真消费音书(隐患:高并发情况下,默许会产生某一个音书被多个消费者共同使用,不错设立一个开关(syncronize) 保证一条音书只可被一个消费者使用)。
3、publish/subscribe发布订阅(分享资源)图片
每个消费者监听我方的队伍;
坐褥者将音书发给broker,由交换机将音书转发到绑定此交换机的每个队伍,欧美童模写真每个绑定交换机的队伍齐将经受到音书。
4、routing路由形态图片
音书坐褥者将音书发送给交换机按照路由判断,路由是字符串(info) 刻下产生的音书佩带路由字符(对象的次序),交换机证据路由的key,只可匹配开赴由key对应的音书队伍,对应的消费者才略消费音书;
证据业务功能界说路由字符串
从系统的代码逻辑中获取对应的功能字符串,将音书任务扔到对应的队伍中。
业务场景:error 见知;EXCEPTION;失误见知的功能;传统兴趣的失误见知;客户见知;应用key路由,不错将设施中的失误封装成音书传入到音书队伍中,开发者不错自界说消费者,实时经受失误;
5、topic 主题形态(路由形态的一种)图片
星号井号代表通配符
星号代表多个单词,井号代表一个单词
路由功能添加疲塌匹配
音书产生者产生音书,把消圮绝给交换机
交换机证据key的司法疲塌匹配到对应的队伍,由队伍的监听消费者经受音书消费
PS:(在我的意会看来即是routing查询的一种疲塌匹配,就访佛sql的疲塌查询表情)
7、怎样保证RabbitMQ音书的礼貌性?拆分多个 queue(音书队伍),每个 queue(音书队伍) 一个 consumer(消费者),即是多一些 queue(音书队伍)辛苦,如实是贫苦点;
或者就一个 queue (音书队伍)然则对应一个 consumer(消费者),然后这个 consumer(消费者)里面用内存队伍作念列队,然后分发给底层不同的 worker 来处理。
8、RabbitMQ音书丢失的情况有哪些?坐褥者发送音书RabbitMQ Server 音书丢失
RabbitMQ Server中存储的音书丢失
RabbitMQ Server中存储的音书分发给消费者者丢失
1、坐褥者发送音书RabbitMQ Server 音书丢失发送过程中存在收集问题,导致音书莫得发送凯旋
代码问题,导致音书没发送
2、RabbitMQ Server中存储的音书丢失音书莫得抓久化,处事器重启导致存储的音书丢失
3、RabbitMQ Server到消费者音书丢失消费端经受到联系音书之后,消费端还没来得及处理音书,消费端机器就宕机了
处理音书存在特殊
9、RabbitMQ怎样保证音书不丢失?针对上头的情况,确保音书不丢失
坐褥者发送音书RabbitMQ Server 音书丢失科罚决策:
常用科罚决策:发送方证明机制(publisher confirm)
开启AMQP的事务处理(不保举)
RabbitMQ Server中存储的音书丢失科罚决策:
音书回退:通过设立 mandatory 参数不错在当音书传递过程中不可达贪图地时将音书复返给坐褥者
设立抓久化:保证重启过程中,交换机和队伍亦然抓久化的
RabbitMQ Server到消费者音书丢失科罚决策:
手动ack证明机制
1、坐褥者发送音书RabbitMQ Server 音书丢失科罚决策1、发布证明机制坐褥者将信谈设立成 confirm 形态,一朝信谈参预 confirm 形态,所有在该信谈上头发布的音书齐将会被指派一个唯独的 ID(从 1 启动),一朝音书被送达到所有匹配的队伍之后,broker就会发送一个证明给坐褥者(包含音书的唯独 ID),这就使得坐褥者知谈音书依然正确到达贪图队伍了,如果音书和队伍是可抓久化的,那么证明音书会在将音书写入磁盘之后发出,broker 回传给坐褥者的证明音书中 delivery-tag 域包含了证明音书的序列号,此外 broker 也不错设立basic.ack的 multiple 域,暗示到这个序列号之前的所有音书齐依然得到了处理。confirm 形态最大的平允在于它是异步的,一朝发布一条音书,坐褥者应用设施就不错在等信谈复返证明的同期连续发送下一条音书,当音书最终得到证明之后,坐褥者应用便不错通过回调次序来处理该证明音书,如果 RabbitMQ 因为自己里面失误导致音书丢失,就会发送一条 nack 音书,坐褥者应用设施不异不错在回调次序中处理该 nack 音书。
发布证明分为三种:
单独发布证明:这是一种简便的证明表情,它是一种同步证明发布的表情,也即是发布一个音书之后唯有它被证明发布,后续的音书才略连续发布,waitForConfirmsOrDie(long)这个次序唯有在音书被证明的时候才复返,如果在指定技术范围内这个音书莫得被证明那么它将抛出特殊。
这种证明表情有一个最大的污点即是:**发布速率尽头的慢,**因为如果莫得证明发布的音书就会阻止所有后续音书的发布,这种表情最多提供每秒不跨越数百条发布音书的朦拢量。天然关于某些应用设施来说这可能依然实足了。
批量发布证明:上头那种表情相称慢,与单个恭候证明音书比拟,先发布一批音书然后通盘证明不错极地面提高朦拢量,天然这种表情的污点即是:当发生故障导致发布出现问题时,不知谈是哪个音书出现问题了,咱们必须将整个批处理保存在内存中,以纪录紧迫的信息此后再行发布音书。天然这种决策仍然是同步的,也一样阻止音书的发布。
异步发布证明:异步证明诚然编程逻辑比上两个要复杂,然则性价比最高,无论是可靠性照旧恶果齐没得说,他是应用回调函数来达到音书可靠性传递的,这个中间件亦然通过函数回调来保证是否送达凯旋
2、开启AMQP的事务处理(不保举)为什么不保举呢,因为它是同步的,一条音书发送之后会使发送端阻止,以恭候RabbitMQ Server的回应,之后才略连续发送下一条音书,坐褥者坐褥音书的朦拢量和性能齐会大大缩小,这就跟单独发布证明一样。
怎样使用:在坐褥者发送音书之前,通过channel.txSelect开启一个事务,接着发送音书, 如果音书送达server失败,进行事务回滚channel.txRollback,然后再行发送, 如果server收到音书,就提交事务channel.txCommit
2、RabbitMQ Server中存储的音书丢失科罚决策第一种保证音书丢失,只大意保证发送方发送音书凯旋到达交换机,若此时处事器存在问题或者绑定的routingKey不正确,导致音书发送失败,那么音书最终也会丢失。
接管音书回退:通过设立 mandatory 参数不错在当音书传递过程中不可达贪图地时将音书复返给坐褥者
设立抓久化
1、音书回退源码:
mandatory参数 true:交换机无法将音书进行路由时,会将该音书复返给坐褥者 false:如果发现音书无法进行路由,则径直丢弃public void basicPublish(String exchange, String routingKey, boolean mandatory, BasicProperties props, byte[] body) throws IOException { this.delegate.basicPublish(exchange, routingKey, mandatory, props, body);}
有了 mandatory 参数和回退音书,咱们得回了对无法送达音书的感知智商,有契机在坐褥者的音书无法被送达时发现并处理。但巧合候,咱们并不知谈该怎样处理这些无法路由的音书,最多打个日记,然后触发报警,再来手动处理。而通过日记来处理这些无法路由的音书是很不优雅的作念法,尽头是当坐褥者所在的处事有多台机器的时候,手动复制日记会愈加贫苦而且容易出错。
这时需要接管备份交换机了
备份交换机不错意会为 RabbitMQ 中交换机的“备胎”,当咱们为某一个交换机声明一个对应的备份交换机时,
即是为它创建一个备胎,当交换机经受到一条不可路由音书时,将会把这条音书转发到备份交换机中,由备份交换机来进行转发和处理,持续备份交换机的类型为 Fanout ,这么就能把所有音书齐送达到与其绑定的队伍中,然后咱们在备份交换机下绑定一个队伍,这么所有那些原交换机无法被路由的音书,就会齐参预这个队伍了。天然,咱们还不错建立一个报警队伍,用孤苦的消费者来进行监测和报警。
三级片在线具体代码请参考这篇:
2、设立抓久化上头咱们的角度是站在坐褥者的方针,然则如果处事器重启了,此时交换机和队伍齐不存在了,音书存在也发送不了,这时需要把交换机和队伍齐抓久化。
/** * 生成一个队伍 * 1.队伍称号 * 2.队伍里面的音书是否抓久化 默许音书存储在内存中 * 3.该队伍是否只供一个消费者进行消费 是否进行分享 true 不错多个消费者消费 * 4.是否自动删除 终末一个消费者端开贯穿以后 该队伍是否自动删除 true 自动删除 * 5.其他参数 */channel.queueDeclare(QUEUE_NAME, false, false, false, null);
3、RabbitMQ Server到消费者音书丢失科罚决策默许音书接管的是自动草率,是以咱们要想杀青音书消费过程中不丢失,需要把自动草率改为手动草率
//将自动草率关闭boolean autoAck = false;channel.basicConsume(TASK_QUEUE_NAME, autoAck, deliverCallback, consumerTag -> { });
10、RabbitMQ音书基于什么传输?由于 TCP 贯穿的创建和捐躯支出较大,且并发数受系统资源放荡,会酿成性能瓶颈。RabbitMQ 使用信谈的表情来传输数据。信谈是建立在真正的 TCP 贯穿内的编造贯穿,且每条 TCP 贯穿上的信谈数目莫得放荡。
11、RabbitMQ维持音书的幂等性吗?维持。在音书坐褥时,MQ 里面针对每条坐褥者发送的音书生成一个 inner-msg-id,作为去重的依据(音书送达失败并重传),幸免重叠的音书参预队伍。
在音书消费时,要求音书体中必须要有一个 bizId(关于归并业务全局唯独,如支付 ID、订单 ID、帖子 ID 等)作为去重的依据,幸免归并条音书被重叠消费。
12、RabbitMQ何如确保音书已被消费?消费端建设手动ACK证明机制
纠合数据库进事业态记号处理
13、RabbitMQ维持事务音书吗?维持事务音书。前边在第9题中保证坐褥者不丢失音书,提到不错使用AMQP的事务,然则它是同步的,是以不何如保举使用
事务的杀青主如果对信谈(Channel)的设立,主要次序如下:1. channel.txSelect() 声明启动事务形态2.channel.txCommit() 提交事务3.channel.txRollback()回滚事务14、RabbitMQ音书抓久化的条目?音书抓久化,天然前提是队伍必须抓久化
声明队伍必须设立抓久化 durable 设立为 true.
音书推送送达形态必须设立抓久化,deliveryMode 设立为 2(抓久)。
音书依然到达抓久化交换器。
音书依然到达抓久化队伍。
15、RabiitMQ音书什么情况下会变成死信音书?由于特定的原因导致queue中的某些音书无法被消费,这么的音书如果莫得后续的处理,就变成了死信音书
16、RabbitMQ死信音书的起首?音书 TTL 落后
队伍达到最大长度(队伍满了,无法再添加数据到 mq 中)
音书被拒却(basic.reject 或 basic.nack)况兼 requeue=false.
17、RabbitMQ死信队伍的用处?不错用于杀青延长队伍
18、RabbitMQ维持延长队伍吗?维持。延时队伍,队伍里面是有序的,最紧迫的特色就体当今它的延时属性上,延时队伍中的元素是但愿在指定技术到了以后或之前取出和处理,简便来说,延时队伍即是用来存放需要在指定技术被处理的元素的队伍。
19、RabbitMQ延长队伍的使用场景订单在十分钟之内未支付则自动取消
新创建的店铺,如果在十天内齐莫得上传过商品,则自动发送音书指示
用户注册凯旋后,如果三天内莫得登陆则进行短信指示
用户发起退款,如果三天内莫得得到处理则见知联系运营东谈主员
预定会议后,需要在预定的技术点前十分钟见知各个与会东谈主员参加会议
20、RabbitMQ杀青延长队伍的有什么条目?音书设立TTL
建设了死信队伍
21、RabbitMQ何如杀青优先级队伍?适度台页面:添加一个x-max-priority
图片
坐褥者添加优先级,案例代码
public class Product { private static final String QUEUE_NAME = 'hello'; public static void main(String[] args) throws Exception { try(Channel channel = RabbitMQConfig.getChannel()){ //给音书赋予一个 priority 属性 AMQP.BasicProperties basicProperties = new AMQP.BasicProperties().builder().priority(5).build(); for (int i = 1; i < 11; i ) { String msg = 'info' i; if(i==5){ channel.basicPublish('', QUEUE_NAME, basicProperties, msg.getBytes()); }else{ channel.basicPublish('', QUEUE_NAME, null, msg.getBytes()); } System.out.println('发送音书完成:' msg); } } }}
消费者队伍中代码添加优先级
public class Consumer { private static final String QUEUE_NAME = 'hello'; public static void main(String[] args) throws Exception { Channel channel = RabbitMQConfig.getChannel(); //设立队伍的最大优先级 最大不错设立到 255 官网保举 1-10 如果设立太高比较吃内存和 CPU Map<String, Object> map = new HashMap<>(); map.put('x-max-priority', 10); channel.queueDeclare(QUEUE_NAME, true, false, false, map); System.out.println('消费者恭候启动经受音书......'); DeliverCallback deliverCallback = (consumerTag, delivery) ->{ String receivedMessage = new String(delivery.getBody()); System.out.println('经受到音书:' receivedMessage); }; channel.basicConsume(QUEUE_NAME, true, deliverCallback, (consumerTag) ->{ System.out.println('消费者无法消费音书时调用,如队伍被删除'); }); }}
22、哪些情况下保举使用RabbitMQ的惰性队伍队伍可能会产生音书堆积
队伍对性能(朦拢量)的要求不是相称高,举例TPS 1万以下的场景
但愿队伍有领略的坐褥消费性能,不受内存影响而波动
23、RabbitMQ怎样处理音书堆积情况?次序:临时扩容,快速处理积压的音书
先开拓 consumer 的问题,确保其复兴消费速率,然后将现存的 consumer 齐停掉;
临时创建原先 N 倍数目的 queue ,然后写一个临时间发数据的消费者设施,将该设施部署上去消费队伍中积压的数据,消费之后不作念任何耗时处理,径直均匀轮询写入临时建立好的 N 倍数目的 queue 中;
接着,临时征用 N 倍的机器来部署 consumer,每个 consumer 消费一个临时 queue 的数据
等快速消费完积压数据之后,恢收复先部署架构 ,再行用原先的 consumer 机器消费音书。
这种作念法相称于临时将 queue 资源和 consumer 资源扩大 N 倍,以平日 N 倍速率消费。
24、RabbitMQ怎样处理音书堆积过程中丢失的数据?接管**“批量重导”**的表情,在流量低峰期,写一个设施,手动去查询丢失的那部分数据,然后将音书再行发送到mq里面,把丢失的数据再行补回首。
25、RabbitMQ怎样处理长技术未处理导致写满的情况?如果音书积压在RabbitMQ里,况兼长技术齐没处理掉,导致RabbitMQ齐快写满了,这种情况细目是临时扩容决策执行太慢;这种时候只好接管 “丢弃 批量重导”的表情来科罚了。领先,临时写个设施,贯穿到RabbitMQ里面消费数据,消费一个丢弃一个,快速消费掉积压的音书,缩小RabbitMQ的压力,然后在流量低峰期时去手动查询重导丢失的这部分数据。
26、怎样想象一个音书队伍?要探究三点:伸缩性、抓久化、可用性
伸缩性:需要扩容的时候不错快速扩容,加多朦拢量和容量;不错参考kafaka的想象理念,broker -> topic -> partition,每个partition放一个机器,就存一部分数据;资源不够了,给topic加多partition,然后作念数据移动,加多机器;
抓久化:也即是数据要不要写入磁盘,不写入吧,进度挂了,数据就丢失了,写入磁盘该怎样高效写入呢?kafaka的念念路:礼貌读写,接管磁盘缓存(Page Cache)的战术,操作系统接管预读和后写的表情,对磁盘进行优化。
预读:磁盘礼貌读取的恶果是很高的(不需要寻谈技术,只需要很少的旋转技术)。而在读取磁盘某块数据时,同期会礼貌读取相邻地址的数据加载到PageCache,这么在读取后续连气儿数据时,只需要从PageCache中读取数据,相称于内存读写,速率会尽头快
后写:数据并不是径直写入到磁盘,而是默许先写入到Page Cache,再由Page Cache刷新到磁盘,刷新频率是由操作系统周期性的sync触发的(用户也不错手动调用sync触发刷新操作)。后写的表情大大减少对磁盘的总写入次数,提高写入恶果
可用性:分散式系统的高可用险些齐是通过冗余杀青的伊伊系列,Kafka不异如斯。Kafka的音书存储到partition中,每个partition在其他的broker中齐存在多个副本。对外通过主partition提供读写处事,当主partition所在的broker故障时,通过HA机制,将其他Broker上的某个副本partition会再行选举成主partition,连续对外提供处事。
本站仅提供存储处事,所有本色均由用户发布,如发现存害或侵权本色,请点击举报。