RabbitMQ如何确保消息发送?消息接收?
1,发送方确认机制
信道需要设置confirm模式,则所有在信道上发布的消息都会分配一个位置id。
一旦消息被投递到queue(可持久化的消息需要写入磁盘),信道会发送一个确认给到生产者,包括消息唯一id。
如果RabbitMq发生内部错误从而导致信息丢失,会发送一条nack ,就是一个未确认的消息给到生产者。
所有被发送的消息都将被confirm (ack)或者被nack一次,但是没有对消息被confirm的快慢做任何保证,而且同一条信息不会同时被nack和ack。
发送方确认模式是异步,生产者应用程序在等待确认的同时,可以继续发送消息,当确认信息到达生产者时候,回调方法就会被触发。
confirmCallback接口,只确认是否正确到达Exchange中,成功到达则回调。
RetrunCallback接口,消息发送失败返回时候回调。
2,接受方确认机制:
消费者在声明队列时候,可以指定noAck参数,当noAck=false时候,RabbitMQ会等待消费者显式发回ack信号才从内存(或者磁盘,持久化信息)中移除信息,否则,消息被消费者后会被立即删除。
消费者接收每一条消息后都必须确认(消息接收和消息确认是两个不同操作),只有消费者确认了消息,RabbitMQ才能安全地把消息从队列中删除。
RabbitMQ不会未ack的消息设置超时时间,它判断此消息是否重新投递给消费者的唯一依据是消费该消息的消费者连接是否已经断开,这么设计的原因是RabbitMQ允许消费者消费一条信息可以很长,保证数据的最终一致性。
如果消费者返回ack之前断开了链接,RabbitMQ就会重新发送给下一个订阅的消费者。重复,需要去重。