Rabbitmq 高级特性 - 消费端限流
-
消费端步骤(在原有RabbitMQ 高级特性 Consumer Ack的基础)
-
新建信监听类
package com.yang.listener; import com.rabbitmq.client.Channel; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener; import org.springframework.stereotype.Component; /** * consumer限流机制 */ @Component public class QosListener implements ChannelAwareMessageListener { @Override public void onMessage(Message message, Channel channel) throws Exception { } }
-
限流的步骤
-
确保ack机制为手动签收(配置文件监听容器哪里
acknowledge="manual"
)<!-- 定义监听器容器 --> <rabbitmq:listener-container connection-factory="connectionFactory" acknowledge="manual"> <rabbit:listener ref="qosListener" queue-names="test_queue_confirm"/> </rabbitmq:listener-container>
-
Listener-container配置属性(刚刚定义监听器容器哪里配
prefetch="1"
)<rabbitmq:listener-container connection-factory="connectionFactory" acknowledge="manual" prefetch="1"> <rabbit:listener ref="qosListener" queue-names="test_queue_confirm"/> </rabbitmq:listener-container>
-
-
完整代码
package com.yang.listener; import com.rabbitmq.client.Channel; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener; import org.springframework.stereotype.Component; /** * consumer限流机制 * 1. 确保ack机制为手动签收 * 2. Listener-container配置属性 * perfetch = 1, 表示消费端每次从mq来消费,知道手动确认完毕后,才会继续拉取下一条消息 */ @Component public class QosListener implements ChannelAwareMessageListener { @Override public void onMessage(Message message, Channel channel) throws Exception { //1. 获取消息 System.out.println(new String(message.getBody())); //2. 处理业务逻辑 System.out.println("处理业务逻辑"); //3. 签收 channel.basicAck(message.getMessageProperties().getDeliveryTag(),true); } }
-
在以前写过的代码生成者里面,发送请求(
RabbitMQ 高级特性 - 消息的可靠性投递
)@Test public void testSend() { for (int i = 0; i < 10; i++) { //1. 发送消息 rabbitTemplate.convertAndSend("test_exchange_confirm","confirm","message confirm ..."); } }
-
为了看到效果把签收消息注释调,这样它只会拉取一条,来消费因为它认为我们还没有完成.
@Component public class QosListener implements ChannelAwareMessageListener { @Override public void onMessage(Message message, Channel channel) throws Exception { //1. 获取消息 System.out.println(new String(message.getBody())); //2. 处理业务逻辑 System.out.println("处理业务逻辑"); //3. 签收 // channel.basicAck(message.getMessageProperties().getDeliveryTag(),true); } }
-
运行结果
-
使用接受的签收的(为了看到效果,每次停止1秒)
@Component public class QosListener implements ChannelAwareMessageListener { @Override public void onMessage(Message message, Channel channel) throws Exception { //1. 获取消息 System.out.println(new String(message.getBody())); //2. 处理业务逻辑 System.out.println("处理业务逻辑"); //3. 签收 channel.basicAck(message.getMessageProperties().getDeliveryTag(),true); Thread.sleep(1000); } }
-
运行结果(可以看到间隔一秒一条,图片看不出)
-
- 消费端限流小结
- 在rabbit:listener-container 中配置 prefetch属性设置消费端一次拉取多少消息
- 消费端的确认模式一定为手动确认。acknowledge=“manual”
- 一定要手动确认!
- 一定要手动确认!
- 一定要手动确认!