Почему COM Connector в 1С жутко тормозит по сети и как это исправить?

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

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

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

Причины задержек при сетевом использовании COM Connector

Проанализируем ситуацию с технической точки зрения. Компонент V83.COMConnector основан на технологии Microsoft DCOM (Distributed COM) и протоколе RPC (Remote Procedure Call). В отличии от стандартного клиенского подключения 1С, оптимизирующего передачу данных, COM-соединение предъявляет специфические требования к сетевой инфраструктуре и авторизации:

  1. Избыточность сетевых вызовов (RPC Overhead): COM Connector выполняет обращения синхронно. Любой вызов метода, получение ссылки через ПолучитьСсылку() или запись объекта через Записать() генерируют отдельные RPC-запросы. Если между подсетями есть пусть даже небольшая сетевая задержка (Latency), суммарное время серии мелких вызовов возрастает экспоненциально.
  2. Задержки DNS и NetBIOS: В межсетевом взаимодействии (особенно вне домена Active Directory) Windows RPC пытается выполнить обратный резолвинг IP-адресов в имена хостов (Reverse DNS / PTR) или опрашивает NetBIOS. Ожидание тайм-аута при неотвечающих узлах может занимать от 15 до 45 секунд на каждый сетевой запрос.
  3. NTLM-аутентификация между серверами: Если службы 1С запущены от имени локальных пользователей без доменной сети, NTLM при каждом вызове COM-интерфейса проверяет кэш безопасности LSA и попытки валидации прав, что создает многоминутные паузы.
  4. Поиск программных лицензий (HASP): При инициализации COM-соединения платформа 1С может пытаться найти клиентскую лицензию через широковещательный запрос (Broadcast), который блокируется маршрутизаторами между разными подсетями.

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


// Инициализация соединения по сети
КомБаза = Новый COMОбъект("V83.COMConnector");
Соединение = КомБаза.Connect("Srvr=""192.168.2.10"";Ref=""BaseBUH"";Usr=""ExchangeUser"";Pwd=""Pass"";");

// Каждое обращение к методам ниже выполняется по 4-6 минут
ВнешняяСсылка = Соединение.Справочники.Показатели.ПолучитьСсылку(ВнешнийИД);
ПоказательКомОбъект = Соединение.Справочники.Показатели.СоздатьЭлемент();
ПоказательКомОбъект.Записать();

Способ 1. Запуск COM Connector на стороне целевого сервера приложений

Для того чтобы COM-объект создавался непосредственно в процессе сервера приложений, а не загружался локально с сетевыми вызовами, используем второй параметр конструктора Новый COMОбъект, передавая в него имя сервера:


// Указываем имя сервера 1С, на котором должен создаваться процесс COM
КомОбъект = Новый COMОбъект("V83.COMConnector", "ИмяСервераПриложений");
Соединение = КомОбъект.Connect("Srvr=""Server1C"";Ref=""BaseName"";Usr=""Admin"";Pwd=""123"";");

Для корректной работы данной схемы выполним настройку приложения COM+ на сервере 1С:

  1. Откроем Панель управления → Администрирование → Службы компонентов.
  2. Перейдем в ветку Компьютеры → Мой компьютер → Приложения COM+.
  3. Найдем компонент v83comconnector (если его нет, создадим новое приложение COM+ и добавим компоненты comcntr.dll).
  4. Откроем Свойства приложения COM+, перейдем на вкладку Удостоверение (Identity).
  5. Укажем учетную запись, от имени которой запущен сервер 1С:Предприятия (или единую доменную учетную запись).

Способ 2. Оптимизация сетевого окружения и файла hosts

Разберем шаг за шагом, как исключить сетевые тайм-ауты на уровне операционной системы, если использование COM Connector неизбежно:

  1. Заполнение файла hosts: На обоих серверах открываем файл C:\Windows\System32\drivers\etc\hosts и добавляем соответствия IP-адресов и сетевых имен серверов. Это исключает задержки при DNS-резолвинге.
  2. Синхронизация локальных пользователей: В среде без домена Active Directory создаем на обоих серверах локальных пользователей Windows с абсолютно идентичными логинами и паролями и запускаем службы 1С под этой учетной записью.
  3. Настройка файла nethasp.ini: В каталоге bin платформы 1С на сервере-источнике прописываем точные параметры поиска лицензий, отключив Broadcast:
    
    [NH_TCPIP]
    NH_USE_BROADCAST = Disabled
    NH_TCPIP_METHOD = TCP
    NH_SERVER_ADDR = 192.168.2.10
    

Способ 3. Переход на HTTP-сервисы (Рекомендуемое решение)

Технология COM/DCOM является устаревшей, платформозависимой (работает только в Windows) и не предназначенной для высокой нагрузки при межсетевом обмене. Практика показывает, что наиболее эффективное решение проблемы медленного COM Connector — полный отказ от него в пользу HTTP-сервисов 1С.

Преимущества HTTP-сервисов по сравнению с COM Connector:

Проанализируем пример реализации получения данных через HTTP-сервис вместо вызова COM Connector.

На стороне базы-приемника (куда раньше подключались по COM) создаем HTTP-сервис с шаблоном URL /get_data/* и методом GET:


// Функция-обработчик HTTP-запроса на стороне базы-источника данных
Функция ПолучитьДанныеGET(Запрос)
    
    Ответ = Новый HTTPСервисОтвет(200);
    Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
    
    // Формируем структуру с данными
    ДанныеСтруктура = Новый Структура;
    ДанныеСтруктура.Вставить("Идентификатор", "000000001");
    ДанныеСтруктура.Вставить("Наименование", "Показатель 1");
    
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, ДанныеСтруктура);
    
    Ответ.УстановитьТелоИзСтроки(ЗаписьJSON.Закрыть());
    Возврат Ответ;
    
КонецФункции

На стороне отправляющей базы вызов выполняем с помощью объектов HTTPСоединение и HTTPЗапрос:


// Вызов HTTP-сервиса вместо установки COM-соединения
Сервер = "192.168.2.10";
Ресурс = "/BaseBUH/hs/Exchange/get_data/";

ЗащищенноеСоединение = Неопределено;
Соединение = Новый HTTPСоединение(Сервер, 80, "WebUser", "WebPassword", , , ЗащищенноеСоединение);

Запрос = Новый HTTPЗапрос(Ресурс);
Ответ = Соединение.Получить(Запрос);

Если Ответ.КодСостояния = 200 Тогда
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
    Результат = ПрочитатьJSON(ЧтениеJSON);
    
    Сообщить("Получены данные: " + Результат.Наименование);
КонецЕсли;

Перевод обмена с COM Connector на HTTP-сервисы ускоряет выполнение процедур интеграции в десятки раз и полностью устраняет проблемы с зависанием сетевых вызовов.

← На главную