@deadsquirrel93

Типы обменников в rabbitmq и хранение сообщения при неактивном получателе?

В оф. доке rabbitmq написано, что есть несколько типов обменников(exchange), один из них fanout - распределяет сообщения во все очереди, игнорирует routing_key.
Модель задачи: есть n сообщений, есть три получателя(consumer), каждое сообщение должно попасть к каждому получателю.
Используется либа https://github.com/php-amqplib/php-amqplib

Что делаю:
Отправитель(producer): декларирую обменник типа fanout, делаю basic_publish всех сообщений
Получатель(consumer): декларирую обменник типа fanout декларирую очередь с рандомным названием(из доки list($queue_name, ,) = $channel->queue_declare("", false, false, true, false);), делаю basic_consume всех сообщений

Проблема:
Если получатели уже запущены, то все происходит верно, все получатели получили по каждому сообщению, но если получатели не запущены, а сообщения отправлены, то при запуске получателей ничего не происходит, сообщения просто потерялись.
Если декларировать очередь в отправителе, то сообщения не теряются, но потом не привязываясь в получателе к этой очереди я не смогу взять сообщения и весь смысл fanout теряется. Игрался с разными флагами(durable, delivery_mode) и ничего не помогло.

Вопрос: как сохранять сообщения, не привязываясь к очереди в отправителе, чтобы при запуске получателей они стали получать эти сообщения? Если способ только декларировать очередь в отправителе, то тогда какой смысл fanout обменника?
  • Вопрос задан
  • 132 просмотра
Решения вопроса 2
@yarkin
Если Вы хотите на пустом RabbitMQ создать обменник, кинуть в него сообщения и позже подключить очереди к этому обменнику в надежде получить ранее отправленные сообщения, то это у Вас не получиться. Обменник не хранит сообщения, а разбрасывает входящие сразу по мере их получения, если в данный момент у него нет очередей для отправки - сообщение просто отбрасывается. Вам нужно стартовать потребителей до того, как отправлять сообщения. Если хотите, чтобы в момент, когда потребитель отвалился, сообщения накапливались, то надо сделать предсказуемое/известное для потребителя имя очереди (по необходимости сделать её durable).
Если надо, чтобы при старте RabbitMQ что-то создавало очереди и обменники, то через менеджмент плагин такое можно устроить (говорят, в последних версиях даже можно это сделать без менеджмент плагина).
Ответ написан
index0h
@index0h
PHP, Golang. https://github.com/index0h
как сохранять сообщения, не привязываясь к очереди в отправителе, чтобы при запуске получателей они стали получать эти сообщения?

Создать эксчейндж, создать очереди, забиндить очереди на эксчейндж.

Если способ только декларировать очередь в отправителе, то тогда какой смысл fanout обменника?

Смысл в том, что распределение идет по очередям, а не консьюмерам. Если нет очередей - распределять некуда.

fanout вам не нужен
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы