RabbitMQ常见问题

⭐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消息生产者发送消息后怎么知道消费者有没有收到消息呢

我:生产者可以通过setConfirmCallback方法设置回调函数,判断方法中的ack,如果ack为true则表示发送成功,如果ack为false则表示发送失败,这里是生产者向路由器发送消息的时候失败。 

在这里插入图片描述  

我:我们还可以通过setReturnCallback方法设置回调函数,这里是路由器向队列发送消息失败,比如该条消息根据路由键没有找到要发送到哪个队列中去。 

在这里插入图片描述 

面试官:那消费端这里怎么判断是否收到消息了呢 

我:消费端这里可以通过channel.basicAck()方法来确认收到消息。 

在这里插入图片描述 

面试官:那消费端这里处理收到的消息的时候发生异常怎么办? 

我:可以使用channel.basicNack()方法来拒绝消息,让MQ重新发送消息 

在这里插入图片描述 

面试官:我们消费端每次处理完消息都需要手动确认消息吗 

我:可以配置手动确认,也可以配置自动确认消息,在配置文件中配置 

在这里插入图片描述 

面试官:那一共有几种确认方式呢 

我:一共有三种确认方式。
1、自动确认:acknowledge=none
2、手动确认:acknowledge=manual
3、根据异常情况确认:acknowledge=auto 

 ⭐RabbitMQ过期时间设置、死信队列、延时队列怎么设计?

 面试官:RabbitMQ发送消息长时间没人处理过期怎么办?

我:消息长时间没人处理过期了我们为了不影响正常的交换机使用,我们可以将过期的消息放到一个死信交换机中,然后这个交换机绑定一个队列就是死信队列,然后通过一个专门的消费者来处理这些过期的消息 

在这里插入图片描述 

面试官:只有消息到达过期时间没有被消费会进入死信交换机吗,还有其他的情况吗 

我:消息成为死信一共有三种情况。
1:队列消息长度达到限制。
2:消费者拒收消息,并且不将消息放入原来的队列中让他重新发送。
3:原队列存在消息过期设置,消息达到超时时间未被消费。 

面试官:我们怎么定义一个死信交换机和死信队列绑定呢? 

我:我们可以通过x-dead-letter-exchangex-dead-letter-routing-key两个参数来配置好死信交换机的名称,和死信交换机与死信队列之间的路由键名称。 

在这里插入图片描述 

面试官:TTL是什么? 

我:TTL全称Time To Live(存活时间/过期时间),是mq中用来设置过期时间的。 

面试官:我们一般怎么设置过期时间,用哪些方式? 

我:我们有两种设置过期时间的方式,一个是对单个消息设置过期时间,一个是对一个队列设置过期时间,这样的话发送到队列中的消息都遵循那个过期时间。 

1:队列设置过期时间:x-message-ttl,单位:ms(毫秒),这样的话进入队列的所有消息都遵循这个过期时间。 

在这里插入图片描述 

2:单个消息设置过期时间:expiration,单位:ms(毫秒),这样的话只有这条消息有过期时间。 

在这里插入图片描述 

面试官:那如果我即给单条消息设置了时间又给队列设置了时间会怎么样? 

我:那样的话根据最短的那个时间来。 

RabbitMQ延时队列怎么设计? 

面试官:那你知道延时队列吗,一般都用来做什么场景下的需求呢?

我:知道,延时队列一般就是发送消息到MQ中后,消费者不要第一时间去处理,比如我们点外卖的时候我们下单成功了,这个时候库存已经减了,但是我们还没有支付,如果我们一直不支付的话,过30分钟订单就自动取消了,然后库存又恢复了。 

面试官:那RabbitMQ有延时队列吗,如果让你自己设计一个延时队列怎么设计呢? 

我:RabbitMQ中没有提供延时队列的功能,但是我们可以使用TTL+死信队列来实现延时队列的功能。 

在这里插入图片描述 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值