Как реализовать многопоточное скачивание файлов с FTP с помощью фоновых заданий

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе интеграции 1С с внешними системами часто возникает задача обмена файлами через FTP-сервер. Когда количество файлов исчисляется сотнями или тысячами (например, до 500 файлов за один сеанс), последовательное скачивание в одном потоке становится узким местом. Это затягивает время выполнения регламентных заданий и может привести к задержкам в обработке данных. Оптимальным решением в такой ситуации является использование многопоточности через механизм фоновых заданий 1С. Разберем подробно, как выстроить этот процесс, и проанализируем основные технические нюансы.

Основной алгоритм многопоточного скачивания

Для эффективной параллельной работы нельзя просто запускать фоновое задание на каждый чих. Рассмотрим правильную последовательность действий, которая позволит избежать дублирования данных и избыточной нагрузки на сервер:

  1. Получение общего списка файлов: Сначала мы устанавливаем одно соединение в основном потоке (или в управляющем фоновом задании) и считываем список всех доступных файлов на FTP.
  2. Разделение списка на пакеты: Весь массив имен файлов делится на равные части в зависимости от количества планируемых потоков.
  3. Запуск фоновых заданий: Для каждого пакета файлов запускается отдельное фоновое задание, в которое передается массив имен.
  4. Скачивание в потоке: Каждое фоновое задание самостоятельно устанавливает соединение с FTP и последовательно скачивает файлы из своего списка.

Проанализируем пример кода для инициализации этого процесса. Предположим, у нас есть функция, которая разделяет массив на части:


// Пример разделения списка файлов на порции
МассивВсехФайлов = ФТПСоединение.НайтиФайлы(ПутьНаФТП, "*");
КоличествоПотоков = 5;
РазмерПакета = Цел(МассивВсехФайлов.Количество() / КоличествоПотоков) + 1;

Для НомерПотока = 1 По КоличествоПотоков Цикл
    ТекущийПакет = Новый Массив;
    // Наполняем пакет именами файлов
    Для Итератор = (НомерПотока - 1) * РазмерПакета По Мин(НомерПотока * РазмерПакета - 1, МассивВсехФайлов.Количество() - 1) Цикл
        ТекущийПакет.Добавить(МассивВсехФайлов[Итератор].Имя);
    КонецЦикла;
    
    Если ТекущийПакет.Количество() > 0 Тогда
        ПараметрыЗадания = Новый Массив;
        ПараметрыЗадания.Добавить(ТекущийПакет);
        ФоновыеЗадания.Выполнить("ИнтеграцияФТП.СкачатьПакетФайлов", ПараметрыЗадания);
    КонецЕсли;
КонецЦикла;

Особенности работы с объектом FTPСоединение

Разберем важный технический момент: объект FTPСоединение не является сериализуемым. Это означает, что вы не можете создать соединение в основной процедуре и передать его как параметр в фоновое задание. Выясним, как это влияет на архитектуру:

Внутри процедуры СкачатьПакетФайлов, которая выполняется в фоновом задании, необходимо заново инициализировать подключение. Рассмотрим пример такой процедуры:


Процедура СкачатьПакетФайлов(МассивИмен) Экспорт
    // Параметры подключения должны быть доступны или переданы
    Соединение = Новый FTPСоединение(АдресСервера, Порт, Логин, Пароль, , Истина); // Пассивный режим
    
    Для Каждого ИмяФайла Из МассивИмен Цикл
        Попытка
            Соединение.Получить(ПутьНаСервере + ИмяФайла, ЛокальныйПуть + ИмяФайла);
            // После успешного скачивания файл нужно обработать или переместить
        Исключение
            ЗаписатьЛогОшибки("Ошибка скачивания файла " + ИмяФайла + ": " + ОписаниеОшибки());
        КонецПопытки;
    КонецЦикла;
КонецПроцедуры

Важно: Всегда используйте ПассивныйРежим = Истина. В современных сетевых инфраструктурах, где серверы 1С часто находятся за NAT или защищены брандмауэрами, активный режим FTP часто приводит к зависанию на командах получения данных.

Подводные камни и ограничения сервера

При реализации многопоточности мы неизбежно столкнемся с аппаратными и программными ограничениями. Рассмотрим их подробнее:

1. Лимиты соединений: Большинство FTP-серверов имеют ограничение на количество одновременных подключений с одного IP-адреса. Если вы запустите 50 потоков, сервер может заблокировать ваш IP или просто выдавать ошибку 421 Too many connections. Рекомендуем ограничить количество потоков разумным числом (обычно от 3 до 8).

2. Проблема "недописанных" файлов: Если сторонняя система загружает файлы на FTP в тот же момент, когда 1С начинает их скачивать, вы рискуете получить поврежденный или пустой файл. Разберем способы решения:

3. Ресурсы сервера 1С: Каждое фоновое задание — это полноценный сеанс, который потребляет оперативную память. Если файлы большие, активное скачивание может существенно нагрузить рабочий процесс rphost. Следите за тем, чтобы суммарный объем потребляемой памяти не привел к перезагрузке рабочих процессов.

Контроль целостности и повторные попытки

В многопоточной среде критически важно понимать статус каждого файла. Мы рекомендуем использовать вспомогательный Регистр сведений для логирования процесса. Перед запуском заданий записи в регистр помечаются как "В очереди". По мере скачивания статус меняется на "Скачан" или "Ошибка".

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

Безопасность и протоколы (SFTP vs FTP)

Стандартный объект 1С FTPСоединение работает с протоколами FTP и FTPS (через SSL). Однако следует помнить, что он не поддерживает SFTP (SSH File Transfer Protocol). Если ваш контрагент требует именно SFTP, вам не удастся решить задачу встроенными средствами FTPСоединение. В этом случае придется использовать внешние компоненты или запускать консольные утилиты, такие как WinSCP или curl, через метод ЗапуститьПриложение(). При этом логика разделения списка файлов на пакеты останется прежней, изменится только механизм самого скачивания в фоновом задании.

Заключение

Реализация многопоточного скачивания — это отличный способ оптимизировать тяжелые интеграционные процессы. Главное — соблюдать баланс между скоростью и стабильностью. Не пытайтесь задействовать слишком много потоков, всегда обрабатывайте исключения внутри фоновых заданий и обязательно используйте пассивный режим подключения. Такой подход обеспечит надежную и быструю работу вашей системы обмена данными.

← На главную