队列的声明默认是存放到内存中的,若是rabbitmq重启会丢失,若是想重启以后还存在就要使队列持久化,保存到Erlang自带的Mnesia数据库中,当rabbitmq重启以后会读取该数据库。数据库
简单理解就是在链接关闭时是否会删除队列(不管队列中有没有消息) 性能
当队列中有消息时,不管是否排他,关闭链接都不会删除队列,此时消费者消费完消息后再断开消费者,队列会被自动删除。(这里若是有多个消费者消费同一个队列,则须要全部消费者都断开后才能自动删除) 线程
在实际应用中,可能会发生消费者收到Queue中的消息,但没有处理完成就宕机(或出现其余意外)的状况,这种状况下就可能会致使消息丢失。为了不这种状况发生,咱们能够要求消费者在消费完消息后发送一个回执给RabbitMQ,RabbitMQ收到消息回执(Message acknowledgment)后才将该消息从Queue中移除;若是RabbitMQ没有收到回执并检测到消费者的RabbitMQ链接断开,则RabbitMQ会将该消息发送给其余消费者(若是存在多个消费者)进行处理。这里不存在timeout概念,一个消费者处理消息时间再长也不会致使该消息被发送给其余消费者,除非它的RabbitMQ链接断开。 这里会产生另一个问题,若是咱们的开发人员在处理完业务逻辑后,忘记发送回执给RabbitMQ,这将会致使严重的bug——Queue中堆积的消息会愈来愈多;消费者重启后会重复消费这些消息并重复执行业务逻辑…。pub message是没有ack的。接口
消息一旦被消费者接收,队列中的消息就会被删除。RabbitMQ怎么知道消息被接收了呢?rabbitmq
若是消费者领取消息后,还没执行操做就挂掉了呢?或者抛出了异常?消息消费失败,可是RabbitMQ无从得知,这样消息就丢失了!队列
所以,RabbitMQ有一个ACK机制。当消费者获取消息后,会向RabbitMQ发送回执ACK,告知消息已经被接收。 内存
rabbitmq的消费模式分为两种: 推(Push)模式和拉(Pull)模式。推模式采用Basic.Consume进行消费,而拉模式则是调用Basic.Get模式。 资源