При реализации систем обмена данными часто возникает ситуация, когда стандартные механизмы выгрузки не справляются с возросшим объемом медиаконтента. Рассмотрим сценарий: клиенту необходимо выгружать гибко настраиваемые списки объектов через FTP, при этом сопровождая их изображениями, которые нужно «на лету» конвертировать из PDF в форматы JPG/PNG с заданными размерами. Основная проблема заключается в длительности процесса конвертации (около 5 секунд на один файл) и сложности синхронизации ссылок в выгружаемых файлах с реальным наличием картинок на удаленном сервере.
В данной статье мы разберем комплексный подход к решению этой задачи, включающий асинхронную обработку, кэширование и использование производительных библиотек для передачи данных.
Если процесс подготовки данных занимает значительное время (например, час на одного клиента), классическая синхронная выгрузка становится неэффективной. Проанализируем модель работы через токены, которая позволяет клиенту не ждать окончания процесса в режиме реального времени.
Алгоритм работы выглядит следующим образом:
HTTP-сервису с запросом на получение данных.РегламентноеЗадание, которое выполняет тяжелые операции: выборку данных по СКД, конвертацию PDF через ImageMagick и загрузку на FTP.XML/JSON файл, где уже прописаны корректные пути к загруженным изображениям.Рассмотрим пример структуры хранения таких запросов в РегистреСведений:
// Структура регистра "ОчередьЗапросовНаВыгрузку"
// Измерения: Токен (Строка)
// Ресурсы: Статус (Перечисление: ВОбработке, Готов, Ошибка), ПутьКФайлу (Строка), ПараметрыВыгрузки (ХранилищеЗначения)
Стандартные средства работы с FTP в 1С могут работать недостаточно быстро при передаче большого количества мелких файлов. Выясним, как библиотека WinSCP помогает ускорить этот процесс и сделать его более надежным. Использование этой библиотеки позволяет работать через протокол SFTP и получать детальный ответ о завершении операции передачи.
Проанализируем пример кода для интеграции WinSCP через COM-объект:
Попытка
Сессия = Новый COMОбъект("WinSCP.Session");
ПараметрыСессии = Новый COMОбъект("WinSCP.SessionOptions");
ПараметрыСессии.Protocol = 1; // SFTP
ПараметрыСессии.HostName = "ftp.yourserver.com";
ПараметрыСессии.UserName = "user";
ПараметрыСессии.Password = "password";
Сессия.Open(ПараметрыСессии);
ОпцииПередачи = Новый COMОбъект("WinSCP.TransferOptions");
ОпцииПередачи.TransferMode = 1; // Binary
РезультатПередачи = Сессия.PutFiles(ЛокальныйПуть, УдаленныйПуть, Ложь, ОпцииПередачи);
РезультатПередачи.Check(); // Вызывает исключение при ошибке
// Если выполнение дошло сюда, значит файл успешно загружен
Сообщить("Файл успешно передан на сервер.");
Исключение
Сообщить("Ошибка передачи: " + ОписаниеОшибки());
КонецПопытки;
Чтобы избежать повторной конвертации одного и того же PDF-файла под нужды разных клиентов (или повторных выгрузок одного клиента), необходимо реализовать систему кэширования. Постоянная генерация картинок «с нуля» — это самая дорогая операция в данном процессе.
Как организовать эффективное кэширование:
РегистрСведений.КэшИзображений, где в качестве измерений будем использовать ссылку на исходный объект (или имя файла) и параметры трансформации (ширину, высоту, формат).Посмотрим на логику проверки наличия файла в кэше перед запуском конвертера:
Функция ПолучитьКартинуДляВыгрузки(ОбъектСсылка, Ширина, Высота)
// Ищем в регистре сведений
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ПутьКФайлу ИЗ РегистрСведений.КэшИзображений
ГДЕ Объект = &Объект И Ширина = &Ширина И Высота = &Высота";
Запрос.УстановитьПараметр("Объект", ОбъектСсылка);
// ... установка остальных параметров
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() И ФайлСуществуетНаДиске(Выборка.ПутьКФайлу) Тогда
Возврат Выборка.ПутьКФайлу;
Иначе
// Запускаем ImageMagick, сохраняем в том, регистрируем в кэше
НовыйПуть = СконвертироватьPDF(ОбъектСсылка, Ширина, Высота);
ЗаписатьВКэш(ОбъектСсылка, Ширина, Высота, НовыйПуть);
Возврат НовыйПуть;
КонецЕсли;
КонецФункции
Если серверные мощности позволяют, процесс конвертации можно значительно ускорить за счет распараллеливания. Вместо последовательной обработки 200 объектов, мы можем разбить массив на части и запустить несколько ФоновыхЗаданий.
Рассмотрим важный нюанс: при запуске внешних программ через ЗапуститьПриложение (например, magick.exe), каждое фоновое задание будет потреблять ресурсы процессора и памяти. Необходимо ограничивать количество одновременно работающих потоков (например, не более количества ядер процессора), чтобы не вызвать отказ всей системы.
Для еще большего ускорения процесса можно рассмотреть использование более быстрых утилит, чем ImageMagick, для специфической задачи извлечения страниц из PDF. Например, инструменты на базе Poppler (pdftoppm) часто показывают лучшие результаты по скорости рендеринга первой страницы документа.
Также, чтобы клиент понимал актуальность данных на FTP, рекомендуется после завершения полной выгрузки записывать в корень каталога обмена файл-манифест (например, manifest.json) с контрольными суммами всех файлов. Это позволит клиентской стороне мгновенно определять, какие картинки изменились, не скачивая их целиком.
Подведем итог: Комбинируя асинхронную работу через HTTP-сервисы, надежную передачу через WinSCP и обязательное кэширование результатов в Томах, мы превращаем тяжелую и медленную процедуру в стабильно работающий конвейер обмена данными.