1、手动新建队列demo
2、创建两个消费者模拟接收并重启项目
ListenWorkQueue1接收一条消息休眠20毫秒
ListenWorkQueue2接收一条消息休眠200毫秒
@RabbitListener(queues = "demo")
public void ListenWorkQueue1(String msg) throws InterruptedException {
System.out.println("消费者1接受到消息" + msg + LocalTime.now());
Thread.sleep(20); //接收一条消息后休眠20毫秒
}
@RabbitListener(queues = "demo")
public void ListenWorkQueue2(String msg) throws InterruptedException {
System.err.println("消费者2接受到消息" + msg + LocalTime.now());
Thread.sleep(200); //接收一条消息后休眠200毫秒
}
3、创建消息发送的测试类并执行
发送50条消息
@Test
public void testSendMessage(){
String queueName="demo";
String message="hello,spring amqp===";
for (int i = 0; i < 50; i++) {
rabbitTemplate.convertAndSend(queueName,message + i);
}
}
4、可以看到ListenWorkQueue1要比ListenWorkQueue2的执行效率高
5、优化
WorkQueue默认是轮询分发,也就是将生产者生产的消息一次性平均分配给消费者,当分配完消息后,它的自动确认机制会一次性全部确认,产生的问题如下:
1、当生产者生产了50个消息,2个消费者平均分到了25个消息,当消费者1消费完10个消息时不明原因宕机了,剩余的15个消息则会丢失
2、当消费者2执行效率低于消费者1时会影响程序最终执行效率
所以我们这里需要在消费者的application.yml文件中增加prefetch控制消费者预取个数
spring:
rabbitmq:
host: 192.168.201.128 # rabbitMQ的ip地址
port: 5672 # 端口
username: itcast
password: 123321
virtual-host: /
listener:
simple:
prefetch: 1 #消息预取每次一条
6、再次测试
可以看到消费者1执行效率比消费者2执行效率高,这样就实现了能者多劳,保证程序最终运行效率