大厂如何用RabbitMQ作消费端限流

1 消息过载

假设RabbitMQ服务器有上万条未处理消息,随便打开一个消费端,会形成巨量消息瞬间所有推送过来,然而咱们单个客户端没法同时处理这么多数据。java

还好比说单个Pro一分钟产生了几百条数据,可是单个Con一分钟可能只能处理60条,这时Pro-Con不平衡。一般Pro没办法作限制,因此Con就须要作一些限流措施,不然若是超出最大负载,可能致使Con性能降低,服务器卡顿甚至崩溃。服务器

所以,咱们须要Con限流。markdown

2 Con限流机制

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

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

限流设置API

basicQos

  • QoS

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

void BasicQos(uint prefetchSize, ushort prefetchCount, bool global);
复制代码
  • prefetchSize: 单条消息的大小限制,Con一般设置为0,表示不作限制
  • prefetchCount: 一次最多能处理多少条消息
  • global: 是否将上面设置true应用于channel级别仍是取false表明Con级别

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

void basicAck(Integer deliveryTag,boolean multiple) 复制代码

调用该方法就会主动回送给Broker一个应答,表示这条消息我处理完了,你能够给我下一条了。参数multiple表示是否批量签收,因为咱们是一次处理一条消息,因此设置为false。code

3 代码实战

  • 自定义Con

  • Con

  • Pro

  • 启动Con,查看管控台

  • 启动Pro,开始发送消息,Con接收消息

  • 实现限流,仅仅处理一条消息,其他的都在等待
  • 如今,咱们开启ACK应答处理

  • 从新启动Con,发现剩余的2条消息也全都发送并接收了!
  • 咱们以前是注释掉手工ACK方法,而后启动消费端和生产端,当时Con只打印一条消息,这是由于咱们设置了手工签收,而且设置了一次只处理一条消息,当咱们没有回送ACK应答时,Broker端就认为Con尚未处理完这条消息,基于这种限流机制就不会给Con发送新的消息了,因此Con那时只打印了一条消息

相关文章
相关标签/搜索