В современной практике автоматизации ритейла часто встречается ситуация, когда компания имеет разветвленную филиальную сеть. При этом учет ведется в одной базе 1С, но каждый филиал (город) представлен отдельным поддоменом на сайте Битрикс (например, spb.site.ru, nsk.site.ru). Каждый такой поддомен требует своих цен, своих остатков по конкретным складам и, зачастую, работает от имени разных юридических лиц.
Основная сложность здесь заключается в организации обмена данными. Если создать для каждого поддомена отдельный узел обмена и запустить их одновременно, система начинает выдавать ошибки. Рассмотрим подробнее, почему это происходит и как правильно спроектировать архитектуру такого обмена, чтобы данные всегда оставались актуальными.
Проанализируем ситуацию: почему при наличии пяти разных настроек обмена в 1С, направленных на разные поддомены одного и того же сайта, возникают ошибки «потери файлов» или «конфликта принятия данных»? Разработчики Битрикса часто называют это «архитектурной особенностью», и это действительно так.
Стандартный механизм обмена CommerceML работает через загрузку файлов во временную папку на сервере (обычно /upload/1c_catalog/). Когда 1С инициирует обмен, Битрикс создает сессию и блокирует возможность одновременной записи для предотвращения повреждения базы данных. Даже если выгрузка идет на разные поддомены, ядро CMS, база данных и папка импорта у них чаще всего общие. Если вторая выгрузка «вклинивается» в момент, когда первая еще не закончила распаковку или обработку import.xml, происходит коллизия. Файлы могут перезаписываться, а процесс импорта прерываться с ошибкой.
Самый надежный способ решить проблему — гарантировать, что в каждый конкретный момент времени выполняется только одна выгрузка. Распределение по времени (расписанием) — решение ненадежное, так как объем данных всегда разный: сегодня 100 товаров выгрузились за 1 минуту, а завтра из-за обновления картинок процесс занял 15 минут, и следующий обмен «наложился» на предыдущий.
Выясним, как создать простейший «Диспетчер обменов». Вместо того чтобы назначать каждому узлу обмена свое стандартное регламентное задание, мы создадим одно общее задание, которое будет последовательно перебирать узлы. Проанализируем пример логики на встроенном языке 1С:
Процедура ВыполнитьПоследовательныйОбмен() Экспорт
СписокУзлов = ПолучитьСписокАктивныхУзловОбмена(); // Функция возвращает массив ссылок на настройки обмена
Для Каждого Узел Из СписокУзлов Цикл
// Проверяем, не запущено ли уже это задание вручную или другим процессом
Если ЗаданиеВыполняется(Узел) Тогда
Продолжить;
КонецЕсли;
Попытка
// Запуск штатной процедуры обмена для конкретного узла
ОбменДаннымиСайт.ВыполнитьОбменДаннымиПоНастройке(Узел);
ЗаписатьЛог("Обмен успешно завершен для: " + Узел.Наименование);
Исключение
ЗаписатьЛог("Ошибка при обмене " + Узел.Наименование + ": " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Такой подход позволяет избежать любых пересечений. Следующий филиал начнет выгрузку только тогда, когда Битрикс полностью освободит ресурсы после предыдущего. Это гарантирует целостность XML-пакетов.
Рассмотрим ситуацию, когда разработчики со стороны сайта просят добавлять префиксы к идентификаторам свойств (например, SPB_Цвет, MSK_Цвет). Это плохая практика, которая ведет к неоправданному раздуванию базы данных Битрикса. Если у товара 300 свойств и у вас 10 филиалов, сайт получит 3000 уникальных записей в таблице свойств, что замедлит работу фильтров и SEO-модулей.
Правильнее будет использовать унифицированные свойства. Разберем по шагам, как этого добиться:
GUID свойства в 1С одинаковый для всех выгрузок, Битрикс поймет, что это одно и то же свойство, и просто обновит его значения.Существует способ «научить» Битрикс принимать несколько обменов одновременно, если доработать скрипт приема (1c_exchange.php). Рассмотрим подробнее: штатно 1С при первом запросе получает от сервера Cookie с идентификатором сессии. Если в 1С настроить использование уникальных логинов для каждого филиала, то на стороне PHP можно разнести процессы по разным сессиям.
Однако помните, что это не решает проблему блокировки таблиц в базе данных MySQL. Если два процесса начнут одновременно обновлять остатки одного и того же товара, возникнет Deadlock. Поэтому последовательная выгрузка (Решение №1) остается приоритетной.
Для каждого филиального узла в 1С необходимо настроить жесткие фильтры. Разберем, что именно должно входить в настройку каждого узла:
Проанализируем ситуацию с передачей заказов обратно в 1С. Если у вас несколько настроек обмена, важно, чтобы заказы с поддомена nsk.site.ru попадали именно в «новосибирский» узел обмена. Это настраивается на стороне Битрикса в параметрах компонента «Интеграция с 1С», где указывается, по какому идентификатору (логину) или адресу сайта фильтровать заказы для выгрузки.
Если филиалов становится слишком много (более 20-30) и последовательный обмен перестает укладываться в приемлемое время (например, цикл занимает 2 часа, а обновлять остатки нужно каждые 15 минут), стоит рассмотреть переход с файлов XML на REST API.
В этом случае 1С не отправляет тяжелые файлы, а вызывает конкретные методы сайта для обновления конкретного поля. Например, изменился остаток на одном складе — 1С сразу отправила JSON-запрос. Это исключает блокировки файлов и позволяет обновлять данные практически в реальном времени. Однако это требует существенных трудозатрат программиста для написания своих обработок обмена на стороне 1С.
Подведем итог: Для стабильной работы филиальной структуры в связке 1С + Битрикс наиболее эффективным и простым в реализации методом является использование единого менеджера очередей в 1С, который поочередно запускает регламентные задания для каждого поддомена, исключая их одновременное выполнение.