项目基础结构参考:
源码:
生产者源码:https://gitee.com/constfafa/rabbitmq-producer-workqueue
消费者1源码:https://gitee.com/constfafa/rabbitmq-consumer-workqueue01
消费者2源码:https://gitee.com/constfafa/rabbitmq-consumer-workqueue02
工作过程
生产者每隔1秒发送一条信息到test_work_queue队列中
工作队列有两种工作方式:
轮询分发round-robin:
代码里进行了测试,将consumer01线程暂停4秒再执行,在round-robin情况下,仍会轮询分发。
结果:
生产者
消费者1:
由于sleep 4s,所以执行起来要比消费者2慢很多
消费者2:
虽然消费者2执行的快,但是由于设置为round-robin,不会多进行消息处理
公平分发fairdispatch:
告诉RabbitMQ不要同时将多个消息分派给一个工作者,换句话说,在某个工作者处理完一条消息并确认它之前,RabbitMQ不会给该工作者分派新的消息,而是将新的消息分派给下一个不是很繁忙的工作者 这就是fair dispatch
//如果不设置,默认是round-robin
factory.setPrefetchCount(1);
并且注释掉(为什么要注释掉呢?)
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
结果:
消费者1:
消费者2:
可以看到目前是fairdispatch方式
消息应答和消息持久化
注意以下两点:
1. 自动应答
为true说明队列把消息给消费者之后就将消息从其内存中删除。如果杀掉正在执行任务的消费者,就会丢失消息。
为false,关闭自动应答,说明队列把消息给消费者之后要等待消费者的确认处理完成消息。如果未收到消费者的确认处理完成消息,就会分发给其他消费者,保证消息不丢失。
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
2. 消息持久化
如果rabbitmq挂了,那么存储在内存中的消息就会丢失了,这里涉及到durable的问题。将队列设置为durable实现消息持久化
@Bean
public Queue queue(){
return new Queue(QUEUE_NAME,true);
}
参考: