Доступ к обмену сообщениями, отправленными до привязки очереди

У меня есть вопрос, касающийся третьего урока RabbitMQ. Я пытаюсь реализовать нечто подобное, за исключением того, что нет никакой гарантии, что потребитель (-и) будет работать в то время, когда производитель отправляет сообщение на биржу.

Итак, у меня есть продюсер, который публикует сообщения для обмена фанатами:

$channel->exchange_declare('my_exchange', 'fanout', false, false, false);
$channel->basic_publish('my_message', 'my_exchange');

В моих издателях я объявляю очереди, которые затем привязываю к обмену:

list($queueName,, ) = $channel->queue_declare("", false, false, true, false);
$channel->queue_bind($queueName, 'my_exchange');

И здесь у моей проблемы есть корень. Учебник говорит:

Сообщения будут потеряны, если к обмену еще не привязана ни одна очередь, но это нормально для нас; если ни один потребитель не слушает, мы можем смело отказаться от сообщения.

Есть ли способ как-то сохранить эти сообщения, чтобы при запуске потребитель получал доступ к ранее отправленным сообщениям? Единственный способ, которым я понял, как это сделать, - объявить одну и ту же очередь в моем производителе и моем издателе, но это отчасти противоречит цели обмена и отдельных очередей для разных потребителей.

2 ответа

Решение

Очереди должны существовать, на самом деле не имеет значения, кто / что их создает: это может быть производитель (хотя я бы настоятельно не рекомендовал это), потребитель, какое-то третье приложение администратора, которое просто создает очередь через rest api, rabbitmqctl... Если вы хотите использовать очереди позже, просто убедитесь, что они долговечны и что TTL для сообщений достаточно длинный (а также длительные сообщения, если это необходимо). Но помните, что ваши очереди не попадают в состояние потока.

Единственный способ, которым я понял, как это сделать, - объявить одну и ту же очередь в моем производителе и моем издателе, но это отчасти противоречит цели обмена и отдельных очередей для разных потребителей.

Во-первых - я думаю, ты хотел сказать in my producer and my subscriber:)
Во-вторых, отдельные очереди для потребителей (или очереди для потребителя) как раз в этом примере. Имейте в виду, что это для обмена разветвлениями, и каждый потребитель очищает исключительную очередь - когда потребитель отключается, очередь исчезает. И вот почему that's okay for usпотому что мы просто вещаем, и кто хочет, чтобы вещание (сообщения) получало его. Обмен Fanout просто помещает сообщения во все связанные с ним очереди, вот и все.
Совершенно нормально, если несколько потребителей потребляют из одной очереди (см. Учебник 2).

Так что вам просто нужно рассмотреть ваш вариант использования. Конечно, не имеет смысла создавать разветвленный обмен и предварительно настраивать очереди для потребителей... Возможно, вам нужны только некоторые ключи маршрутизации или что-то еще.

В этом примере (так в уроке 3) имеется в виду, что есть широковещательный обмен сообщениями, и, если никто их не получает, это не большая (или маленькая) сделка. Если кто-то хочет их, они должны получить их. Это как телевизионный канал - независимо от того, кто-то смотрит или нет, сигнал продолжается.

Потребители должны присоединяться к очередям, они не должны объявлять свои собственные очереди. Думайте об очередях, как о корзинах работы, которая должна быть сделана. В зависимости от рабочей нагрузки вы можете добавить N потребителей в эти очереди для выполнения работы.

Когда вы создаете обмен, у вас должна быть одна или несколько очередей (групп работ), которые прикреплены к этому обмену. Если вы сделаете это, сообщения попадут в очереди и начнут стоять в очереди (простите за каламбур). Ваши потребители могут присоединиться, когда они будут готовы, и начать работу.

Другие вопросы по тегам