Как организовать частую выгрузку цен и остатков из 1С на сайт в формате JSON без потерь производительности?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При интеграции 1С с интернет-магазинами часто возникает задача оперативного обновления данных. Когда количество товаров исчисляется десятками тысяч, а склады и типы цен исчисляются десятками, стандартные методы выгрузки «всего подряд» перестают работать. Обновление каждые 5 минут требует от системы ювелирной точности: нужно передавать только то, что изменилось, при этом не блокируя работу пользователей и не создавая избыточную нагрузку на сервер. В этой статье мы разберем, как построить эффективную систему дельта-выгрузки, используя современные механизмы платформы 1С.

Анализ проблемы: почему стандартные подходы могут подвести?

Традиционно разработчики рассматривают два пути: использование Планов обмена или ручное сравнение остатков. Однако в условиях высокой интенсивности записей (большие документы перемещения, массовое обновление прайс-листов) оба метода имеют недостатки. Ручное сравнение запросом требует хранения «слепка» данных на момент предыдущей выгрузки, что удваивает объем хранимой информации. Стандартные планы обмена, в свою очередь, при регистрации изменений регистров накопления часто фиксируют только документ-регистратор. Это вынуждает систему при обмене перебирать все строки документа, даже если изменился остаток только по одной позиции, что создает лишнюю нагрузку.

Рассмотрим, как оптимизировать эти процессы, перейдя от модели «синхронизируем всё по расписанию» к модели «синхронизируем асинхронно только измененное».

Решение №1: Использование промежуточной очереди в Регистре Сведений

Один из самых надежных способов — создание собственной «очереди задач». Вместо того чтобы пытаться выгрузить данные в момент проведения документа, мы лишь фиксируем факт изменения объекта. Это позволяет минимизировать время транзакции и избежать блокировок веб-сервиса.

Алгоритм реализации:

  1. Создадим непериодический Регистр Сведений ОчередьВыгрузкиНаСайт с измерениями Номенклатура, Склад (если нужно) и ресурсом ДатаИзменения.
  2. Создадим Подписку на событие ПриЗаписи для Регистров Накопления (остатки) и Регистров Сведений (цены).
  3. В обработчике подписки будем записывать в наш регистр только ссылки на те товары, которые реально изменились.

Проанализируем пример кода для подписки на запись набора записей регистра остатков:


Процедура ПриЗаписиРегистраОстатков(Источник, Отказ, Замещение) Экспорт
    
    // Источник — это НаборЗаписей регистра накопления
    ТаблицаИзменений = Источник.ВыгрузитьКолонку("Номенклатура");
    // Удаляем дубли, чтобы не писать лишнего в очередь
    ТаблицаИзменений.Свернуть("Номенклатура");
    
    Для Каждого Стр Из ТаблицаИзменений Цикл
        МенеджерЗаписи = РегистрыСведений.ОчередьВыгрузкиНаСайт.СоздатьМенеджерЗаписи();
        МенеджерЗаписи.Номенклатура = Стр.Номенклатура;
        МенеджерЗаписи.ДатаИзменения = ТекущаяДатаСеанса();
        МенеджерЗаписи.Записать();
    КонецЦикла;
    
КонецПроцедуры

Такой подход гарантирует, что даже при отмене проведения документа или частичном изменении табличной части, в очередь попадут именно те ссылки, которые затронуты движениями. Фоновое задание, запускаемое каждые 5 минут, будет считывать записи из этого регистра, формировать JSON и очищать отработанные строки.

Решение №2: Оптимизация планов обмена

Если вы всё же решили использовать Планы обмена, важно обойти проблему регистрации только «Регистратора». Чтобы система знала конкретные товары, которые изменились, необходимо в той же подписке на событие регистрировать изменения программно для каждого товара.

Выясним, как это сделать правильно:


// Вместо автоматической регистрации используем программную
ПланыОбмена.ЗарегистрироватьИзменения(УзелСайта, МассивИзмененныхТоваров);

При этом при выгрузке данных следует использовать выборку порциями и метод ВыбратьИзменения(). Чтобы не блокировать таблицу изменений при интенсивной работе, рекомендуется использовать «грязное чтение» в запросах к виртуальным таблицам остатков, если бизнес-логика допускает небольшую погрешность в моменте.

Решение №3: Потоковое формирование JSON (Streaming)

При работе с 20 000 позиций формирование одной огромной структуры Соответствие или Структура для последующей сериализации в JSON может привести к перерасходу оперативной памяти и падению рабочего процесса 1С. Разберем, как использовать объект ЗаписьJSON для потоковой записи данных.

Рассмотрим правильный подход к генерации файла:


ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(ПутьКФайлу, "UTF-8");

ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("items");
ЗаписьJSON.ЗаписатьНачалоМассива();

Пока ВыборкаДанных.Следующий() Цикл
    // Записываем каждый товар отдельно, не загружая всё в память
    СтруктураТовара = Новый Структура("id, price, stock", 
        ВыборкаДанных.Код, 
        ВыборкаДанных.Цена, 
        ВыборкаДанных.Остаток);
    ЗаписатьДанныеJSON(ЗаписьJSON, СтруктураТовара);
КонецЦикла;

ЗаписьJSON.ЗаписатьКонецМассива();
ЗаписьJSON.ЗаписатьКонецОбъекта();
ЗаписьJSON.Закрыть();

Использование метода ЗаписатьДанныеJSON в цикле позволяет системе эффективно сбрасывать данные в поток, что критически важно для частого обмена.

Решение №4: Современный подход через DataVersion (Версионирование данных)

Для конфигураций на платформе 8.3 существует еще один изящный способ отслеживания изменений без использования планов обмена — поле DataVersion. Каждая запись в базе данных имеет скрытую системную версию. Вместо сложной логики сравнения, мы можем сохранять «номер последней выгруженной версии».

Проанализируем преимущества:

Практические советы по снижению трафика

Чтобы еще больше оптимизировать обмен, воспользуемся советами опытных разработчиков:

  1. Качественная оценка вместо количественной: Если остаток товара на складе больше определенного порога (например, > 100 шт.), не нужно выгружать точное число при каждом изменении. Достаточно передать статус «Много». Это сократит количество срабатываний триггера выгрузки в разы.
  2. Асинхронность и многопоточность: Если выгрузка JSON занимает значительное время, можно разделить данные на несколько пакетов и отправлять их в несколько потоков через фоновые задания.
  3. Использование HTTP-сервисов: Вместо того чтобы 1С «стучалась» на сайт, можно реализовать HTTP-сервис в 1С. Сайт сам будет запрашивать изменения (Pull-модель), когда его ресурсы свободны. 1С в ответ отдаст JSON только с теми позициями, которые изменились с момента указанной в запросе даты.

Важный нюанс с отменой проведения: При отмене документа перемещения остатки товаров обнуляются или уменьшаются. Чтобы сайт об этом узнал, в вашей очереди (или плане обмена) обязательно должна фиксироваться ссылка на товар. Даже если текущие остатки по нему стали нулевыми, он должен попасть в выборку выгрузки, чтобы JSON содержал актуальное значение "stock": 0.

Подводя итог, можно сказать, что для системы с 20 000 товаров оптимальным выбором будет сочетание промежуточного Регистра Сведений (очереди) и потоковой записи JSON в фоновом задании. Это обеспечит максимальную отзывчивость системы для пользователей и гарантированную доставку изменений на сайт.

← На главную