При организации интеграции между базами 1С через COM-соединение (V83.COMConnector) разработчики часто сталкиваются с ситуацией, когда на локальном компьютере обмен отрабатывает за доли секунды, а при работе через интернет или корпоративный VPN-канал выполнение растягивается на долгие минуты или часы. При этом пропускная способность канала может быть отличной (десятки мегабайт в секунду). Выясним причину такого поведения и разберем способы решения проблемы.
Проанализируем технические особенности работы платформы, которые приводят к падению производительности:
Выборка.Следующий()) или обращение к реквизиту через точку — это отдельный сетевой запрос типа «запрос-ответ». Если пинг составляет 30 мс, то цикл на 10 000 итераций только на сетевые ожидания потратит: 10 000 × 0.03 с = 300 секунд (5 минут), независимо от скорости интернета.Если отказаться от COM-соединения прямо сейчас невозможно, необходимо кардинально пересмотреть архитектуру взаимодействия. Главное правило: не выполнять циклы и обращения к свойствам через границу COM-процесса.
Рассмотрим правильный подход по шагам:
ИнтеграцияСервер).JSON или XML и возвращается вызывающей стороне за один единственный COM-вызов.Посмотрим на пример неэффективного кода, который создает тысячи сетевых обращений:
// НЕПРАВИЛЬНО: тысячи сетевых запросов через COM
Соединение = Новый COMОбъект("V83.COMConnector");
База = Соединение.Connect(СтрокаПодключения);
Запрос = База.NewObject("Запрос");
Запрос.Текст = "ВЫБРАТЬ Ссылка, Номер, Дата ИЗ Документ.РеализацияТоваровУслуг";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Каждая строка выборки и каждое поле - это сетевой вызов
НомерДок = Выборка.Номер;
ДатаДок = Выборка.Дата;
КонецЦикла;
Перепишем данный алгоритм по схеме минимизации вызовов. В подключаемой базе создаем функцию:
// В общем модуле удаленной базы
Функция ПолучитьДанныеРеализацийВФорматеJSON() Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Реализация.Номер КАК Номер,
| Реализация.Дата КАК Дата,
| Реализация.СуммаДокумента КАК Сумма
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация";
Таблица = Запрос.Выполнить().Выгрузить();
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, Таблица);
Возврат ЗаписьJSON.Закрыть();
КонецФункции
На стороне вызывающей базы получаем данные за один сетевой вызов:
// В вызывающей базе
Соединение = Новый COMОбъект("V83.COMConnector");
База = Соединение.Connect(СтрокаПодключения);
// Всего один COM-вызов через сеть
СтрокаJSON = База.ИнтеграцияСервер.ПолучитьДанныеРеализацийВФорматеJSON();
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
Данные = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Если база данных файловая и расположена на удаленном сервере, подключение к ней через общий сетевой ресурс (SMB) приводит к катастрофическому падению скорости. Чтобы избежать удаленной блокировки файлов, компонент comcntr.dll настраивают как отдельное приложение COM+ (служба компонентов Windows) непосредственно на том сервере, где физически лежит база. В этом случае все файловые операции выполняются локально на сервере, а по сети передаются только готовые результаты удаленного вызова процедур.
Наиболее надежным и современным решением является полный отказ от COM-технологии в пользу платформенных сервисов 1С:
JSON. HTTP-сервисы работают быстро, не требуют настройки DCOM и стабильно передают данные по стандартным защищенным портам (HTTPS).При проектировании архитектуры на базе COM-соединений следует учитывать критические платформенные особенности:
comcntr.dll (32-бит или 64-бит) должны строго совпадать.