温馨提示:
以下需要控制台声明队列跟交换机的操作也可用代码实现,具体实现方式见以下文章:
Work queues,任务模型。简单来说就是让多个消费者绑定到一个队列,共同消费队列中的消息。
模拟WorkQueue,实现一个队列绑定多个消费者
基本思路如下
- 在RabbitMQ的控制台创建一个队列,名为work.queue
- 在publisher服务中定义测试方法,在1秒内产生50条消息,发送到work.queue
- 在consumer服务中定义两个消息监听者,都监听work.queue队列
- 消费者1每秒处理50条消息,消费者2每秒处理5条消息
控制台声明队列
代码实现
1、消息发送者
@Test
void testWorkQueue() throws InterruptedException {
String queueName = "work.queue";
for (int i = 1; i < 50; i++) {
String msg = "hello, amqp!!!work:msg....."+i;
rabbitTemplate.convertAndSend(queueName,msg);
Thread.sleep(20);
}
}
2、消息消费者
@RabbitListener(queues = "work.queue") //监听的队列:work.queue
public void listenWorkQueue1(String msg) throws InterruptedException {
System.out.println("消费者1收到消息:【"+msg+"】");
Thread.sleep(20); //模拟消费能力较高的消费者
}
@RabbitListener(queues = "work.queue") //监听的队列:work.queue
public void listenWorkQueue2(String msg) throws InterruptedException {
System.err.println("消费者2收到消息:【"+msg+"】");
Thread.sleep(200); //模拟消费能力较低的消费者
}
3、消费者消息推送限制
默认情况下,RabbitMO的会将消息依次轮询投递给绑定在队列上的每一个消费者。但这并没有考虑到消费者是否已经处理完消息,可能出现消息堆积。如下图:
因此我们需要修改application.yml,设置prefetch值为1,确保同一时刻最多投递给消费者1条消息,能者多劳。
spring:
rabbitmq:
listener:
simple:
prefetch: 1 #每次只能获取一条信息,处理完才能获取下一条信息,避免消息堆积
总结:
Work模型的使用:
- 多个消费者绑定到一个队列,可以加快消息处理速度
- 同一条消息只会被一个消费者处理
- 通过设置prefetch来控制消费者预取的消息数量,处理完一条再处理下一条,实现能者多劳