Обмен данными между базами 1С: от файлов до очередей

Двенадцать магазинов, три базы 1С и папка обмена на файловом сервере. Каждые 30 минут регламентное задание выгружает остатки из 1С:ERP в XML, кладёт файл в сетевую папку, а 1С:Розница забирает его при следующем запуске. Между выгрузкой и загрузкой проходит от 15 до 45 минут. За это время кассир продаёт товар, которого на складе уже нет. Менеджер закупок видит остатки часовой давности. Иногда файл не записывается до конца, и загрузка падает с ошибкой разбора XML. Иногда два регламентных задания пытаются записать файл одновременно, и один из них получает отказ доступа.

Знакомая ситуация. Файловый обмен — первый способ синхронизации баз 1С, который осваивает каждый разработчик. Он работает. До тех пор, пока бизнес не вырастает за пределы одной базы и пяти пользователей.

Файловый обмен — классика, которая не масштабируется

Стандартный механизм обмена между конфигурациями 1С — планы обмена и сериализация в XML. Работает это так: план обмена фиксирует изменения в зарегистрированных объектах (документах, справочниках, регистрах), формирует сообщение обмена и записывает его в файл. Принимающая сторона читает файл, десериализует объекты и записывает в свою базу. Всё прозрачно, всё типовое, всё задокументировано в стандартах 1С.

Проблемы начинаются при масштабировании.

Задержка. Обмен выполняется по расписанию — обычно раз в 5-30 минут. Данные актуальны на момент последней выгрузки. Для бухгалтерии, где документы проводят раз в день, это нормально. Для розничной сети, где остатки меняются каждую минуту, — нет. Интервал между продажей в магазине и отражением этой продажи в ERP может составлять час.

Хрупкость транспорта. Файл — ненадёжный носитель. Сетевая папка может быть недоступна (сервер перезагружается, VPN-канал упал, диск переполнен). Файл может быть прочитан до полной записи — и загрузка упадёт на невалидном XML. Два процесса могут попытаться записать файл одновременно. Антивирус может заблокировать файл на время проверки. Каждый из этих сценариев мы видели в рабочих системах.

Отсутствие обратной связи. Отправляющая сторона не знает, получил ли адресат сообщение. Не знает, обработал ли. Не знает, была ли ошибка при загрузке. Единственный способ узнать — посмотреть в журнале регистрации принимающей базы. Вручную. Постфактум.

Масштабирование количества узлов. Два узла обмена — один файл в одну сторону. Три узла — уже шесть файлов (каждый с каждым). Двенадцать магазинов плюс центральная ERP — 24 файловых потока. Каждый может сломаться независимо. Мониторить 24 регламентных задания и 24 файловых потока — задача, которая съедает время администратора.

Конфликты. Если один и тот же объект изменён в двух базах между циклами обмена, возникает конфликт. Типовой механизм планов обмена решает это приоритетом узла: кто главнее — тот перезаписывает. Но «главнее» — грубый инструмент. Менеджер в магазине исправил телефон контрагента, а бухгалтер в центральной базе — юридический адрес. При следующем обмене одно из изменений потеряется. Без ручной проверки никто об этом не узнает.

Сравнение файлового обмена и очереди сообщений для синхронизации 1С

Всё это не значит, что файловый обмен бесполезен. Для синхронизации справочников между двумя базами с интервалом в час он работает нормально и будет работать ещё десятилетия. Проблема — в инерции: когда бизнес вырастает, архитектуру обмена не пересматривают. Продолжают наращивать файловые потоки, добавлять костыли для обхода гонок и потерь, писать обработки-мониторы, которые проверяют, пришёл ли файл. В какой-то момент поддержка файлового обмена занимает больше времени, чем работа с данными.

COM-соединение и прямой доступ — быстро, но хрупко

Когда файловый обмен перестаёт устраивать, первая идея — подключиться к другой базе напрямую. В мире 1С для этого есть COM-соединение (COMConnector) и, реже, прямой доступ к SQL-базе.

COM-соединение позволяет из кода одной базы 1С обратиться к другой: прочитать данные, выполнить запрос, вызвать серверную процедуру, создать документ. Технически это работает через объект V83.COMConnector, который создаёт сеанс во второй базе и даёт доступ к её объектной модели. Задержка — миллисекунды, данные — актуальные.

Преимущества очевидны: реальное время, нет промежуточных файлов, нет десериализации, можно использовать бизнес-логику целевой базы (а не обходить её).

Ограничения — менее очевидны, но существенны:

  • Только Windows. COM — технология Microsoft. Если сервер 1С работает на Linux (а это всё чаще встречается с ростом популярности PostgreSQL), COM-соединение невозможно. Точнее, возможно, но через wine/dbus, и это не тот уровень надёжности, который нужен в продуктиве.
  • Блокировки и зависания. COM-соединение создаёт полноценный сеанс в целевой базе. Если вызванный код повисает (бесконечный цикл, ожидание блокировки, нехватка памяти), повисает и вызывающая сторона. Timeout на уровне COM-вызова настроить нельзя. Мы видели ситуации, когда зависшее COM-соединение блокировало регламентное задание в вызывающей базе на часы.
  • Утечки ресурсов. Каждое COM-соединение — это процесс rphost в целевой базе. Если соединение не закрывается корректно (исключение, сбой вызывающей стороны), процесс остаётся висеть. За сутки накапливаются десятки «мёртвых» сеансов, которые потребляют лицензии и память.
  • Нет работы через интернет. COM-соединение требует прямого сетевого доступа к серверу 1С. Для баз в одной локальной сети — нормально. Для удалённого магазина, подключённого через VPN, — латентность и нестабильность канала делают COM ненадёжным.
  • Сложность отладки. Когда что-то падает внутри COM-вызова, стек ошибки теряет контекст вызывающей стороны. Найти, почему загрузка документов из ERP в Розницу упала в четверг в 14:32, — задача для детектива, а не для разработчика.

Прямой доступ к SQL — ещё более радикальный подход. Из кода 1С (или из внешнего скрипта) выполняются SQL-запросы к базе другой конфигурации. Это быстро — прямое чтение таблиц, без объектной модели. И это опасно: структура таблиц 1С не документирована, меняется при обновлениях, имена полей — транслитерированные хэши. Запись напрямую в SQL обходит всю бизнес-логику 1С: подписки на события, проведение документов, контроль остатков. Данные оказываются в базе, но проводки не формируются, регистры не заполняются, связанные документы не обновляются.

Мы используем COM-соединение ровно в двух сценариях: автоматизированное тестирование (когда обе базы на одном сервере и контролируются) и разовая миграция данных (где скорость важнее отказоустойчивости). Для постоянного обмена между рабочими базами COM — слишком хрупкий инструмент. Аналогичный вывод справедлив и для интеграции с внешними системами — если нужен надёжный канал, стоит рассматривать REST API как интеграционный слой.

Очереди сообщений — когда обмену нужна надёжность

Очередь сообщений — архитектурный паттерн, при котором отправитель кладёт сообщение в очередь (брокер), а получатель забирает его оттуда, когда готов. Отправитель и получатель не знают друг о друге, не зависят друг от друга, не должны быть доступны одновременно.

В мире корпоративных систем очереди используются десятилетиями: IBM MQ, Apache Kafka, RabbitMQ, Redis Streams. В мире 1С этот подход долго оставался экзотикой — типовые конфигурации ориентированы на файловый обмен. Но когда количество баз и объём данных выходят за пределы файловой схемы, очередь сообщений становится естественным следующим шагом.

Что даёт очередь по сравнению с файлом:

Гарантированная доставка. Сообщение, принятое брокером, не потеряется. Если получатель недоступен, сообщение ждёт в очереди — минуту, час, сутки. Когда получатель восстановится, он заберёт все накопленные сообщения. Файл в сетевой папке такой гарантии не даёт: если папка недоступна в момент записи, файл просто не создаётся.

Подтверждение обработки (acknowledge). Получатель забирает сообщение, обрабатывает и отправляет подтверждение. Если получатель упал до подтверждения, брокер возвращает сообщение в очередь и отдаёт другому получателю (или тому же после перезапуска). Ни одно сообщение не теряется при сбоях.

Маршрутизация. Брокер может направлять сообщения по правилам: сообщения об остатках — в Розницу, о ценах — на сайт, о заказах — в ERP. Один отправитель, несколько получателей, каждый получает только то, что ему нужно. В файловой схеме для этого пришлось бы создавать отдельные папки и отдельные правила обмена для каждого направления.

Скорость. Сообщение попадает к получателю за миллисекунды после отправки. Нет расписания, нет интервалов, нет ожидания следующего цикла.

Масштабирование. Нужно добавить ещё одну базу-получатель? Создаём новую подписку на очередь. Нужно обрабатывать больше сообщений? Запускаем несколько потребителей параллельно. Брокер распределяет нагрузку.

Жизненный цикл сообщения при обмене данными между базами 1С

Самые распространённые брокеры для интеграции с 1С — RabbitMQ и Apache Kafka. RabbitMQ проще в настройке, поддерживает протокол AMQP, хорошо подходит для задач «доставить каждое сообщение ровно одному получателю». Kafka заточен под потоковую обработку больших объёмов данных, хранит историю сообщений, позволяет перечитывать поток с произвольной точки. Для обмена между базами 1С в большинстве случаев хватает RabbitMQ.

Взаимодействие 1С с брокером реализуется через HTTP: RabbitMQ предоставляет Management API (REST), а также поддерживает протокол STOMP over WebSocket. Из 1С отправляем POST-запрос с телом сообщения в JSON, получаем ответ с подтверждением. Для чтения — GET-запрос к очереди. Никаких внешних компонент, никаких нестандартных протоколов. Стандартный HTTPСоединение, который доступен на любой платформе 1С начиная с 8.3.10.

Как мы внедряли RabbitMQ для розничной сети (кейс)

Розничная сеть: 12 точек продаж, центральный офис, 80 пользователей. Три базы 1С: ERP (управление, закупки, финансы), Розница (кассы, продажи, остатки в магазинах), Бухгалтерия (регламентированный учёт). Обмен между ними — через планы обмена и файлы в сетевых папках. Регламентные задания запускались каждые 15 минут.

Проблемы, с которыми обратились:

  • Остатки в ERP отставали от реальных продаж на 15-45 минут. Менеджеры закупок работали с неактуальными данными. Два раза за месяц заказывали товар, который уже был на складе, — просто не видели приход, обработанный в Рознице.
  • Файлы обмена терялись. В среднем 2-3 раза в неделю файл не записывался (сетевая папка была недоступна из-за перезагрузки файлового сервера) или записывался не полностью (тайм-аут записи). Обнаруживали это через часы, когда кто-то замечал расхождение данных.
  • Рассинхронизация номенклатуры. Новый товар, созданный в ERP, появлялся в Рознице через 30-60 минут. Если менеджер магазина принимал поставку до синхронизации, он не мог оприходовать товар и вводил его вручную — с ошибками в наименовании, без артикула, без привязки к группе.
  • Конфликты при обмене цен. Маркетолог менял цены в ERP, но до загрузки в Розницу проходило 15-30 минут. В это время кассиры продавали по старым ценам. Иногда файл с ценами «обгонял» файл с документами, и Розница получала цены, ссылающиеся на номенклатуру, которая ещё не загрузилась.

Что мы сделали.

Первый этап — анализ потоков данных. Мы задокументировали все 24 направления обмена (12 магазинов x 2 направления между Розницей и ERP, плюс ERP-Бухгалтерия). Для каждого направления определили: какие объекты передаются, какой объём, какая допустимая задержка, какие зависимости между объектами (нельзя отправить документ, пока не отправлен справочник номенклатуры).

Второй этап — развёртывание RabbitMQ. Установили брокер на отдельном Linux-сервере (2 ядра, 4 ГБ RAM — для такого объёма более чем достаточно). Создали структуру очередей:

  • erp.nomenclature — справочник номенклатуры из ERP, fanout exchange (раздаётся всем подписчикам: Розница, Бухгалтерия)
  • erp.prices — цены из ERP, fanout
  • retail.sales.{store_id} — продажи из каждого магазина, direct exchange в ERP
  • retail.receipts.{store_id} — кассовые чеки, direct exchange в Бухгалтерию
  • erp.orders — заказы поставщикам, direct exchange в Бухгалтерию

Третий этап — формат сообщений. Отказались от XML в пользу JSON. Причина прагматичная: JSON компактнее (в наших тестах — на 40% меньше по объёму на тех же данных), быстрее парсится, проще отлаживать (можно прочитать глазами в интерфейсе RabbitMQ Management). Каждое сообщение — один объект (один документ, одна позиция справочника). Не пакет из 500 объектов, а 500 отдельных сообщений. Это позволяет обрабатывать каждый объект независимо: если загрузка одного документа упала, остальные 499 не застревают в ожидании.

Структура сообщения:

{
  "type": "document",
  "entity": "SalesReceipt",
  "action": "create",
  "source": "retail-store-05",
  "timestamp": "2025-11-14T16:23:07+03:00",
  "correlationId": "a3f7b2c1-...",
  "payload": {
    "number": "РН-000412",
    "date": "2025-11-14T16:22:54+03:00",
    "store": "Магазин №5",
    "items": [
      {"sku": "00-001234", "quantity": 2, "price": 15.40, "sum": 30.80},
      {"sku": "00-005678", "quantity": 1, "price": 42.00, "sum": 42.00}
    ],
    "total": 72.80,
    "paymentType": "card"
  }
}

Поле correlationId — сквозной идентификатор, позволяющий отследить путь объекта от создания в Рознице до отражения в ERP и Бухгалтерии. Поле action (create, update, delete) определяет, что делать с объектом на принимающей стороне.

Четвёртый этап — код на стороне 1С. В каждой базе создали подсистему обмена с двумя компонентами: отправитель и получатель. Отправитель — подписка на событие ПриЗаписи для зарегистрированных объектов. Документ проведён — подписка формирует JSON и отправляет POST-запросом в RabbitMQ Management API. Получатель — регламентное задание, которое каждые 3 секунды забирает сообщения из очереди (GET-запрос с параметром count=100 и ackmode=ack_requeue_false). Забрал — разобрал JSON — записал объект — подтвердил.

Важный момент: регламентное задание работает с интервалом 3 секунды, но это не значит, что задержка — 3 секунды. Задание запускается, забирает все накопленные сообщения (до 100 за раз), обрабатывает и завершается. Если сообщений нет — завершается мгновенно. Фактическая задержка от отправки до обработки — от 0.3 до 3 секунд, в среднем 0.8 секунды.

Пятый этап — обработка ошибок и мониторинг. Если загрузка сообщения упала (невалидный JSON, ссылка на несуществующий объект, ошибка проведения), сообщение перемещается в очередь ошибок (dead letter queue) с описанием проблемы. Администратор видит ошибки в интерфейсе RabbitMQ Management и в Telegram-канале (настроили webhook). Исправить можно без перезапуска обмена: поправили причину, переместили сообщение из dead letter обратно в рабочую очередь.

Архитектура обмена данными 1С через очередь сообщений RabbitMQ

Результаты после трёх месяцев работы:

МетрикаФайловый обменRabbitMQ
Средняя задержка синхронизации18 минут0.8 секунды
Потерянные сообщения за месяц8-120
Пропускная способность~800 объектов/час12 400 сообщений/час
Время обнаружения сбоя1-4 часа (вручную)30 секунд (алерт)
Среднее время восстановления20-40 минутАвтоматическое (retry)
Метрики обмена данными 1С в продакшене — скорость и надёжность

Отдельно стоит отметить побочный эффект: команда перестала тратить время на «починку обменов». До перехода администратор тратил 3-5 часов в неделю на разбор инцидентов с файловым обменом (файл не дошёл, данные рассинхронизировались, нужно запустить полную синхронизацию). После перехода эти инциденты прекратились. Если в обмене 1С с внешними системами (сайтом, CRM) тоже возникают потери и задержки, подходы из этого кейса применимы и там — подробнее в материале про обмен данными между 1С и интернет-магазином.

Какой вариант выбрать — зависит от задачи

Не существует универсального способа обмена. Каждый инструмент решает свой класс задач, и выбирать нужно от требований, а не от технологической моды.

Файловый обмен по-прежнему оправдан, если:

  • Две базы 1С, одна сеть, интервал обмена 30+ минут устраивает бизнес
  • Обмен справочниками (номенклатура, контрагенты) без жёстких требований к оперативности
  • Нет ресурса на администрирование дополнительной инфраструктуры
  • Типовые конфигурации с типовыми планами обмена — всё работает из коробки

COM-соединение — для узких сценариев:

  • Разовая миграция данных между базами на одном сервере
  • Автоматизированное тестирование (создание тестовых данных, проверка результатов)
  • Синхронный вызов, где нужен немедленный ответ и обе базы на Windows в одной сети

Очередь сообщений — когда масштаб требует надёжности:

  • Три и более баз-участников обмена
  • Допустимая задержка — секунды, а не минуты
  • Потеря данных недопустима (финансовые операции, остатки, заказы)
  • Нужна маршрутизация: разные данные — разным получателям
  • Удалённые базы через интернет (филиалы, магазины, склады в других городах)

Сводная таблица для быстрого выбора:

КритерийФайловый обменCOM-соединениеОчередь (RabbitMQ)
ЗадержкаМинутыМиллисекундыСекунды
Гарантия доставкиНетНет (при сбое)Да
ПлатформаЛюбаяТолько WindowsЛюбая
МасштабируемостьНизкаяНизкаяВысокая
Обратная связьНетСинхроннаяAcknowledge
Работа через интернетFTP/SFTPНетДа (HTTPS)
ИнфраструктураСетевая папкаНичегоСервер брокера
Сложность внедренияНизкаяСредняяВысокая

Часто оптимальный путь — эволюционный. Начинаете с файлового обмена (типовые планы обмена, минимум доработок). Когда бизнес вырастает — добавляете очередь для критичных потоков (остатки, продажи, цены), а файловый обмен оставляете для тяжёлых пакетных операций (полная синхронизация справочников раз в сутки). Радикальная замена «всё и сразу» — дороже и рискованнее, чем постепенный переход.

Ещё один фактор, который часто упускают, — формат данных. XML, который генерирует типовой план обмена, содержит внутренние идентификаторы 1С, ссылки на объекты метаданных, служебные поля. Это удобно для обмена между двумя базами 1С, но бесполезно для интеграции с внешними системами: сайтом, CRM, мобильным приложением. Если среди получателей есть не-1С-системы, JSON через очередь — единственный разумный выбор. Подробнее о том, как строить такой мост, — в материале про интеграцию 1С с CRM.

Технология обмена — такая же часть архитектуры, как структура базы или набор отчётов. Она должна соответствовать текущему масштабу бизнеса и иметь запас на рост. Двенадцать магазинов с файловой папкой — это не архитектурное решение, а привычка. Иногда привычки стоит пересматривать.