Хранение тяжелых утилит в макетах внешних обработок 1С: риски, влияние на память и лучшие альтернативы

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

В практике разработки на платформе 1С:Предприятие часто возникает необходимость расширить стандартные возможности системы за счет стороннего софта. Это могут быть консольные утилиты для конвертации файлов, работы с архивами, отправки специфических сетевых запросов или криптографические модули. Самым простым и соблазнительным решением кажется упаковка стороннего исполняемого файла (весом в 20 МБ и более) прямо в макет двоичных данных внешней обработки (файлы .epf или .erf). На первый взгляд, это гарантирует полную автономность: обработка сама распакует всё необходимое при первом запуске. Но так ли это «комильфо» с точки зрения архитектуры и производительности сервера? Давайте подробно разберем этот вопрос, проанализируем поведение платформы и рассмотрим наиболее надежные варианты реализации.

Влияние тяжелых обработок на оперативную память и rphost

Для начала выясним, как платформа 1С:Предприятие ведет себя при работе с внешними обработками большого объема. Когда мы вызываем метод ВнешниеОбработки.Создать(ПутьКФайлу) или используем механизмы БСП для подключения дополнительных обработок, платформа вынуждена прочитать весь файл с диска или из базы данных (если обработка хранится в справочнике).

Важный нюанс работы с памятью: даже если сам двоичный макет инициализируется как полноценный объект встроенного языка ДвоичныеДанные только при непосредственном вызове метода ПолучитьМакет(), сырой поток байтов всей обработки всё равно считывается в буфер памяти рабочего процесса rphost при ее регистрации в сеансе. Если внешняя обработка весит 22 МБ, то при каждом её создании сервер выделяет соответствующий объем оперативной памяти под хранение структуры обработки.

Представим сценарий, когда данная обработка запускается в рамках регламентного задания каждые несколько минут. Постоянное пересоздание объекта весом более 20 МБ в памяти приведет к следующим негативным последствиям:

Проблема обновления версий и кэширования утилит

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

Если в коде реализована простая проверка существования файла на диске вроде Файл.Существует(), то после обновления макета в коде 1С старая версия утилиты на сервере так и останется нетронутой. Платформа обнаружит ранее распакованный файл старой версии и продолжит использовать именно его. Чтобы этого избежать, нам придется реализовывать дополнительные проверки.

Проанализируем пример кода, который решает эту проблему за счет контроля версии через имя файла или проверку хэш-суммы MD5:


// Пример контроля версии утилиты при распаковке из макета
ИмяФайлаУтилиты = "my_utility_v1_2.exe"; // Явно указываем версию в имени
ПутьККаталогу = "C:\Services\ExternalUtilities\";
ПолныйПутьКУтилите = ПутьККаталогу + ИмяФайлаУтилиты;

ФайлНаДиске = Новый Файл(ПолныйПутьКУтилите);
Если Не ФайлНаДиске.Существует() Тогда
    // Если файла текущей версии нет, извлекаем его из макета
    МакетДвоичныеДанные = ЭтотОбъект.ПолучитьМакет("ИсполняемыйФайл");
    МакетДвоичныеДанные.Записать(ПолныйПутьКУтилите);
    
    // Опционально: удаляем старые версии утилиты из каталога, чтобы не копить мусор
    // (для этого можно перебрать файлы по маске "my_utility_*.exe")
КонецЕсли;

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

Ограничения безопасности платформы 1С 8.3

Современные версии платформы 1С:Предприятие 8.3 предъявляют жесткие требования к безопасности выполнения кода во внешних обработках. По умолчанию внешние обработки запускаются в безопасном режиме. В этом режиме платформой полностью заблокирован запуск любых внешних приложений через методы ЗапуститьПриложение() или КомандаСистемы().

Для корректной работы вашей утилиты администратору системы потребуется настроить **профили безопасности** в кластере серверов 1С и явно разрешить запуск конкретного исполняемого файла из определенного каталога. Без этой настройки вы столкнетесь с ошибками прав доступа на стороне платформы 1С, даже если у учетной записи службы usr1cv8 в операционной системе есть полные права.

Особенности работы на серверах под управлением Linux

Если серверная часть 1С работает на операционной системе Linux, хранение и запуск исполняемых файлов из макетов сталкивается с дополнительными трудностями:

  1. Права на выполнение (Execution bit): Когда платформа 1С распаковывает двоичные данные из макета во временную папку на Linux-сервере, созданный файл по умолчанию не имеет флага исполняемого файла (x). Попытка вызвать команду запуска завершится ошибкой «Доступ запрещен». Разработчику необходимо программно выдать права на исполнение перед запуском.
  2. Кроссплатформенность: Файл .exe, скомпилированный под Windows, физически не запустится на Linux без использования Wine, что крайне не рекомендуется для промышленных серверов. Соответственно, в макетах придется хранить разные версии утилит под разные ОС и программно определять текущую операционную систему.

Посмотрим, как программно установить права на выполнение файла в среде Linux из кода 1С:


// Установка прав на исполнение для Linux систем
СистемнаяИнформация = Новый СистемнаяИнформация;
Если СистемнаяИнформация.ТипПлатформы = ТипПлатформыДокументаВызова.Linux Тогда
    КомандаУстановкиПрав = "chmod +x " + ПолныйПутьКУтилите;
    ЗапуститьПриложение(КомандаУстановкиПрав, , Истина);
КонецЕсли;

Альтернативные варианты архитектуры (как сделать правильно)

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

Вариант 1. Хранение утилиты в справочнике информационной базы

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

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

Разберем пример реализации извлечения утилиты из хранилища значений:


// Пример получения бинарного файла из базы данных
Функция ПолучитьУтилитуИзБазы(ИмяУтилиты)
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   ХранилищеУтилит.ФайлХранилище КАК ФайлХранилище
        |ИЗ
        |   Справочник.ХранилищеУтилит КАК ХранилищеУтилит
        |ГДЕ
        |   ХранилищеУтилит.Наименование = &ИмяУтилиты";
        
    Запрос.УстановитьПараметр("ИмяУтилиты", ИмяУтилиты);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Если Выборка.Следующий() Тогда
        Возврат Выборка.ФайлХранилище.Получить(); // Возвращает ДвоичныеДанные
    КонецЕсли;
    
    Возврат Неопределено;
КонецФункции

Вариант 2. Использование Native API внешних компонент 1С

Если логику внешней утилиты можно переписать или обернуть в динамическую библиотеку (.dll под Windows и .so под Linux), то самым надежным решением станет создание внешней компоненты по технологии Native API. Платформа 1С умеет штатно работать с такими компонентами, автоматически кэшируя их на сервере, управляя их жизненным циклом и решая проблемы с правами доступа и кроссплатформенностью в рамках единого ZIP-архива компоненты.

Вариант 3. Загрузка утилиты из корпоративного веб-сервера (Private Cloud)

Если у вас крупная инфраструктура, правильным решением будет вынести все сторонние утилиты на внутренний веб-сервер организации. При запуске обработка проверяет локальное наличие файла, а при его отсутствии — отправляет HTTP-запрос и скачивает необходимую версию утилиты по защищенному протоколу HTTPS. Это минимизирует объем базы данных 1С и гарантирует централизованное обновление вспомогательного софта силами системных администраторов.

← На главную