public static final AcknowledgeMode AUTO
- Auto - the container will issue the ack/nack based on whether the listener returns normally, or throws an exception.
- Do not confuse with RabbitMQ autoAck which is represented by NONE here.
The AUTO
is involved in the commitIfNecessary()
which is called only when your target listener returns normally
https://docs.spring.io/spring-amqp/reference/html/_reference.html#template-confirms
https://www.rabbitmq.com/blog/2011/02/10/introducing-publisher-confirms/
https://www.rabbitmq.com/confirms.html#publisher-confirms
https://docs.spring.io/spring-amqp/reference/html/_reference.html#transactions
https://github.com/spring-projects/spring-amqp-samples/tree/master/spring-rabbit-confirms-returns
-
slow processing using transactions https://gist.github.com/scvalex/613157
-
faster processing using publisher confirms https://gist.github.com/scvalex/613165
spring.rabbitmq.publisher-confirms=true
No, that isn't good practice to always use Publisher Confirms. You lose a bit in performance and throughput. Since there should be run some mechanism on the Broker to notify you about those particular events.
It depends on the use case; if you want guaranteed delivery then, yes, they can be used; they are significantly more efficient than using transactions (by several hundred times).
ack
is for the consumer side - therefore Listener Container is there for you- The publisher-returns is up to producer - therefore RabbitTemplate
If you publish a message with a RabbitTemplate
that has setChannelTransacted(true)
, it's about 250x slower than without it.
Sometimes transactions are needed but often publisher confirms are sufficient -
however, if you block the sending thread and wait for the confirmation, it won't be much faster than using transactions.
Publisher confirms come into their own when you publish a bunch of messages and then later wait for the confirmations.
If performance is not a concern then the simplest config is to enable channelTransacted
on both the listener container (inbound adapter) and template (outbound adapter).
Then, the container will start a transaction, receive a message;
any downstream publishing on the container thread will participate in the transaction.
If the flow finishes normally, the message will be ack'd and the transaction committed.
Receiving the message is not part of the transaction, but the ack is.
Dealing with publisher confirms adds complexity (and won't help much with performance if you want to wait for the confirm on a single message).
https://docs.spring.io/spring-amqp/reference/html/_reference.html#_introduction_13
The primary reconnection features are enabled by the CachingConnectionFactory itself. It is also often beneficial to use the RabbitAdmin auto-declaration features. In addition, if you care about guaranteed delivery, you probably also need to use the channelTransacted flag in RabbitTemplate and SimpleMessageListenerContainer and also the AcknowledgeMode.AUTO (or manual if you do the acks yourself) in the SimpleMessageListenerContainer.
https://docs.spring.io/spring-amqp/reference/html/_reference.html#async-listeners
If you send a mandatory message to an exchange that can't route to a queue; you get a returned message followed by an ack - the ack meaning it reached an exchange.
https://www.rabbitmq.com/confirms.html#when-publishes-are-confirmed
As also stated on that page nacks generated by the broker are rare (means there is a bug in the broker). However, Spring AMQP will synthesize a nack if there is an outstanding ack and something caused the channel to close before the ack was received.