publish message confirmation

Using standard AMQP, the only way to guarantee that a message isn't lost is by using transactions -- make the channel transactional, publish the message, commit. In this case, transactions are unnecessarily heavyweight and decrease throughput by a factor of 250. To remedy this, a confirmation mechanism was introduced.
If the standard AMQP protocol is used, the only way to guarantee that messages will not be lost is to use the transaction mechanism -- put the channel in transactional mode, publish a message to it, and perform a commit action. In this way, the transaction mechanism will bring a lot of redundant overhead and will result in a 250% drop in throughput. In order to remedy the problems caused by transactions, a confirmation mechanism (ie Publisher Confirm) is introduced.


To enable confirms, a client sends the confirm.select method. Depending on whether no-wait was set or not, the broker may respond with a confirm.select-ok. Once the confirm.select method is used on a channel, it is said to be in confirm mode. A transactional channel cannot be put into confirm mode and once a channel is in confirm mode, it cannot be made transactional.
In order to enable the confirm mechanism, the client must first send the confirm.select method frame. Depending on whether the no-wait attribute is set, the broker will determine whether to respond with confirm.select-ok accordingly. Once the confirm.select method is used on the channel, the channel will be in confirm mode. A channel in transactional mode can no longer be set to confirm mode and vice versa.


Once a channel is in confirm mode, both the broker and the client count messages (counting starts at 1 on the first confirm.select). The broker then confirms messages as it handles them by sending a basic.ack on the same channel. The delivery-tag field contains the sequence number of the confirmed message. The broker may also set the multiple field in basic.ack to indicate that all messages up to and including the one with the sequence number have been handled.
Once the channel is in confirm mode, Both broker and client will start the message count (counting from 1 based on confirm.select). After the broker has finished processing the message, it will confirm it by sending basic.ack on the current channel. The value of the delivery-tag field identifies the sequence number of the confirmed message. The broker can also indicate that all messages up to the specified sequence number have been correctly processed by the broker by setting the multiple field in basic.ack.


In exceptional cases when the broker is unable to handle messages successfully, instead of a basic.ack, the broker will send a basic.nack. In this context, fields of the basic.nack have the same meaning as the corresponding ones in basic. ack and the requeue field should be ignored. By nack'ing one or more messages, the broker indicates that it was unable to process the messages and refuses responsibility for them; at that point, the client may choose to re-publish the messages.
In exceptional cases, the broker will not be able to successfully process the corresponding message, in which case the broker will send basic.nack instead of basic.ack. In this case, the meaning of each field value in basic.nack is the same as that of the corresponding field in basic.ack, and the value of the requeue field should be ignored. By nacking one or more messages, the broker indicates that it cannot complete the processing of the corresponding messages and refuses to take responsibility for the processing of those messages. In this case, the client may choose to re-publish the message.


After a channel is put into confirm mode, all subsequently published messages will be confirmed or nack'd once. No guarantees are made as to how soon a message is confirmed. No message will be both confirmed and nack'd
. After entering confirm mode, all subsequent messages published will be confirmed (ie ack) or nack once. But there is no guarantee about how quickly a message is confirmed, and the same message cannot be both confirmed and nacked.


An example in Java that publishes a large number of messages to a channel in confirm mode and waits for the acknowledgements can be found here.
Example it's here.




When will messages be confirmed? When will messages be confirmed
?


The broker will confirm messages once: The broker will confirm messages
in the following cases:
•it decides a message will not be routed to queues
(if the mandatory flag is set then the basic.return is sent first) or the
broker finds that the current message cannot be routed to the specified queues (if the mandatory attribute is set, the broker will Send basic.return first)
• a transient message has reached all its queues (and mirrors) or
a message with non-persistent attributes has reached all the queues it should reach (and mirrored queues)
• a persistent message has reached all its queues (and mirrors) and been
persisted to disk (and fsynced) or
a persistent message has been consumed (and if necessary acknowledged) from all its queues
A persistent message has been consumed (and acknowledged if necessary) from all its queues



Notes


The broker loses persistent messages if it crashes before said messages are written to disk. Under certain conditions, this causes the broker to behave in surprising ways
. Under certain conditions, this situation can cause the broker to behave in a strange way.


For instance, consider this scenario
:
1.a client publishes a persistent message to a durable queue
2.a
client consumes the message from the queue (noting that the message is persistent and the queue durable), but doesn't yet ack it,
another client consumes the message from the queue (note: the message has persistent properties, and the queue is persistent), when it has not been acked
3. the broker dies and is restarted, and the
broker restarts abnormally
4. the client reconnects and starts consuming messages.
At

this point, the client could reasonably assume that the message will be delivered again. This is not the case: the restart has caused the broker to lose the message . In order to guarantee persistence, a client should use confirms. If the publisher's channel had been in confirm mode, the publisher would not have received an ack for the lost message (since the consumer hadn't ack'd it and it hadn' t been written to disk).

In the above scenario, the client has reason to believe that the message needs to be re-delivered by the (broker). But this is not the case: restarting will (possibly) cause the broker to lose messages. To ensure persistence, clients should use the confirm mechanism. If the channel used by the publisher is set to confirm mode, the publisher will not receive an ack for the lost message (because the consumer did not ack the message and the message was not written to disk).


Reference: http://blog.csdn.net/jiao_fuyou/article/details/21594205

Official website document: http://www.rabbitmq.com/confirms.html

Reference: http://www.cnblogs.com/leocook/p/mq_rabbitmq_2.html

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326889304&siteId=291194637
Recommended