RabbitMQ学习心得体会之工作队列
一、工作队列(Work Queues)
为了完成一些对资源敏感又需要等待立即响应请求的任务,我们可以使用工作队列来完成。我们可以把任务封装成消息发送给工作队列,工作队列可以异步的在返回请求结果后,稍后执行任务。一个生产者可以对应多个队列,生产者投递的消息可以平均的分发到不同的队列里面去。
消息确认(Message acknowledgment)
在生产者投递消息后,如果消费者没有全部执行完任务就出现异常,导致程序死了,那我们的这个没完成全部消息该怎么处理?在rabbitmq中,生产者投递后的消息,这个消息会被生产者标记为删除中,如果消费者使用自动ack回复,那么消费者一旦接收到消息,这个任务就会被删除,不管任务执行完没有(这是我的理解)。为了解决这个问题,可以关闭自动ack回复,并且在任务执行完毕之后,手动写代码回复一个ack,这样就可以确保消息执行完了,然后服务端删除这个任务。如果服务没有在指定ack超时时间收到ack,那么这个处理失败的消息将会被重新投递其他在线的消费者。
这让我联想到之前看的一些工作队列的博客,从中知道,如果ack设置的超时时间过长,一个队列突然死了,那么很可能会积压大量的失败任务,就会造成服务器内存猛涨,因为那些失败的队列迟迟没有被删除有没有被重新投递。或者关闭了自动回复ack,但是任务完成时又忘记回复ack了,ack超时时间又有些长,也会造成内存猛涨的。另外如果超时后,重新投递了任务,但是因为之前处理是异步的,所有有可能超时后这个失败的任务又完成了,那么就导致了任务被重复的执行,所以这个超时时间的设置还是需要注意分寸。
消息持久(Message durability)
对于服务器可能挂掉的情况,就需要提前把消息和队列都标记会可持久化的,那样可以把消息存入到缓存和磁盘中,但要注意并不是所有的消息都会存入磁盘。
任务公平分配(Fair Dispatch)
当有的队列因为投递的的任务不同, 有的队列会很忙 ,有的队列很轻松,忙的会一直忙,不忙的就会很闲,为了平衡这些工作队列,可以使用BasicQos方法设置, 让队列的处理任务更平衡
该方法的作用是:进行消费端的限流
- param1:prefetchSize,消息本身的大小 如果设置为0 那么表示对消息本身的大小不限制
- param2:prefetchCount,告诉rabbitmq不要一次性给消费者推送大于N个消息
- param3:global,是否将上面的设置应用于整个通道
- false:表示只应用于当前消费者
- true:表示当前通道的所有消费者都应用这个限流策略