Sometimes, a message consumer might be failed because of connection issues or other logical reasons. In this case, the application should handle the fail scenario properly and retry the failed message several times based on some rules.
Today, we are gonna see how to retry a failed message in a Symfony application through Messenger Component by referencing the previous post:
How To Retry
Messenger Component, retries a failed message through the
dead letter feature of RabbitMQ in case of RabbitMQ usage. It tries by default 3 times, with 1000 ms delay, and multiplies the duration by 2 in each try.
RabbitMQ deliver the messages with a specific delay when it received some headers as the following:
You can check out the document for more details regarding dead lettering
Delayed messages with RabbitMQ - Documentation - CloudAMQP
Sometimes you want to delay the delivery of messages for a certain time so that subscribers doesn't see them…
How To Customize Retry Strategy:
Messenger Component, allows you to customize the retry strategy, based on the transporters. You can customize the retry strategy of your transporter as following:
You can also implement your own retry strategy by implementing
Symfony\Component\Messenger\Retry\RetryStrategyInterface and put its service id — usually its class name
How To Avoid Retrying
You may have some specific scenarios that you should ignore a failed message. In this case, you can simply throw
Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException. In case of you throw this exception, you will see that Messenger won’t create the dead letter queues on RabbitMQ and will never retry that failed message.
How To Save Failed Messages
Normally, a failed message will be discarded after retried several times. You can avoid this situation by using
failure_transport configuration. When you configured a specific transporter for the failure case, Messenger will store send the message to the failure transporter, after it retried several times.
Let’s take look at the following configuration:
As you see, we just defined a new transporter that write the failed messages to the database and defined transporter id to
failure_transport configuration. Here
default word in the
doctrine://default DSN points to the default connection definition in the Doctrine configuration.
So, this means you need to run another consumer also to persist the failed messages to the database.
$ ./bin/console messenger:consume failed --time-limit=3600 --memory-limit=128M
When you start the consumer, you will see that
failed_message table created in the database like the following one:
Do not forget to check out the complete example repository:
Run the following command to start the application containers $ cd dev $ docker-compose up The RabbitMQ instance will…
Using RabbitMQ in A Symfony Application Through Messenger Component
Cover photo: https://forevervets.com/reasons-parasite-prevention-is-necessary-for-dogs/