一、前言
RabbitMQ有很多高级特性,一般项目用不到,但是总有面试官会问到,被问到的时候我们要假装这些对我们来说就是小意思一样。
二、面试
面试官:小奇是吧,你先做一个自我介绍吧
我:面试官您好,我毕业于XXX,我之前在XXX工作,我精通XXX,总之一句话,我就是优秀,你问就完了。
面试官:行,你的自我介绍很强硬啊,那我看看你到底有没有过硬的实力
我:是骡子是马拉出来溜溜
三、RabbitMQ怎么实现消费端限流
面试官:好,那我先问你一个场景题,比如我们公司现在做了一个秒杀系统,在活动当天用户下单太多了,造成消费端崩溃了,这种情况我们该怎么处理呢
我:好说呀,多买几台服务器,多搭建几台消费端的服务,减缓服务端的压力,这样不就没有问题了吗。
面试官:额。。。你这么说确实可以解决,实不相瞒我们老板特别抠。。。不舍得买更多的服务器,就想让我们一台服务器搞定
我:???光让马儿跑,不让马儿吃草,那特么能行啊,跟你们老板说,让他自己出来顶着消费端的压力吧,他不是不舍得花钱吗,等秒杀的时候让他去用户那里捣乱,让用户不能够同一时间下单不就行了。
面试官:哎呀不行呀,我们也想过给用户捣乱,但是老板不让,老板说必须让用户在最短的时间内都完成下单
我:可以啊,那就使用MQ,让客户端下单后将下单信息放入消息队列中,然后让消费端去处理呗。
面试官:哎呀我们就是这么弄的,但是消费端总是崩溃
我:你们消费端服务器配置怎么样?
面试官:嗯。。消费端服务器配置是半核CPU、1G运行内存空间、10G磁盘空间
我: 半核? 你特么在逗我,另外半个CPU让别人掰走了?
面试官:嘿嘿,情况就是这么个情况,事情就是这么个事情,反正公司就是穷困潦倒,等你进来了我再慢慢跟你讲,你现在先帮我想一个解决方案,我用来应付一下老板
我:那就在消费端实现限流吧。
面试官:怎么实现呢?
我:使用channel.basicQos(int prefetchSize, int prefetchCount, boolean global)方法来设置限流的配置。
prefetchSize:表示消息的大小(0的话表示不限制大小)
prefetchCount:表示消息的数量
global:true表示该通道下的所有消费者都适用这个策略,而false表示只有当前这一个消费者适用这个策略。
如图,这里我们channel.basicQos(0,1,false);表示不限制消息的大小,但是限制消息的数量,一次只能给消费者发送一条消息。
面试官:为什么不限流的话会将消费端搞挂掉呢
我:假如现在小明的妈妈有10个饺子给小明吃,小明叫来了9个同学,然后他们一共10个人,一人一个饺子都是一口就吃完了没有任何问题,但是今天就小明一个人,总不能10个饺子一下塞到小明的嘴里面吧,这样直接将小明噎死了。
面试官:那怎么解决呢
我:现在小明先吃一个饺子,等小明吃完了这一个饺子后告诉他妈,说我吃完了,然后他妈再给他一个饺子吃,这样的话也是可以吃完10个饺子的,并且小明没有事。
面试官:我看限流的参数还有数据大小是干什么的
我:假如现在小明妈妈为了让小明一口就吃完十个饺子,他包了一个特别大的饺子,有一斤重,这个时候跟小明说还是一个饺子,一口闷吧,这个时候照样将小明噎死了,所以数据大小也是要限制的。
面试官:那队列怎么知道消费者消费完了一条消息,要给他再发送一条消息呢
我们要配置消费端手动确认,当我们消费端消费完消息后手动确认消息,这个时候队列就认为整个消费流程走完了,就开始下一个信息的发送了。
开启手动确认配置
代码中手动确认。
这里手动确认有两个参数,第一个是tag编号,就是这个消息的一个编号,第二个参数为是否确认多条,true的话就是确认多条消息,false的话就是只确认这一条消息,一般我们都是false。
面试官:可以呀小伙子,有点东西
我:请你不要迷恋哥,哥只是一个传说。。。
面试官:小伙子真厉害啊,一下子就把RabbitMQ消费端限流讲明白了,你面试通过了,明天上岗吧
我:啊,这么急吗,我后面还有好多东西没有讲呢。
面试官:不着急,进来了以后慢慢听你讲,加班让你跟我讲
我:啊。。。这也太难了吧
四、总结
这里关于RabbitMQ还没有整理完毕,文章后面持续更新,建议收藏。
文章中涉及到的命令大家一定要像我一样每个都敲几遍,只有在敲的过程中才能发现自己对命令是否真正的掌握了。