Как запустить внешнюю обработку в фоновом задании на многосерверном кластере 1С без общих сетевых папок?

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

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

В этой статье мы подробно разберем, почему возникает эта ошибка, как функционирует кластер 1С при работе с временными файлами, и рассмотрим несколько эффективных способов решения этой проблемы без необходимости разворачивать общие сетевые ресурсы (NAS/DFS) для серверов кластера.

---

Выясняем причину: почему фоновые задания теряют файл обработки?

Проанализируем классический сценарий, который приводит к ошибке:

  1. Пользователь открывает внешнюю обработку через меню «Файл — Открыть» (или обработка запускается программно на клиенте).
  2. Для выполнения длительной операции на сервере код обработки отправляет файл на сервер-инициатор, где он сохраняется во временную папку операционной системы (например, в каталог сеанса рабочего процесса rphost).
  3. Инициируется запуск фонового задания с помощью функции БСП ДлительныеОперации.ЗапуститьВыполнениеВФоне, куда передается путь к созданному временному файлу на сервере.
  4. Если в кластере активен только один рабочий сервер, то фоновое задание стартует на нем же. Оно без проблем находит файл по локальному пути и выполняет код.
  5. Если в кластере функционируют несколько рабочих серверов и настроена балансировка нагрузки, диспетчер кластера распределяет новые фоновые задания на другие физические серверы. Эти серверы пытаются обратиться к переданному локальному пути (например, C:\Users\...\AppData\Local\Temp\...), но у них собственная изолированная файловая система. Файла обработки там физически нет, что и приводит к системной ошибке.

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

---

Решение 1. Использование подсистемы БСП «Дополнительные отчеты и обработки» (Рекомендуемый способ)

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

Если обработка зарегистрирована в справочнике БСП ДополнительныеОтчетыИОбработки, двоичные данные файла обработки хранятся непосредственно в базе данных (в защищенном хранилище). Механизмы БСП автоматически синхронизируют и извлекают эти данные на любом сервере кластера, где бы ни запустилось фоновое задание.

Рассмотрим, как выглядит вызов фонового задания через БСП в этом случае:


ПараметрыВыполнения = Новый Структура;
ПараметрыВыполнения.Вставить("ДополнительнаяОбработкаСсылка", СсылкаНаОбъектСправочника);
ПараметрыВыполнения.Вставить("ИмяМетода", "ВыполнитьДлительнуюОперацию");
ПараметрыВыполнения.Вставить("ПараметрыВыполнения", ВашаСтруктураПараметров);
ПараметрыВыполнения.Вставить("ЭтоВнешняяОбработка", Истина);

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

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

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

---

Решение 2. Передача двоичных данных через Временное хранилище (Для динамической работы)

Если нам необходимо сохранить возможность запуска обработки «из файла» без ее предварительной регистрации в справочниках БСП, мы можем обойти ограничение файловой системы с помощью платформенного механизма Временного хранилища. Данные во временном хранилище реплицируются между всеми рабочими серверами кластера 1С.

Разберем по шагам, как реализовать этот алгоритм:

Шаг 1. Подготовка и передача данных с клиента на сервер

На стороне клиента (или сервера-инициатора) мы считываем файл внешней обработки в объект ДвоичныеДанные и помещаем его во временное хранилище. При этом крайне важно привязать адрес хранилища к уникальному идентификатору формы или фонового задания, чтобы платформа не очистила эти данные до момента старта фонового процесса.


&НаСервере
Функция ПодготовитьОбработкуКПередаче(ПутьКФайлу)
    
    // Считываем обработку в двоичные данные
    ДвоичныеДанныеОбработки = Новый ДвоичныеДанные(ПутьКФайлу);
    
    // Помещаем во временное хранилище с привязкой к УникальномуИдентификатору формы
    АдресВХ = ПоместитьВоВременноеХранилище(ДвоичныеДанныеОбработки, УникальныйИдентификатор);
    
    Возврат АдресВХ;
    
КонецФункции

Шаг 2. Разработка процедуры-обертки для фонового задания

Поскольку стандартный метод БСП ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки ожидает имя файла, мы напишем собственный метод-прослойку в общем модуле (например, в модуле КастомныеПроцедурыСервер с установленными свойствами "Сервер", "Вызов сервера"). Этот метод будет выполняться уже внутри контекста фонового задания.


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

Шаг 3. Инициализация фонового задания

Теперь мы можем запустить фоновое задание через стандартный интерфейс БСП, передав структуру параметров с адресом временного хранилища:


АдресВХ = ПодготовитьОбработкуКПередаче(Объект.ИспользуемоеИмяФайла);

ПараметрыЗапуска = Новый Структура;
ПараметрыЗапуска.Вставить("АдресВХ", АдресВХ);
ПараметрыЗапуска.Вставить("ИмяМетода", "ВыполнитьРасчетДанных");
ПараметрыЗапуска.Вставить("ПараметрыМетода", Новый Структура("ДатаНачала, ДатаОкончания", Объект.ДатаНачала, Объект.ДатаОкончания));

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

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

---

Решение 3. Настройка требований назначения функциональности в кластере (Административный метод)

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

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

Рассмотрим порядок настройки через консоль администрирования кластера (утилиту MMC или rac):

  1. Откройте дерево консоли администрирования и перейдите к списку рабочих серверов вашего кластера.
  2. Выберите сервер, который должен обрабатывать все фоновые задания (обычно это центральный сервер кластера, на котором также хранятся временные файлы сеансов).
  3. Перейдите в раздел «Требования назначения функциональности» этого сервера.
  4. Добавьте новое правило со следующими параметрами:
    • Тип объекта: Фоновое задание (или конкретный сервис BackgroundJob.CommonModule).
    • Тип требования: Назначать.
    • Имя метода: можно оставить пустым или указать конкретные фоновые задания БСП.
  5. Для всех остальных серверов кластера добавьте аналогичное требование, но с типом требования Не назначать.
  6. Примените требования назначения функциональности для кластера.

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

---

Резюме: какой метод выбрать?

Выбор оптимального подхода зависит от стадии жизненного цикла вашей разработки:

← На главную