Многие разработчики при настройке обмена между 1С:Управление торговлей и 1С-Битрикс (или другими CMS) задаются вопросом: как системе удается передавать гигабайты данных (каталоги, остатки, изображения) через обычный протокол HTTP, не упираясь в лимиты хостинга и не используя FTP? Кажется невероятным, что файл размером в несколько сотен мегабайт или даже гигабайт может быть «проглочен» скриптом exchange.php на обычном виртуальном хостинге. Разберем детально механизмы, которые позволяют это реализовать.
Для начала проанализируем общую схему. Обмен данными строится не на разовой отправке «всего и сразу», а на четко регламентированном протоколе взаимодействия. Рассмотрим основные этапы, которые проходит 1С при инициации выгрузки. Процесс начинается с авторизации (запрос mode=checkauth) и последующей инициализации (запрос mode=init).
Именно на этапе инициализации происходит магия. Сайт отвечает 1С строкой параметров, среди которых есть file_limit. Рассмотрим, что это означает. Параметр file_limit указывает 1С максимальный размер порции данных (в байтах), которую сервер готов принять за один раз. Если 1С видит, что сформированный XML-файл или ZIP-архив больше этого значения, она не пытается отправить его целиком.
Проанализируем ситуацию: у нас есть файл выгрузки размером 100 Мб, а сервер в параметре file_limit указал 2 Мб (стандартное ограничение для многих PHP-конфигураций). В этом случае 1С выполняет следующие действия:
Таким образом, на сервере постепенно «склеивается» исходный архив. Это позволяет обходить настройки post_max_size и upload_max_filesize в php.ini, так как каждый отдельный запрос не превышает установленных лимитов. Посмотрим на пример логики, которая может использоваться при записи файла на стороне сервера (упрощенно на языке PHP):
// Принимаем данные из входного потока
$content = file_get_contents("php://input");
// Дописываем данные в файл (флаг FILE_APPEND)
file_put_contents($tempFilePath, $content, FILE_APPEND);
Загрузить файл — это только половина дела. Его нужно распаковать и импортировать в базу данных. Если файл содержит 50 000 товаров, попытка обработать его за один запуск скрипта приведет к ошибке Maximum execution time exceeded. Выясним, как решается эта проблема.
Система использует итерационный подход. После того как файл полностью загружен, 1С отправляет запрос на импорт (mode=import). Сервер начинает обработку:
progress.Проанализируем реакцию 1С: получив progress, она не завершает сеанс, а тут же отправляет новый запрос на импорт. Сервер открывает файл с сохраненного места и обрабатывает следующую порцию. Так продолжается до тех пор, пока весь файл не будет прочитан.
Рассмотрим, почему нам крайне редко приходится передавать те самые «200 гигабайт», о которых упоминалось в обсуждении. В типовых конфигурациях 1С (УТ, УНФ, ERP) используется механизм ПланыОбмена.
Вместо того чтобы каждый раз выгружать всю номенклатуру, система регистрирует только изменения. Если бухгалтер изменил цену только у двух товаров, в XML-файл попадут только эти два товара. Полная выгрузка выполняется только один раз при первоначальной настройке.
Для реализации такой логики в коде 1С используются объекты ПланыОбменаМенеджер. Посмотрим на пример регистрации изменений:
// Регистрируем изменения для узла обмена с сайтом
ПланыОбмена.ЗарегистрироватьИзменения(УзелСайта, СсылкаНаТовар);
При выгрузке 1С выбирает данные, используя метод ВыбратьИзменения(), что гарантирует минимальный объем передаваемого файла.
Несмотря на интеллектуальные алгоритмы дробления, стабильность обмена сильно зависит от настроек серверной части. Рассмотрим ключевые параметры, которые стоит проверить системному администратору:
file_limit, который передает сайт в 1С. Если 1С пытается отправить 5 Мб, а в Nginx стоит лимит 2 Мб, сервер вернет ошибку 413 Request Entity Too Large еще до того, как запрос дойдет до PHP./bitrix/tmp/1c_catalog/ (для Битрикса) или аналогичную директорию. Именно там происходит сборка фрагментов файлов.PUT позволяет передавать данные напрямую во входной поток, что иногда эффективнее работы с POST и переменными формы, так как данные не буферизируются в памяти PHP целиком.Изображения — это самая тяжелая часть данных. Выясним, как 1С справляется с ними. Обычно картинки упаковываются в ZIP-архив вместе с основным файлом import.xml. Если картинок очень много, 1С может быть настроена на отправку их отдельными архивами. Благодаря сжатию и тому же механизму file_limit, даже папки с фотографиями высокого разрешения успешно доходят до сервера по частям.
Таким образом, «магия» передачи огромных объемов данных через HTTP строится на трех столпах:
Разберем типичную ошибку начинающих разработчиков: попытку написать свой модуль обмена, который формирует один гигантский файл и пытается отправить его одним запросом POST. Теперь мы понимаем, почему такой подход обречен на провал на больших базах и почему штатный механизм 1С работает гораздо надежнее, используя цепочку последовательных запросов и подтверждений.