在使用RabbitMQ的过程当中,确定会遇到这样的几个概念:transaction、confirm、ack。本文介绍一下这几个概念,以及他们之间的关系。html
RabbitMQ是采用的AMQP协议,AMQP协议定义了”确认”(acknowledgement),它是从consumer到RabbitMQ的确认,表示一条消息已经被客户端正确处理。RabbitMQ扩展了AMQP协议,定义了从broker到publisher的”确认”,但将其称之为confirm。因此RabbitMQ的确认有2种,叫不一样的名字,一个consumer acknowledgement,一个叫publisher confirm。socket
根据AMQP协议规定,consumer acknowledgemenet是经过basic.ack方法实现的,consumer在收到一条消息后,能够向broker发送basic.ack方法,确认一条消息已经收到。在默认的状况下,consumer acknowledgement模式是开启的,若是不想发送basic.ack,能够在发送basic.consume方法时指定no-ack参数,关闭consumer acknowledgement模式。日志
Publisher confirm并无在AMQ协议的基础上添加新的确认方法,而是复用了basic.ack方法。可是publisher confirm模式并非默认打开的,须要调用confirm.select方法将channel设置成confirm模式。当开启了confirm模式以后,只有当一条消息被全部的mirrors接受以后,publisher才会收到这条消息的confirm,也就是一个basic.ack方法。server
RabbitMQ支持事务(transaction)。事务模式也不是默认开启的,须要调用tx.select方法开启事务模式。当开启了事务模式后,只有当一个事务被全部的mirrors接受以后,tx.commit-ok才会返回给客户端。confirm模式和开启事务模式均可以保证”被全部的mirrors接受”,那么,开启confirm模式和开启事务模式有什么区别吗?不一样点在于confirm是针对一条消息的,而事务是能够针对多条消息的(固然是针对同一个queue的多条消息)。另外就是,confirm模式只是针对publisher的设置,而事务模式便可以针对publisher,也能够针对consumer。若是针对publisher设置事务模式,则咱们能够将多个basic.publish方法放在一个事务中,当全部的publish的消息被全部的mirrors接受后,publisher client会收到tx.commit-ok的方法。若是针对consumer设置事务模式,则咱们能够将多个basic.ack方法放在一个事务中,收到tx.commit-ok时表示这些消息都被确认了。htm
kafka 生产者 ack 机制rabbitmq
Producer端配置
一、acks设置为-1事务
设置为0表示producer不须要等待任何确认收到的信息,副本将当即加到socket buffer并认为已经发送。没有任何保障能够保证此种状况下server已经成功接收数据,同时重试配置不会发生做用(由于客户端不知道是否失败)
设置为1意味着至少要等待leader已经成功将数据写入本地log,可是并无等待全部follower是否成功写入。这种状况下,若是follower没有成功备份数据,而此时leader又挂掉,则消息会丢失
设置为-1意味着leader须要等待全部备份都成功写入日志,这种策略会保证只要有一个备份存活就不会丢失数据。这是最强的保证。get
rabbitmq 生产者 ack 机制
kafka
参考:it
http://www.rabbitmq.com/confirms.html
http://www.rabbitmq.com/amqp-0-9-1-reference.html#class.tx
http://www.rabbitmq.com/amqp-0-9-1-reference.html#class.confirm