Можно ли сохранить COM-подключение к базе 1С для повторного использования и как ускорить соединение

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

При регулярном обмене данными с множеством информационных баз 1С разработчики сталкиваются с заметными задержками при инициализации внешних подключений. Инициализация COM-соединения через V83.COMConnector к каждой отдельной базе может занимать от 10 до 20 секунд. Возникает закономерный вопрос: можно ли единожды получить COM-объект подключения к удаленной базе, сохранить его в базе данных, файле или хранилище настроек и затем мгновенно переиспользовать в следующих сеансах?

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

Почему COM-соединение невозможно сохранить в постоянное хранилище или файл

Проанализируем природу COM-объекта в операционной системе и платформе 1С. Объект подключения, возвращаемый методом Connect(), не содержит в себе копию удаленной базы данных. Он представляет собой неуправляемый системный указатель в оперативной памяти текущего процесса на интерфейс IDispatch / IUnknown библиотеки COM-соединения.

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

  1. Мутабельность и отсутствие сериализации: COM-объекты являются мутабельными значениями. Платформа 1С не поддерживает сериализацию указателей памяти в поток байтов. Ни метод ЗначениеВФайл(), ни ЗначениеВСтрокуВнутр(), ни объект СериализаторXDTO, ни стандартные функции СохранитьЗначение() не способны сохранить живое межпроцессное или сетевое соединение на диск.
  2. Привязка к адресному пространству процесса: при завершении сеанса или перезапуске рабочего процесса сервера 1С (rphost) адресное пространство уничтожается. Даже если бы существовал способ записать байты указателя в файл, при чтении в новом процессе этот адрес указывал бы в пустоту или на чужие данные в памяти.

Поведение COM-объектов во временном хранилище и кэше

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

Однако здесь действуют строгие системные правила работы с кэшем временного хранилища:

  1. При помещении значения во временное хранилище без привязки к уникальному идентификатору формы оно удерживается в кэше оперативной памяти сервера.
  2. Стандартное время удержания значения в кэше с момента последнего обращения составляет около 20 минут.
  3. По истечении 20 минут платформа пытается сбросить содержимое кэша временного хранилища на диск. Поскольку COM-объект невозможно сериализовать и записать на диск, он безвозвратно уничтожается сборщиком мусора, а попытка повторного вызова по сохраненному адресу завершается ошибкой.

Расход серверных клиентских лицензий при удержании подключений

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

  1. Каждое активное COM-соединение к серверной информационной базе регистрируется на сервере 1С:Предприятия как полноценный сеанс внешнего подключения.
  2. Если программные лицензии установлены на сервере 1С, они выдаются сервером приложений по принципу «одна лицензия на одно соединение/сеанс».
  3. Если обработка удерживает открытыми соединения к 40 информационным базам одновременно, сервер заблокирует 40 клиентских лицензий на все время жизни этих объектов в памяти.

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

Способы оптимизации и повторного использования соединений

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

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


Функция ПолучитьCOMСоединениеКБазе(СтрокаПодключения) Экспорт
    
    COMКоннектор = Новый COMОбъект("V83.COMConnector");
    
    Попытка
        Возврат COMКоннектор.Connect(СтрокаПодключения);
    Исключение
        ЗаписьЖурналаРегистрации("COM-Соединение", УровеньЖурналаРегистрации.Ошибка,,, 
            "Не удалось подключиться к базе: " + ОписаниеОшибки());
        Возврат Неопределено;
    КонецПопытки;
    
КонецФункции

При вызове такой функции с одинаковой строкой подключения платформа вернет уже созданный в текущем сеансе объект без повторной авторизации. Однако после завершения сеанса соединение будет закрыто автоматически.

Использование встроенного пула соединений COMConnector

Объект V83.COMConnector предоставляет встроенный механизм пула соединений, который управляется свойствами самого коннектора. Разберем доступные параметры пула:

  1. PoolCapacity — максимальное количество неиспользуемых соединений, удерживаемых в пуле.
  2. PoolTimeout — время (в секундах), в течение которого свободное соединение остается в пуле перед его автоматическим закрытием.
  3. MaxServerConnections — предельное количество одновременно открытых соединений с сервером.

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


Коннектор = Новый COMОбъект("V83.COMConnector");
Коннектор.PoolCapacity = 10;
Коннектор.PoolTimeout = 60; // удержание соединения в течение 60 секунд
Коннектор.MaxServerConnections = 20;

Соединение = Коннектор.Connect(СтрокаПодключения);
// Выполнение необходимых операций выборки данных
// ...
// Явное освобождение переменной для возврата в пул
Соединение = Неопределено;

При повторном вызове метода Connect() с теми же параметрами в течение интервала PoolTimeout платформа мгновенно возьмет готовое соединение из пула без накладных расходов на создание сеанса.

Архитектурные альтернативы COM-соединениям

Для регулярного обмена с большим количеством баз (десятки узлов) использование COM-технологии архитектурно устарело. Рассмотрим более эффективные и современные альтернативы:

  1. HTTP-сервисы: разработка легковесных HTTP-сервисов на стороне баз-источников. Вызовы по протоколу HTTP(S) с передачей данных в формате JSON выполняются за доли секунды, не создают тяжелый контекст клиентского сеанса и потребляют лицензию только на время выполнения конкретного запроса.
  2. Стандартный интерфейс OData: публикация стандартного REST-интерфейса OData в базах-источниках позволяет читать остатки, документы и справочники простыми HTTP-запросами без программирования кода на стороне удаленной базы.
  3. Параллелизация опроса через фоновые задания: если требуется опрашивать базы через COM, процесс опроса 40 баз следует распараллелить с помощью объекта ФоновыеЗадания. Запуск нескольких параллельных потоков сокращает общее время ожидания с нескольких минут до нескольких секунд.
← На главную