Руководство RabbitMQ - Часть 2. Work Queues - рабочие очереди

06.08.26

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

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

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

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

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

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

Для имитации работы исполнителя использую ВызватьПаузу() - работает с версии платформы 8.3.25

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

В части 1 мы отправляли и получали сообщение из именованной очереди. Здесь сделаем рабочую очередь (Work Queue) - она распределяет трудоёмкие задачи между несколькими исполнителями (workers).

Идея простых очередей задач (Task Queues) такая: не делать тяжёлую работу сразу и не ждать окончания выполнения. Задачу планируют к выполнению: упаковывают в сообщение и кладут в очередь. Фоновый исполнитель забирает сообщения и выполняет работу. Если исполнителей несколько - нагрузка делится между ними. Так не приходится «морозить» пользователя, пока идёт долгий расчёт или обработка.

В части 1 слали «Hello World!». Теперь - строки, которые обозначают сложные задачи. Реальной работы (изменение размера картинок, печать PDF) нет: притворимся, что заняты, через ВызватьПаузу. Сложность - число точек в строке (до 10): каждая точка - 0,5 с «работы». Например, Задача 2.......... займёт пять секунд, а Задача 3. - полсекунды.

Исполнителей в 1С можно запускать поднять двумя способами: отдельными клиентами или несколько фоновых заданий в одной ИБ, в примере используются несколько фоновых.

Подключение и канал к брокеру

Два уровня API, которые легко смешать:

  • Подключение (ПодключитьсяКСерверу) - сессия клиента к брокеру (TCP / AMQP): на ней учётные данные и vhost. Параметры - из ОМ_РМКУ_Настройки.СтрокаПодключения().
  • Канал (СоздатьКанал) - логический канал внутри подключения. На нём объявляют очереди, публикуют и потребляют. Настройки вроде предзагрузки (сколько неподтверждённых сообщений держать у получателя) задают на канале, а не на подключении.

Типичный цикл: подключились U94; создали канал U94; работа U94; при необходимости ЗакрытьКанал U94; обязательно ОтключитьсяОтСервера.

Несколько каналов на одном подключении удобны, когда нужны разные настройки (у исполнителя - предзагрузка = 1) или изоляция ошибок канала. Предзагрузку для рабочей очереди разберём после подтверждений.

Отправка задач

Публикуем несколько сообщений (не одно «Hello World!»). Число точек в теле - «вес» задачи (1..10): каждая точка - 0,5 с паузы у исполнителя. Веса задаю массивом, рядом с тяжёлыми кладу несколько лёгких, чтобы в логе было видно - пока один исполнитель тянет задачу на 8-10 точек, второй успевает обработать две-три коротких.

В расширении веса - ОМ_РМКУ_Настройки.ВесаЗадачЧасть2(): 1, 10, 1, 1, 2, 8, 1.

Очередь task_queue и долговечность

Очередь hello из части 1 уже могла быть объявлена с другими параметрами - брокер не даст «тихо» поменять объявление. Для рабочей очереди берём новое имя task_queue: durable + quorum через хелпер из части 1.

Сообщения помечаем как постоянные (СохранитьСообщениеНаДиске = Истина): при рестарте брокера задача с большей вероятностью сохранится. Полной гарантии нет (есть окно до записи на диск), более жёсктий вариант описан в подтверждение публикаций.

// Подключение и Канал
ИмяОчереди = ОМ_РМКУ_Настройки.ИмяОчередиЧасть2(); // "task_queue"
Очередь = ОМ_РМКУ_Настройки.ОбъявитьОчередь(КлиентRMQ, Канал, ИмяОчереди);

ВесаЗадач = ОМ_РМКУ_Настройки.ВесаЗадачЧасть2(); // 1, 10, 1, 1, 2, 8, 1
Номер = 0;
Для Каждого Вес Из ВесаЗадач Цикл
	
	Номер = Номер + 1;
	ТекстСообщения = "Задача " + Номер + Лев("..........", Вес);
	СохранитьСообщениеНаДиске = Истина; // persistent
	
	Ответ = КлиентRMQ.ОпубликоватьСообщение(
		Канал, ТекстСообщения, ИмяОчереди, "", Истина, СохранитьСообщениеНаДиске);
	
	Если КлиентRMQ.ЭтоОшибка(Ответ) Тогда
		ВызватьИсключение СтрШаблон("Ошибка отправки: %1", Ответ.Текст);
	КонецЕсли;
	
	// журнал обмена - РС rmq_ОчередьОбменаRMQ 
	ОМ_РМКУ_Настройки.ЗафиксироватьОтправку(ИмяОчереди, ТекстСообщения, "Урок2_Отправитель");
	ОМ_РМКУ_Настройки.СообщитьКонтрольнуюТочку("Отправка в очередь", ТекстСообщения, ИмяОчереди);
	
КонецЦикла;

В расширении это ОМ_ТестRMQ_Lessons.Урок2_Отправитель.

Циклическая диспетчеризация (round-robin)

Одно из преимуществ очереди задач - распараллеливание. Накопился объем сообщений - можно добавить исполнителей для распределения нагрузки.

По умолчанию RabbitMQ отдаёт каждое следующее сообщение следующему получателю по кругу (round-robin): в среднем поровну.

Подтверждение сообщения

Задача у исполнителя может идти несколько секунд. Если брокер считает сообщение обработанным сразу после выдачи, а исполнитель упадёт посередине - задача потеряна. Мы хотим другое: упал исполнитель - задача вернулась в очередь и ушла другому.

В части 1 параметр АвтоматическоеПодтверждение у СоздатьПолучателя (в AMQP это no_ack) часто оставляют Истина: брокер удаляет сообщение сразу после доставки. Для рабочей очереди так недопустимо.

АвтоматическоеПодтверждение = Ложь;

Получатель = КлиентRMQ.СоздатьПолучателя(
	Канал, ИмяОчереди, ТегПолучателя, АвтоматическоеПодтверждение);

// … обработка задачи …

Ответ = КлиентRMQ.ПодтвердитьСообщение(Канал, ДанныеСообщения.Тег);

> Забытое подтверждение. Сообщения, выданные исполнителю, но ещё не подтверждённые копятся увеличивая расход памяти брокера. Проверяйте через Management UI счётчики готовых к выдаче и неподтверждённых. Таймаут подтверждения у брокера по умолчанию ~30 мин - Delivery Acknowledgement Timeout.

Справедливая раздача (предзагрузка)

Round-robin всё ещё может быть несправедливым. Два исполнителя: все нечётные задачи тяжёлые, чётные - лёгкие. Один постоянно занят, второй почти простаивает. Брокер об «весе» не знает и по кругу отдаёт каждое следующее сообщение следующему получателю - вслепую.

Когда подтверждение ручное, можно ограничить предзагрузку: сколько неподтверждённых сообщений брокер держит у одного получателя. В КлиентRMQ это третий параметр СоздатьКанал - КоличествоПредзагруженныхНеПодтвержденныхСообщений.

При значении 1 следующее сообщение не отдадут, пока не подтверждено текущее и свободный исполнитель получит сообщение раньше занятого. При использовании АвтоматическоеПодтверждение = Истина параметр предзагрузки не влияет на распределение.

КоличествоПредзагруженныхНеПодтвержденныхСообщений = 1;
Канал = КлиентRMQ.СоздатьКанал(
	Подключение, Ложь, КоличествоПредзагруженныхНеПодтвержденныхСообщений);

Собираем исполнителя вместе

Полный код - в расширении: ОМ_ТестRMQ_Lessons.Урок2_ИсполнительВФоне. Здесь - скелет того, что собрали выше.

Подключение = КлиентRMQ.ПодключитьсяКСерверу(URI);
КоличествоПредзагруженныхНеПодтвержденныхСообщений = 1;
Канал = КлиентRMQ.СоздатьКанал(
	Подключение, Ложь, КоличествоПредзагруженныхНеПодтвержденныхСообщений);
Очередь = ОМ_РМКУ_Настройки.ОбъявитьОчередь(КлиентRMQ, Канал, ИмяОчереди);

АвтоматическоеПодтверждение = Ложь;
Получатель = КлиентRMQ.СоздатьПолучателя(
	Канал, ИмяОчереди, ТегПолучателя, АвтоматическоеПодтверждение,,,, ТаймаутОжиданияСек);

Пока КлиентRMQ.СледующееСообщение(Получатель) Цикл
	
	ДанныеСообщения = КлиентRMQ.ДанныеСообщения();
	ТекстСообщения = Строка(ДанныеСообщения.Данные);
	
	ЧислоТочек = СтрЧислоВхождений(ТекстСообщения, ".");
	ВызватьПаузу(ЧислоТочек * ПаузаНаТочкуМс); // «работа»
	
	КлиентRMQ.ПодтвердитьСообщение(Канал, ДанныеСообщения.Тег);
	ОМ_РМКУ_Настройки.СообщитьКонтрольнуюТочку(
		"Получение из очереди",
		СтрШаблон("%1 | %2", ПрефиксИсполнителя, ТекстСообщения), // «исполнитель N | Задача …»
		ИмяОчереди);
	
КонецЦикла;

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

С ручным подтверждением и предзагрузкой = 1 получается рабочая очередь.

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

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


 

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

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

// round-robin с паузой (ФЗ + ВызватьПаузу), одной процедурой:
ОМ_ТестRMQ_Lessons.Урок2_RoundRobinВОднойИБ();

// или вручную
Для Номер = 1 По ОМ_РМКУ_Настройки.КоличествоИсполнителейЧасть2() Цикл // по умолчанию 2
	ПараметрыЗадания = Новый Массив;
	ПараметрыЗадания.Добавить(Номер); // U94; метка «исполнитель N» в РС / ЖР
	ПараметрыЗадания.Добавить(0);     // лимит жизни, сек; 0 = из настройки
	ФоновыеЗадания.Выполнить(
		"ОМ_ТестRMQ_Lessons.Урок2_ИсполнительВФоне",
		ПараметрыЗадания);
КонецЦикла;

// когда слушатели уже в очереди - публикуем пакет
ОМ_ТестRMQ_Lessons.Урок2_Отправитель();

Результат работы: В регистре rmq_ОчередьОбменаRMQ - исходящие записи Отправлено и входящие Подтверждено. В ЖР / окне сообщений после round-robin примерно такой лог - у продюсера строка на каждую задачу, у каждого исполнителя - после ack:

05.08.2026 19:16:36 | Старт | очередь: task_queue | данные: Урок2_Отправитель
05.08.2026 19:16:35 | Старт | очередь: task_queue | данные: Урок2_RoundRobinВОднойИБ | исполнителей=2 | задач=7 | лимитФЗ=40 с
05.08.2026 19:16:36 | Отправка в очередь | очередь: task_queue | данные: Задача 1.
05.08.2026 19:16:36 | Отправка в очередь | очередь: task_queue | данные: Задача 2..........
05.08.2026 19:16:36 | Отправка в очередь | очередь: task_queue | данные: Задача 3.
05.08.2026 19:16:36 | Отправка в очередь | очередь: task_queue | данные: Задача 4.
05.08.2026 19:16:36 | Отправка в очередь | очередь: task_queue | данные: Задача 5..
05.08.2026 19:16:36 | Отправка в очередь | очередь: task_queue | данные: Задача 6........
05.08.2026 19:16:36 | Отправка в очередь | очередь: task_queue | данные: Задача 7.
05.08.2026 19:16:36 | Окончание | очередь: task_queue | данные: Урок2_Отправитель
05.08.2026 19:16:36 | Получение из очереди | очередь: task_queue | данные: исполнитель 2 | Задача 1.
05.08.2026 19:16:36 | Старт | очередь: task_queue | данные: исполнитель 1
05.08.2026 19:16:36 | Старт | очередь: task_queue | данные: исполнитель 2
05.08.2026 19:16:37 | Получение из очереди | очередь: task_queue | данные: исполнитель 2 | Задача 3.
05.08.2026 19:16:37 | Получение из очереди | очередь: task_queue | данные: исполнитель 2 | Задача 4.
05.08.2026 19:16:38 | Получение из очереди | очередь: task_queue | данные: исполнитель 2 | Задача 5..
05.08.2026 19:16:41 | Получение из очереди | очередь: task_queue | данные: исполнитель 1 | Задача 2..........
05.08.2026 19:16:41 | Получение из очереди | очередь: task_queue | данные: исполнитель 1 | Задача 7.
05.08.2026 19:16:42 | Окончание | очередь: task_queue | данные: исполнитель 1
05.08.2026 19:16:42 | Получение из очереди | очередь: task_queue | данные: исполнитель 2 | Задача 6........
05.08.2026 19:16:43 | Окончание | очередь: task_queue | данные: исполнитель 2
05.08.2026 19:16:43 | Окончание | очередь: task_queue | данные: Урок2_RoundRobinВОднойИБ | бэклогСнят=0 | приростИсполнителей=7

Пока исполнитель 2 закрывает задачу на 10 точек (W76;5 с), у исполнитель 1 в логе подряд несколько коротких ack - это как раз эффект prefetch=1. Точный порядок строк может чуть съехать изR09;за планировщика ФЗ, важнее расклад по меткам и что лёгкие не ждут окончания «гири».

Таймаут у СоздатьПолучателя (ТаймаутПолучателяСекЧасть2 = 1) - это ожидание пустой очереди, а не «время на обработку». Пока в Ready есть сообщения, СледующееСообщение возвращает их сразу; секунда нужна только чтобы корректно выйти из цикла, когда пакет разобран.

Результат

Настроили рабочую очередь: quorum task_queue, persistent сообщения, ручное подтверждение, несколько фоновых исполнителей, предзагрузка = 1 на канале.

Дальше - часть 3: доставка одного сообщения многим получателям (Publish/Subscribe).

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

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

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

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

RabbitMQ КлиентRMQ Work Queues рабочая очередь prefetch предзагрузка ack подтверждение round-robin фоновое задание durable persistent task queue quorum 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    32455    50    49    

49

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

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

85400 руб.

05.10.2022    14075    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    54784    126    107    

86

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

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

10370 руб.

24.06.2021    26222    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    9825    25    4    

22

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

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

15250 руб.

15.05.2024    4824    8    1    

9

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

Решение позволяет по ИНН производить проверку контрагентов, получая сведения: видов деятельности, данных ЕГРЮЛ, связанных организаций, отчетности, налогов, финансовый анализ, а также в один клик заполнить карточки справочников контрагентов/партнеров по ИНН в программе 1С по данным ФНС. Попробуйте ДЕМО версию перед покупкой.

5000 руб.

12.08.2025    3891    12    20    

12
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. starik-2005 3299 27.09.24 16:07 Сейчас в теме
Статья супер, но повторение - мать учения. Я вот реально потратил кучу кликов, чтобы дойти до сорцов компоненты. Можно было бы сцылку на оное в каждую статью вставлять, а то ищешь, бывает, и находишь самое свежее, а там тридцать кликов до того, как что-то скачать.

ЗЫ: и с каждой следующей статьей этих кликов будет все больше и больше (((
2. malikov_pro 1372 28.09.24 01:13 Сейчас в теме
(1) Принято, соберу обработку после того как приведу код в порядок, сейчас стыдно ...
Чем дальше в код, тем больше костылей. То что просто сделано на python непонятно как сделать на 1С.
3. malikov_pro 1372 02.10.24 07:26 Сейчас в теме
(1) Репо на Github сделал, в статью ссылку добавил, в репо ссылку на компоненту организую.
Возможно сделаю адаптер через REST rabbitmq-management, для тестов и понимания думаю хватит.
4. starik-2005 3299 02.10.24 10:31 Сейчас в теме
(3)
адаптер через REST rabbitmq-management
Вчера читал про 27-й релиз и веб-сокет в нем. 1С как раз позиционируют это для телефонии, очередей и брокеров. Я так понял, что кролик в базовом своем сценарии через веб-сокет и работает. Так что, предположу, скоро эти все штуки будут без надобности )))
5. malikov_pro 1372 03.10.24 07:27 Сейчас в теме
(4) Благодарю за идею с ws. Но он используется через плагины:
RabbitMQ поставляется с двумя плагинами, которые могут позволить вам взаимодействовать с RabbitMQ из браузера: плагинами Web-STOMP и Web-MQTT.
Источник https://www.cloudamqp.com/blog/rabbitmq-and-websockets-part-2-web-mqtt-web-stomp-and-web-amqp.html, пред статья про форматы, полезная, думаю переведу.

Для пробы и понимания думаю лучше REST, для продакшена можно и ws, добро пожаловать в адаптеры.

27 версии платформы не обязательно ждать https://infostart.ru/1c/tools/937068/
6. starik-2005 3299 03.10.24 10:25 Сейчас в теме
(5)
27 версии платформы не обязательно ждать
Ага, 26-й - тоже )))
https://infostart.ru/1c/articles/2044928/
Для отправки сообщения требуется регистрация/авторизация