В процессе разработки интеграций с очередями сообщений RabbitMQ программисты часто сталкиваются с ситуацией, когда внешняя компонента PinkRabbitMQ идеально работает при ручном запуске обработки, но выдает критическую ошибку при попытке выполнить тот же код через регламентное задание. Проанализируем причины этой проблемы, разберем типичные ошибки в коде и выясним, как правильно инициализировать компоненты в фоновом контексте.
Рассмотрим типичную ситуацию: при запуске регламентного задания система выдает ошибку "Процедура или функция с указанным именем не определена (УстановитьВнешнююКомпоненту)". Выясним причину ее возникновения. Метод УстановитьВнешнююКомпоненту предназначен для интерактивного взаимодействия с пользователем. Он инициирует загрузку файлов компоненты в локальный каталог пользователя на клиентской машине.
Поскольку регламентное задание выполняется на сервере (в фоновом процессе), у него отсутствует понятие "клиентского сеанса" и "интерактивного интерфейса". На сервере 1С данный метод просто не существует, что и приводит к аварийному завершению модуля. Для серверного кода мы должны использовать исключительно метод ПодключитьВнешнююКомпоненту, который работает с макетами конфигурации напрямую.
Проанализируем ситуацию, описанную в обсуждении. При ручном запуске в режиме "Обычные формы" (Толстый клиент), код часто выполняется в контексте клиента. Даже если пользователь обладает полными правами, среда выполнения диктует свои правила. Рассмотрим основные отличия, которые мешают инициализации:
USR1CV8). В отличие от вашего личного профиля Windows, у системного пользователя могут быть ограничены права на запись во временные папки сервера или на доступ к реестру (если используется COM).PinkRabbitMQ.dll, сервер не сможет ее подключить.Предупреждение или Вопрос внутри логики подключения компоненты в фоне приведет к ошибке.Разберем важный нюанс, упомянутый в решении проблемы. Существует два способа подключения внешних компонент: Native API и COM.
Рассмотрим подробнее работу с ТипВнешнейКомпоненты.Native. Это современный стандарт, который не требует регистрации библиотеки в реестре Windows. Однако для его корректной работы в фоне важно, чтобы внутри ZIP-архива, хранящегося в макете, был правильно сформирован файл manifest.xml. Если манифест не содержит описания для архитектуры Windows x86_64, то на 64-битном сервере подключение не произойдет.
Посмотрим на пример, когда используется ТипВнешнейКомпоненты.COM. Этот способ требует, чтобы библиотека была зарегистрирована в операционной системе через regsvr32. В фоновых заданиях это часто становится "узким местом", так как регистрация должна быть выполнена на всех серверах кластера от имени администратора. Как показала практика участников обсуждения, иногда переключение типа подключения помогает "обойти" проблемы с манифестом Native API, но это требует внимательной настройки прав доступа системного пользователя USR1CV8.
Выясним, как должен выглядеть надежный механизм получения компоненты, работающий и на клиенте, и на сервере. Разберем по шагам правильный алгоритм:
Шаг 1. Исключаем клиентские методы. Уберем вызов УстановитьВнешнююКомпоненту. Вместо него обеспечим наличие библиотеки в общем макете конфигурации.
Шаг 2. Реализуем универсальное подключение. Используем попытку подключения с явным указанием типа. Проанализируем следующий пример кода:
Функция ПолучитьКомпонентуRabbitMQ() Экспорт
ИмяМакета = "ОбщийМакет.PinkRabbitMQ";
СимвольноеИмя = "PinkRabbit";
// Пытаемся подключить Native API
Результат = ПодключитьВнешнююКомпоненту(ИмяМакета, СимвольноеИмя, ТипВнешнейКомпоненты.Native);
Если Не Результат Тогда
// Если Native не взлетел, пробуем COM (если библиотека это поддерживает)
Результат = ПодключитьВнешнююКомпоненту(ИмяМакета, СимвольноеИмя, ТипВнешнейКомпоненты.COM);
КонецЕсли;
Если Результат Тогда
Попытка
ОбъектКомпоненты = Новый("AddIn." + СимвольноеИмя + ".PinkRabbitMQ");
Возврат ОбъектКомпоненты;
Исключение
ЗаписьЖурналаРегистрации("Ошибка RabbitMQ", УровеньЖурналаРегистрации.Ошибка, , , ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
Возврат Неопределено;
КонецПопытки;
КонецЕсли;
Возврат Неопределено;
КонецФункции
Если код выше всё равно возвращает Ложь в регламентном задании, проанализируем содержимое общего макета. Выполним следующие действия:
PinkRabbitMQ в файл (это должен быть ZIP-архив).manifest.xml.
<bundle xmlns="http://v8.1c.ru/8.2/addin/bundle">
<component os="Windows" arch="i386" path="PinkRabbitMQ_x86.dll" type="native" />
<component os="Windows" arch="x86_64" path="PinkRabbitMQ_x64.dll" type="native" />
</bundle>
Если в архиве отсутствует 64-битная версия .dll, то никакие изменения в коде 1С не помогут инициализировать компоненту на 64-битном сервере в фоновом задании. В этом случае необходимо либо использовать 32-битный сервер 1С (что не рекомендуется), либо обновить версию компоненты до поддерживающей x64.
Поскольку отладка регламентных заданий сложнее обычной, воспользуемся следующими советами. Во-первых, всегда используйте ЗаписьЖурналаРегистрации для логирования каждого шага инициализации. Это позволит увидеть, на каком именно этапе (подключение или создание объекта) происходит сбой. Во-вторых, проверьте права доступа системного пользователя USR1CV8 к папке %TEMP% на сервере. Именно туда 1С распаковывает компоненты из макета перед их загрузкой в память процесса.
Подводя итог, можно сказать, что стабильная работа PinkRabbitMQ в фоне зависит от трех факторов: отсутствия клиентских функций в коде, соответствия разрядности библиотеки разрядности сервера 1С и правильного выбора типа подключения в методе ПодключитьВнешнююКомпоненту.