RabbitMQ高级特性之限流原理详解

  点击上方“JavaEdge”,关注公众号

设为“星标”,好文章不错过!

RabbitMQ高级特性之限流原理详解

1 消息过载场景

RabbitMQ高级特性之限流原理详解

假设Rabbitmq服务器有上万条未处理的消息,随便打开一个消费端,会造成巨量消息瞬间全部推送过来,然而我们单个客户端无法同时处理这么多数据。此时很有可能导致服务器崩溃,严重的可能导致线上的故障。
还有一些其他的场景,比如说单个Pro一分钟产生了几百条数据,但是单个Con一分钟可能只能处理60条,这时Pro-Con不平衡的。通常Pro没办法做限制,所以Con就需要做一些限流措施,否则如果超出最大负载,可能导致Con性能下降,服务器卡顿甚至崩溃等一系列严重后果。

因此,我们需要Con限流

RabbitMQ高级特性之限流原理详解

2 Con限流机制

RabbitMQ高级特性之限流原理详解

RabbitMQ提供了一种qos (服务质量保证)功能,在非自动确认消息的前提下,若一定数目的消息 (通过基于Con或者channel设置Qos的值) 未被确认前,不消费新的消息。

不能设置自动签收功能(autoAck = false)
如果消息未被确认,就不会到达Con,目的就是给Pro减压

RabbitMQ高级特性之限流原理详解

3 限流设置API

RabbitMQ高级特性之限流原理详解

basicQos

RabbitMQ高级特性之限流原理详解


RabbitMQ高级特性之限流原理详解

请求特定设置“服务质量(quality of service)”。这些设置强加数据的服务器将需要确认之前,为消费者发送的消息数量限制。因此,他们提供消费者发起的流量控制的一种手段。

RabbitMQ高级特性之限流原理详解
void BasicQos(uint prefetchSize, ushort prefetchCount, bool global);

  • prefetchSize: 单条消息的大小限制,Con通常设置为0,表示不做限制

  • prefetchCount: 一次最多能处理多少条消息

  • global: 是否将上面设置true应用于channel级别还是取false代表Con级别

prefetchSize和global这两项,RabbitMQ没有实现,不研究
prefetchCount在 autoAck=false 的情况下生效,即在自动应答的情况下该值无效,所以必须手工ACK。

basicAck

RabbitMQ高级特性之限流原理详解

void basicAck(Integer deliveryTag,boolean multiple)
调用这个方法就会主动回送给Broker一个应答,表示这条消息我处理完了,你可以给我下一条了。参数multiple表示是否批量签收,由于我们是一次处理一条消息,所以设置为false

RabbitMQ高级特性之限流原理详解

4 代码实战

RabbitMQ高级特性之限流原理详解

自定义Con
RabbitMQ高级特性之限流原理详解

Con
RabbitMQ高级特性之限流原理详解

Pro
RabbitMQ高级特性之限流原理详解

启动Con,查看管控台
RabbitMQ高级特性之限流原理详解RabbitMQ高级特性之限流原理详解

启动Pro,开始发送消息,Con接收消息
RabbitMQ高级特性之限流原理详解

实现限流,仅仅处理一条消息,其余的都在等待RabbitMQ高级特性之限流原理详解

现在,我们开启ACK应答处理
RabbitMQ高级特性之限流原理详解

重新启动Con,发现剩余的2条消息也全都发送并接收了!

我们之前是注释掉手工ACK方法,然后启动消费端和生产端,当时Con只打印一条消息,这是因为我们设置了手工签收,并且设置了一次只处理一条消息,当我们没有回送ACK应答时,Broker端就认为Con还没有处理完这条消息,基于这种限流机制就不会给Con发送新的消息了,所以Con那时只打印了一条消息
RabbitMQ高级特性之限流原理详解

RabbitMQ高级特性之限流原理详解

RabbitMQ高级特性之限流原理详解

目前交流群已有 800+人,旨在促进技术交流,可关注公众号添加笔者微信邀请进群

RabbitMQ高级特性之限流原理详解

喜欢文章,点个“在看、点赞、分享”素质三连支持一下~