RabbitMQ持久化
默认情况下RabbitMQ退出或由于某种原因崩溃时,他忽视队列和消息,除非告知它不要这么做。确保消息不会丢失需要做两件事情:我们需要将队列和消息都标记为持久化。
队列如何实现持久化
队列创建时如果没有选择持久化,那么rabbitmq重启时,该队列就会被删除,如果要实现队列持久化,只需要在生命队列时把持久化参数(durable)设置为true,则队列就会自动设置成持久化队列。就是有一点需要注意,如果在声明该队列为持久化队列之前,该队列在rabbitmq中已经存在,并且不是持久化的,那么就会报错,说该队列参数与原来的参数不匹配,所以需要把原来的队列删除了,才可以创建新的队列。
消息实现持久化
要想让消息实现持久化需要在消息生产者修改代码,MessageProperties.PERSISTENT_TEXT_PLAIN添加这个属性
这样就设置了消息持久化。
将消息标记为持久化并不能完全保证不会丢失消息。尽管他告诉RabbitMQ将消息保存到磁盘,但是这里依然存在当消息刚准备存储在磁盘的时候,但是还没有存储完,消息还在缓存的一个间隔点。此时并没有真正写入磁盘。持久性保证不强,但是对于我们简单任务队列而言,这已经绰绰有余了。
不公平分发
在最开始的时候我们学习到RabbitMQ分发消息采用的轮询分发,但是在某种场景下这种策略并不是很好,比方说有两个消费者在处理任务,其中消费者1处理任务的速度非常快,消费者2处理速度却很慢,这个时候我们还是轮询分发就会导致处理速度很快的消费者1很大一部分时间处于空闲状态,消费者2一直在干活。为了避免这种方式,我们可以设置参数channel.basicQos(1);这样就设置为不公平分发模式。就是谁空闲rabbitmq就把消息分发给谁,不会导致某个消费者一直在干活,而有其他的消费者一直处于空闲状态。
预取值
本身消息的发送就是异步的,所以在任何时候,channel上肯定不知只有一个消息另外来自消费者的手动确认消息本质上也是异步的,因此这里就存在一个未确认的消息缓冲区。因此希望开发人员能限制此缓冲区的大小,以避免缓冲区里面无限制的未确认消息问题 。这个时候可以使用channel.basicQos()设置“预取计数”值来完成。该值定义通道上允许的未确认消息的最大数量。一旦数量达到配置的数量,RabbitMQ将停止在通道上传递消息,除非至少有一个未处理的消息被确认。