RabbitMQ не поддерживает отложенный обмен сообщениями из коробки. Однако в конце сообщения Ловушки повторной доставки RabbitMQ мы представили фрагменты кода, которые задерживают либо с помощью комбинации ttl и обмена недоставленными сообщениями, либо с помощью плагина задержки.

Но это было до появления amqp interop и некоторых других изменений в этой области. Среди других значительных изменений мы добавили несколько полезных методов в интерфейс производителя, например setDeliveryDelay, setPriority, setTimeToLive.

Скажем, нам нужно это: сообщение, которое задерживается на пять секунд, поэтому ни один потребитель не видит его сразу, его время жизни составляет одну минуту, после него оно просто удаляется из очереди и, кроме того, нам нужен немного более высокий приоритет для этого конкретного сообщения. Вот как бы вы это сделали, если бы AMQP поддерживал отложенный обмен сообщениями:

Но это не так, поэтому RabbitMQ выдает DeliveryDelayNotSupportedException при вызове метода setDeliveryDelay. Конечно, вы можете проигнорировать это, перехватив исключение, если задержка сообщений для вас не важна:

Но что делать тем, кому это действительно нужно? Не беспокойтесь, ребята, мы позаботились о вас. Вот решение: производитель AMQP принимает стратегию задержки, и если она установлена, он ничего не генерирует, а вместо этого вызывает стратегию, когда дело доходит до задержки сообщения. Так что, не говоря уже о подробностях отсрочки, просто подключите стратегию и продолжайте взламывать! Кроме того, стратегии задержки работают с любым транспортом, совместимым с amqp interop, таким как enqueue/amqp-ext, enqueue/bunny, enqueue/amqp-lib.

Мы использовали RabbitMqDlxDelayStrategy стратегию, но она не единственная, есть и другие. Вы можете использовать их, установив пакет enqueue/amqp-tools.

Прежде всего, вы можете реализовать свою собственную стратегию задержки. Это может пригодиться, когда вам приходится иметь дело с большими задержками (дни или недели). Хотя стандартные решения могут обслуживать такие задержки, они не лучший выбор в этом случае. Лучше использовать планировщик или базу данных для хранения сообщений до тех пор, пока не придет время. Я дам главу и стих о том, как php-quartz scheduler может справляться с большими задержками.