Руководство RabbitMQ - Часть 3. Publish/Subscribe - одно сообщение многим (fanout)

06.08.26

Интеграция - Внешние источники данных

Перевод руководства и адаптация кода под платформу 1С. Источник https://www.rabbitmq.com/tutorials/tutorial-three-python

Подготовка окружения

Компонента kovalevdmv/1CRabbitMQ, обработка КлиентRMQ. Брокер - как в части 1.

Код примеров собран в расширении RMQ_lessons (malikov-pro/1CRabbitMQ) для запуска через YAxUnit.

Те же сценарии можно вызывать из консоли кода в серверном контексте - например bsl_console и аналоги.

 

На чём сосредоточена часть

В части 2 рабочая очередь отдавала каждую задачу ровно одному исполнителю. Здесь наоборот: одно сообщение получают все слушатели. Паттерн называют publish/subscribe (издатель–подписчик).

Чтобы показать идею, соберём простую «систему логирования»: одна программа шлёт сообщения лога, несколько получателей их принимают. Каждая запущенная копия получателя видит одни и те же сообщения - можно одного писать в файл, другого смотреть «на экране» (в ЖР / РС).

По сути сообщения рассылаются (broadcast) всем подписчикам.

 

 

Точки обмена (exchanges)

В частих 1–2 мы писали «в очередь». Полная модель RabbitMQ чуть точнее: производитель никогда не кладёт сообщение напрямую в очередь. Он публикует только в точку обмена (exchange). Exchange решает, в какие очереди положить сообщение - по своему типу и привязкам.

Кратко:

  • Producer - отправляет сообщения;
  • Queue - буфер;
  • Consumer - получает;
  • Exchange - точка входа: принял от producer U94; раздал по правилам.

Типы точек обмена: direct, topic, headers, fanout. В этой части рассмотрим fanout: рассылает каждое сообщение во все привязанные очереди. Как раз для логгера.

Добавим точку обмена logs.

// один раз перед публикацией / подпиской (идемпотентно при тех же параметрах)
ТочкаОбмена = ОМ_РМКУ_Настройки.ИмяОбменникаЧасть3(); // "logs"
ОМ_РМКУ_ManagementAPI.ОбъявитьExchange(ТочкаОбмена, "fanout");

Раньше в ОпубликоватьСообщение мы передавали пустую ТочкаОбмена - это обменник по умолчанию: сообщение шло в очередь с именем из ключа маршрутизации. Теперь публикуем в наш logs:

// Подключение и Канал - как в [части 1](//infostart.ru/1c/articles/2196530/)
// Exchange «logs» уже объявлен через Management API (тип fanout)
ТочкаОбмена = "logs";
ТекстСообщения = "info: Hello World!";

Ответ = КлиентRMQ.ОпубликоватьСообщение(
	Канал, ТекстСообщения, "", ТочкаОбмена, Истина);

Ключ маршрутизации при публикации указать нужно, но для fanout его значение игнорируется.

Если к exchange никто не привязан, сообщение пропадёт - для логгера это нормально: некому слушать - некуда писать.

 

Временные очереди и привязки

В work queue имя очереди (task_queue) было общим для всех исполнителей. Для подписчика лога другое:

  1. при каждом подключении - своя пустая очередь (имя может выбрать сервер);
  2. после отключения подписчика очередь должна исчезнуть (exclusive / auto-delete).

В КлиентRMQ объявление очереди и привязка к exchange - один вызов ОбъявитьОчередь: пустое имя U94; серверное имя; ТочкаОбмена + ключ - binding.

// временная exclusive + auto-delete, привязка к fanout «logs»
Очередь = КлиентRMQ.ОбъявитьОчередь(
	Канал,
	"",           // имя выберет сервер (amq.gen-…)
	"",           // binding key; для fanout не важен
	"logs",       // ТочкаОбмена
	Ложь,         // не durable
	Истина,       // exclusive
	Истина);      // auto-delete

ИмяОчереди = Очередь.ИмяОчереди;

Связь «exchange U94; очередь» и есть binding (привязка). С этого момента logs копирует входящие сообщения в нашу очередь.

 

 

В Management UI на вкладке Bindings при двух подписчиках увидите две очереди, обе связанные с logs.

 

Реализация

Издатель:

ТочкаОбмена = "logs";
ОМ_РМКУ_ManagementAPI.ОбъявитьExchange(ТочкаОбмена, "fanout");

Подключение = КлиентRMQ.ПодключитьсяКСерверу(URI);
Канал = КлиентRMQ.СоздатьКанал(Подключение);

КлиентRMQ.ОпубликоватьСообщение(Канал, ТекстСообщения, "", ТочкаОбмена, Истина);

КлиентRMQ.ЗакрытьКанал(Канал);
КлиентRMQ.ОтключитьсяОтСервера(Подключение);

Подписчик:

Четвёртый параметр СоздатьПолучателя - АвтоматическоеПодтверждение (no_ack). Здесь ставим Истина. В части 2 для work queue так нельзя было: задача должна пережить падение исполнителя и вернуться в общую очередь. У логгера другая модель: у каждого подписчика своя temporary-очередь, сообщение - копия broadcast, потеря одной копии не «съедает» задачу у остальных. Учебный приёмник только пишет в ЖР / РС - ручной ack здесь усложняет код без выигрыша. Если подписчик начнёт делать критичную работу (запись в ИБ с гарантией), переходите на Ложь + ПодтвердитьСообщение, как в части 2.

ТочкаОбмена = "logs";
ОМ_РМКУ_ManagementAPI.ОбъявитьExchange(ТочкаОбмена, "fanout");

Подключение = КлиентRMQ.ПодключитьсяКСерверу(URI);
Канал = КлиентRMQ.СоздатьКанал(Подключение);

Очередь = КлиентRMQ.ОбъявитьОчередь(Канал, "", "", ТочкаОбмена, Ложь, Истина, Истина);
// auto-ack = Истина - см. пояснение выше (не как work queue в части 2)
Получатель = КлиентRMQ.СоздатьПолучателя(
	Канал, Очередь.ИмяОчереди, "подписчик_1", Истина,,,, ТаймаутОжиданияСек);

Пока КлиентRMQ.СледующееСообщение(Получатель) Цикл
	ДанныеСообщения = КлиентRMQ.ДанныеСообщения();
	// … ЗафиксироватьПолучение / Сообщить …
КонецЦикла;

КлиентRMQ.ОтменитьПолучателя(Получатель);
КлиентRMQ.ЗакрытьКанал(Канал);
КлиентRMQ.ОтключитьсяОтСервера(Подключение);

 

Запуск решения

Как в части 2 сначала запускам слушателей потом отправляем сообщения иначе broadcast «на лету» не будет видно.

YAxUnit - тесты набора «Урок 3» Урок3_PubSubВОднойИБ

Консоль кода (серверный контекст) - те же сценарии:

// smoke: exchange logs U94; два temporary-подписчика U94; broadcast U94; оба получают одно тело
ОМ_ТестRMQ_Lessons.Урок3_PubSubВОднойИБ();

// или вручную: два слушателя (ФЗ / сеансы по скелету «Подписчик» выше) U94; потом emit
ОМ_ТестRMQ_Lessons.Урок3_Отправитель();
ОМ_ТестRMQ_Lessons.Урок3_Отправитель("warning: disk low");

Результат работы: в регистре rmq_ОчередьОбменаRMQ - исходящие Отправлено и входящие у обоих подписчиков. В ЖР / окне сообщений после Урок3_PubSubВОднойИБ примерно:

… | Старт | очередь: часть3_pubsub | данные: Урок3_PubSubВОднойИБ
… | Отправка в очередь | очередь: часть3_pubsub | данные: broadcast:a1b2c3d4
… | Получение из очереди | очередь: часть3_pubsub | данные: подписчик 1 | broadcast:a1b2c3d4
… | Получение из очереди | очередь: часть3_pubsub | данные: подписчик 2 | broadcast:a1b2c3d4
… | Окончание | очередь: часть3_pubsub | данные: Урок3_PubSubВОднойИБ

При ручном emit двух сообщений у каждого подписчика будет по две строки «Получение» - тела одинаковые у подписчик 1 и подписчик 2.

 

Результат

Настроили рассылку: fanout-exchange, временные очереди подписчиков, binding. Каждое опубликованное сообщение уходит всем слушателям.

Дальше - часть 4: слушать не всё подряд, а подмножество по ключу.

 

Ссылки на остальные части

Благодарю за внимание.

Создано совместно с Cursor Grok 4.5

Вступайте в нашу телеграмм-группу Инфостарт

RabbitMQ КлиентRMQ Publish/Subscribe fanout обменник exchange подписчик временная очередь exclusive binding логирование AMQP 1CRabbitMQ интеграция

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Внешние источники данных Программист Бизнес-аналитик Пользователь 1С:Предприятие 8 1C:Бухгалтерия Узбекистан Беларусь Кыргызстан Молдова Россия Казахстан Платные (руб)

Готовое решение для автоматической выгрузки данных из 1С 8.3 в базу данных ClickHouse, PostgreSQL или Microsoft SQL для работы с данными 1С в BI-системах. «Экстрактор данных 1С в BI» работает со всеми типовыми и нестандартными конфигурациями 1С 8.3 и упрощает работу бизнес-аналитиков. Благодаря этому решению, специалистам не требуется быть программистами, чтобы легко получать данные из 1С в вашей BI-системе.

35000 руб.

15.11.2022    32442    50    49    

49

Внешние источники данных Кадровый учет Файловый обмен (TXT, XML, DBF), FTP Перенос данных 1C Программист 1С:Предприятие 8 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бухгалтерский учет Бюджетный учет Платные (руб)

Обработка позволяет перенести кадровую информацию и данные по заработной плате, фактическим удержаниям, НДФЛ, вычетам, страховым взносам из базы Парус 10 учреждений (далее Парус) в конфигурацию 1С:Зарплата и кадры государственного учреждения ред. 3 (далее 1С) и начать с ней работать с любого месяца года.

85400 руб.

05.10.2022    14066    16    8    

17

Розничная торговля Внешние источники данных Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист 1С:Предприятие 8 1С:Бухгалтерия 3.0 Фармацевтика, аптеки Россия Бухгалтерский учет Платные (руб)

Внешняя обработка загрузки данных из файла-выгрузки, сформированного в программе F3 TAIL версии 3.4 (и выше) или еФарма версии 2.1, в базу конфигурации 1С: Бухгалтерия предприятия 8, ред. 3.0 (Базовая, ПРОФ, КОРП, ФРЕШ (тонкий клиент)).

17080 руб.

19.12.2016    54771    126    107    

86

Производство готовой продукции (работ, услуг) Внешние источники данных 1С:Предприятие 8 1С:Управление нашей фирмой 1.6 Лесное и деревообрабатывающее хозяйство Россия Управленческий учет Платные (руб)

Обработка предназначена для загрузки файлов, выгруженных из системы Базис-мебельщик, в справочник 1С "Спецификации" для последующих процессов учета и диспетчирования полуфабрикатов и изделий.

10370 руб.

24.06.2021    26214    64    55    

47

Внешние источники данных Программист Бизнес-аналитик 1С:Предприятие 8 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)

Обработка для выгрузки данных из подготовленных СКД в фоновом режиме в базу ClickHouseDB, PostgreSQL, MySQL, в шину данных с поддержкой REST API (CSV, JSON. SQL), в локальные файлы (CSV, JSON, XLS, XLSX) или в Google Sheets. Это дополнительная подключаемая обработка.

18000 руб.

21.08.2024    9813    25    4    

22

Оптовая торговля Розничная торговля Внешние источники данных Прайсы 1С:Предприятие 8 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Оптовая торговля, дистрибуция, логистика Управленческий учет Платные (руб)

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

15250 руб.

15.05.2024    4822    8    1    

9
Для отправки сообщения требуется регистрация/авторизация