Почему зависают фоновые и регламентные задания в 1С 8.3 при выгрузке на FTP?

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

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

Анализ основной причины: зависание сокетов при работе с FTP-соединением

Если зависающее фоновое задание связано с обменом данными (выгрузка файлов каталогов, остатков, заказов или прайс-листов во внешние системы), в подавляющем большинстве случаев зависание происходит на уровне сетевого вызова встроенного объекта FTPСоединение при выполнении методов Записать() или Получить().

По умолчанию, если при инициализации объекта не передан таймаут, операционная система может удерживать открытый сетевой сокет часами, ожидая ответа от удаленного сервера. Если на промежуточном сетевом оборудовании (роутере, межсетевом экране, NAT-шлюзе) происходит тихий сброс сессии (silent drop) без отправки TCP-пакета с флагом RST, 1С продолжает бесконечно ожидать ответа. Решением проблемы является обязательное явное указание таймаута при создании объекта.

Рассмотрим пример корректной инициализации FTP-подключения с контролем времени ожидания и пассивным режимом:


ТаймаутПодключения = 30; // Таймаут в секундах
ПассивныйРежим = Истина;
ПортFTP = 21;

Попытка
    СоединениеFTP = Новый FTPСоединение(
        АдресСервера,
        ПортFTP,
        ПользовательFTP,
        ПарольFTP,
        , // Прокси
        ПассивныйРежим,
        ТаймаутПодключения
    );
    
    СоединениеFTP.Записать(ПутьКЛокальномуФайлу, ПутьНаСервере);
    
    // Освобождаем дескрипторы для сборщика мусора
    СоединениеFTP = Неопределено;
Исключение
    СоединениеFTP = Неопределено;
    ЗаписьЖурналаРегистрации(
        "ВыгрузкаFTP",
        УровеньЖурналаРегистрации.Ошибка,,,
        ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())
    );
    ВызватьИсключение;
КонецПопытки;

Обратите внимание на явное присвоение переменной значения Неопределено в блоке исключения и после успешной отправки. Это позволяет рабочему процессу rphost своевременно закрыть файловые и сетевые дескрипторы сокетов, предотвращая утечки ресурсов операционной системы.

Влияние активного и пассивного режима передачи данных

Еще одной распространенной причиной зависания метода Записать() или Получить() является работа в активном режиме FTP. Выясним разницу:

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

Проверка настроек расписания и количества повторов

Проанализируем распространенную ситуацию: регламентное задание не зависает физически, но создает иллюзию непрерывного зависания. Это происходит, когда в свойствах расписания регламентного задания настроен бесконечный перезапуск при ошибке.

  1. Откроем свойства регламентного задания в конфигураторе либо в режиме «1С:Предприятие» через панель администрирования регламентных заданий.
  2. Перейдем к настройке расписания на вкладку Дневное.
  3. Проверим параметры блока Повторять при аварийном завершении. Если там задано ненулевое количество повторов с коротким интервалом (например, 10 секунд), а сетевой ресурс недоступен, задание будет немедленно перезапускаться после каждого падения.
  4. Если задача не успевает очистить состояние или блокирует таблицу регистрации изменений, на сервере образуется непрерывная череда аварийных сессий, визуально выглядящая как одно «вечно висящее» задание. Для отладки рекомендуется временно отключить автоматические повторы при ошибке.

Детальное протоколирование и локализация зависания

Если регламентное задание по-прежнему зависает, необходимо точно установить, на какой строке исходного кода останавливается выполнение. Разберем два основных инструмента локализации проблемы.

Способ 1. Точечное логирование в Журнал регистрации

Добавим в код регламентной процедуры контрольные точки перед каждым потенциально опасным действием:


ЗаписьЖурналаРегистрации("ФоновыйОбмен", УровеньЖурналаРегистрации.Информация,,, "Начало формирования файла выгрузки");
СформироватьФайлНаДиске(ПутьКФайлу);

ЗаписьЖурналаРегистрации("ФоновыйОбмен", УровеньЖурналаРегистрации.Информация,,, "Попытка подключения к FTP-серверу");
ПодключитьсяКFTP(ПараметрыПодключения);

ЗаписьЖурналаРегистрации("ФоновыйОбмен", УровеньЖурналаРегистрации.Информация,,, "Отправка файла по FTP начата");
ОтправитьФайл(ПутьКФайлу);

ЗаписьЖурналаРегистрации("ФоновыйОбмен", УровеньЖурналаРегистрации.Информация,,, "Выгрузка успешно завершена");

Сравнивая временные метки событий в журнале регистрации, можно точно определить шаг, после которого запись перестает появляться, что указывает на зависшую операцию.

Способ 2. Технологический журнал платформы

Для серверных баз (включая базы на СУБД PostgreSQL) эффективным методом является настройка технологического журнала (logcfg.xml) на сбор событий:

  1. EXCP — фиксирует системные исключения и сетевые разрывы;
  2. TIMEOUT и TLOCK — отслеживают таймауты управляемых блокировок и взаимные блокировки данных в СУБД;
  3. SCALL — регистрирует длительные вызовы серверных процедур.

Блокировки данных на уровне СУБД PostgreSQL

Иногда зависание регламентного задания вызвано не сетевым протоколом, а блокировками транзакций. Перед отправкой файла задание часто считывает данные из таблиц регистрации изменений или записывает статус выгрузки в регистр сведений.

Если другое задание или действие пользователя параллельно блокирует те же строки, процесс уходит в ожидание. Для PostgreSQL рекомендуется настроить защитные лимиты в файле postgresql.conf:

  1. lock_timeout — задает максимальное время ожидания захвата блокировки таблицы или строки. Если время превышено, СУБД прерывает команду, и платформа 1С получает управляемую ошибку, которую можно обработать в конструкции Попытка ... Исключение.
  2. statement_timeout — ограничивает максимальное время выполнения любого SQL-запроса, предотвращая бесконечное выполнение дефектных планов запросов.
  3. idle_in_transaction_session_timeout — автоматически закрывает соединения, которые открыли транзакцию и перешли в режим ожидания.

Альтернативные архитектурные решения

Если встроенный механизм FTPСоединение продолжает работать нестабильно из-за особенностей локальной сетевой инфраструктуры или прокси-серверов, рассмотрим альтернативные варианты передачи данных:

  1. Использование внешних консольных утилит: вызов проверенных утилит (например, curl) через метод ЗапуститьПриложение(). Данные утилиты позволяют тонко задавать параметры подключения, таймауты на соединение, максимальную скорость передачи и гарантированно завершают дочерний процесс операционной системы.
  2. Переход на современные протоколы обмена: замена устаревшего протокола FTP на REST API по протоколу HTTPS через объект HTTPСоединение либо использование безопасного протокола SFTP. Протокол HTTP работает через единый стандартный порт, прозрачно маршрутизируется прокси-серверами и не имеет проблем с блокировкой динамических портов брандмауэрами.
← На главную