Work queue,工作队列,可以提高消息处理速度,避免队列消息堆积
模拟WorkQueue,实现一个队列绑定多个消费者
基本思路如下:
- 在publisher服务中定义测试方法,每秒产生50条消息,发送到simple.queue
- 在consumer服务中定义两个消息监听者,都监听simple.queue队列
- 一个消息监听者每秒处理50条消息,另一个消费者每秒处理10条消息
生产者循环发送消息到simple.queue
@Test public void testWorkQueue() throws InterruptedException { String queueName = "simple.queue"; String message = "hello, work queue message====="; for (int i = 0; i < 50; i++) { rabbitTemplate.convertAndSend(queueName, message + i); Thread.sleep(20); } }
编写两个消费者,都监听simple.queue
@RabbitListener(queues = "simple.queue") public void listenWorkQueue1(String msg) throws InterruptedException { System.out.println("listenWorkQueue1 消费者接收到消息 :【" + msg + "】"); Thread.sleep(25); } @RabbitListener(queues = "simple.queue") public void listenWorkQueue2(String msg) throws InterruptedException { System.err.println("listenWorkQueue2 消费者接收到消息 :【" + msg + "】"); Thread.sleep(100); }
运行结果发现消费者监听不会因为监听性能好而多处理消息,而是信息被平均分配处理,这是由RabbitMQ内部消息预取机制造成
消息预取:当有大量的消息发送到队列,队列会提前将消息依次投递给每个消息消费者,不会关心消费者处理能力。
消息预取限制
修改application.yml文件,设置preFetch这个值,可以控制预取消息的上限
spring: rabbitmq: host: 192.168.223.128 # 主机名 port: 5672 # 端口 virtual-host: / # 虚拟主机 username: guest # 用户名 password: guest # 密码 listener: simple: prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一个消息