Как заменить COM-соединения на Web-сервисы в 1С и оптимизировать их работу

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

В современной разработке на платформе 1С переход с COM-соединений на Web-сервисы (SOAP) или HTTP-сервисы становится необходимостью. Основными драйверами этого процесса выступают переход на операционные системы семейства Linux, где COM не поддерживается, и потребность в более гибкой архитектуре. Однако простая замена строк кода не всегда дает ожидаемый прирост производительности. В этой статье мы подробно разберем, как правильно перевести механизмы интеграции на Web-сервисы, проанализируем статистику выполнения запросов и научимся обходить «подводные камни» сериализации данных.

Почему COM уходит в прошлое и в чем преимущество Web-сервисов

Традиционно COM-соединение использовалось для обмена данными между базами 1С благодаря простоте реализации: программист мог обращаться к объектам удаленной базы так же, как к локальным. Главный минус этой технологии — колоссальные временные затраты на инициализацию соединения. Создание COM-объекта требует запуска полноценного сеанса на стороне сервера Windows, что может занимать от 10 до 30 секунд.

Рассмотрим результаты замеров времени инициализации:

  1. COM-соединение: Время подключения (Тини) варьируется от 22 до 36 секунд.
  2. Web-сервис (WSПрокси): Время подключения составляет около 1–8 секунд при первом запуске и практически 0 секунд при повторных вызовах благодаря механизму пула соединений на веб-сервере.

Таким образом, для частых коротких запросов Web-сервисы выигрывают «всухую». Однако при работе с тяжелыми отчетами ситуация меняется, и мы разберем, почему это происходит.

Переход на Web-сервис: базовая замена кода

Рассмотрим стандартную ситуацию: нам нужно получить данные из филиала. Если раньше мы использовали выборку из запроса через COM, то теперь мы будем получать готовую таблицу значений, сериализованную в XDTO. Рассмотрим, как изменяется код на стороне клиента.

Было (через COM-соединение):


РезОбразцы = ЗапросОбразцы.Выполнить();
ВыборкаОбразцы = РезОбразцы.Выбрать();
Пока ВыборкаОбразцы.Следующий() Цикл 
    ОбработкаПрерыванияПользователя();
    стрТЗ = тзОбразцы.Добавить();
    ЗаполнитьЗначенияСвойств(стрТЗ, ВыборкаОбразцы);
    стрТЗ.НаименованиеБД = стрБД.НаименованиеБД;
КонецЦикла;

Стало (через Web-сервис):


// Выполняем запрос через прокси-функцию, которая возвращает ТаблицуЗначений
РезОбразцы = глЗапрос(Префикс, ЗапросОбразцы); 

// Обход уже готовой таблицы значений
Для каждого ВыборкаОбразцы Из РезОбразцы Цикл
    ОбработкаПрерыванияПользователя();
    стрТЗ = тзОбразцы.Добавить();
    ЗаполнитьЗначенияСвойств(стрТЗ, ВыборкаОбразцы);
    стрТЗ.НаименованиеБД = стрБД.НаименованиеБД;
КонецЦикла;

Заметим, что в случае с Web-сервисом мы избавляемся от последовательного чтения данных через Следующий(), что уменьшает количество «походов» к удаленной базе. Все данные передаются одним пакетом.

Проблема сериализации ссылочных полей и «точек» в запросах

Главная причина, по которой Web-сервис может работать медленнее COM на больших выборках — это накладные расходы на сериализацию данных в XML формат. Когда СериализаторXDTO встречает в результате запроса ссылку (например, СправочникСсылка.Номенклатура), он пытается выгрузить информацию о ней. Если же в запросе используются обращения через точку (например, ДокументПродажи.Контрагент.Наименование), платформа выполняет неявные соединения на стороне сервера, что существенно замедляет выполнение SQL-запроса.

Проанализируем пример неудачного запроса для Web-сервиса:


ТекстЗапроса = "ВЫБРАТЬ
               |    ФактПродажи.Период КАК ПериодМесяц,
               |    ФактПродажи.Номенклатура.Наименование КАК НоменклатураНаименование,
               |    ФактПродажи.СуммаПродажи КАК Сумма,
               |    ФактПродажи.ДокументПродажи.Контрагент КАК Контрагент
               |ИЗ
               |    РегистрНакопления.Продажи.Обороты(&Дата1, &Дата2) КАК ФактПродажи";

В данном случае поле Контрагент является ссылкой. При передаче 100 000 строк через Web-сервис XML-пакет станет огромным, так как для каждой ссылки будет формироваться описание типа. В COM это работает быстрее, так как передается внутренний идентификатор 1С.

Оптимизация запроса: использование простых типов и функции ВЫРАЗИТЬ

Чтобы Web-сервис работал эффективно, мы должны придерживаться правила: передавать только простые типы (Строка, Число, Дата, Булево). Если нам нужны данные из связанных справочников, их нужно получать прямо в запросе, а ссылки преобразовывать в строки (Наименование или Код) или Уникальные Идентификаторы.

Разберем правильную оптимизацию через ВЫРАЗИТЬ и левые соединения:

Вместо обращения к составному типу ДокументПродажи.Контрагент, выполним явное приведение типов и получим наименование сразу.


ТекстЗапроса = "ВЫБРАТЬ
               |    ВложенныйЗапрос.ПериодМесяц,
               |    ВложенныйЗапрос.НоменклатураНаименование,
               |    СУММА(ВложенныйЗапрос.Сумма) КАК Сумма,
               |    ВложенныйЗапрос.КонтрагентНаименование
               |ИЗ
               |    (ВЫБРАТЬ
               |        Продажи.Период КАК ПериодМесяц,
               |        Продажи.Номенклатура.Наименование КАК НоменклатураНаименование,
               |        Продажи.СуммаОборот КАК Сумма,
               |        ВЫРАЗИТЬ(Продажи.ДокументПродажи КАК Документ.РеализацияТоваров).Контрагент.Наименование КАК КонтрагентНаименование
               |    ИЗ
               |        РегистрНакопления.Продажи.Обороты(&Дата1, &Дата2) КАК Продажи
               |    ГДЕ
               |        Продажи.ДокументПродажи ССЫЛКА Документ.РеализацияТоваров) КАК ВложенныйЗапрос
               |СГРУППИРОВАТЬ ПО
               |    ВложенныйЗапрос.ПериодМесяц,
               |    ВложенныйЗапрос.НоменклатураНаименование,
               |    ВложенныйЗапрос.КонтрагентНаименование";

Результаты такой оптимизации впечатляют:

Статистика на больших объемах данных

Проанализируем критический порог, после которого COM начинает выигрывать у Web. Это происходит на очень больших выборках данных (свыше 150 000 – 200 000 строк или более 80 Мб в текстовом эквиваленте).

Сравнение при выборке в 216 000 строк:

  1. COM: Общее время 79 сек (из них 36 сек подключение, 10 сек запрос, 33 сек чтение).
  2. Web: Общее время 81 сек (из них 0 сек подключение, 65 сек выполнение и упаковка в XML, 15 сек чтение).

Мы видим, что на сверхбольших объемах XDTO-сериализатор тратит слишком много времени на упаковку данных в XML (65 секунд против 10 секунд работы SQL). Но учитывая, что COM — это технология прошлого, для таких объемов рекомендуется использовать HTTP-сервисы с передачей данных в формате JSON или порционную выгрузку.

Реализация функции на стороне Web-сервиса

Для того чтобы сделать переход максимально бесшовным, на стороне удаленной базы (филиала) создается универсальный Web-сервис. Рассмотрим пример реализации функции, которая принимает текст запроса и параметры, а возвращает ОбъектXDTO (таблицу значений).


Функция ВыполнитьЗапрос(ТекстЗапроса, СериализованныеПараметры)
    
    Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);
    
    // Распаковываем параметры запроса (структуру)
    ПараметрыЗапроса = Сериализатор.ПрочитатьXDTO(СериализованныеПараметры);
    
    Запрос = Новый Запрос(ТекстЗапроса);
    Для каждого ТекПараметр Из ПараметрыЗапроса Цикл
        Запрос.УстановитьПараметр(ТекПараметр.Ключ, ТекПараметр.Значение);
    КонецЦикла;
    
    // Выполняем и выгружаем в ТЗ
    РезультатТЗ = Запрос.Выполнить().Выгрузить();
    
    // Сериализуем всю таблицу целиком для передачи
    Возврат Сериализатор.ЗаписатьXDTO(РезультатТЗ);
    
КонецФункции

Подводим итоги: практические советы по эксплуатации

Проанализировав ситуацию, мы можем сформулировать следующие правила для успешной замены COM на Web-сервисы:

  1. Минимизируйте количество обращений. Если COM позволял делать мелкие запросы в цикле (хоть это и было медленно), то для Web-сервисов это фатально. Старайтесь собрать все данные одним тяжелым запросом на стороне сервера удаленной базы и передать их одним пакетом.
  2. Используйте временные таблицы с осторожностью. В Web-сервисах между вызовами методов состояние менеджера временных таблиц не сохраняется. Весь пакет запросов (помещение во ВТ, работа с ними, уничтожение) должен находиться внутри одного текста запроса, передаваемого в метод сервиса.
  3. Забываем про ссылки. В полях ВЫБРАТЬ и в параметрах ГДЕ используйте Наименование, Код или УникальныйИдентификатор(). Это радикально сократит объем XML-пакета и ускорит сериализацию.
  4. Индексация обязательна. Так как мы переносим логику сбора данных полностью на сторону удаленной базы, не забывайте индексировать поля во временных таблицах внутри сложного запроса. Это сократит время Тзап (время выполнения запроса), которое при работе через веб-сервер становится критичным.
  5. Кэширование WSПрокси. Не пересоздавайте объект WSПрокси при каждом обращении. Если вы опрашиваете 8 филиалов, создайте прокси один раз и храните их в кэше (например, в параметрах сеанса или глобальной переменной), пока сеанс пользователя активен.

Переход на Web-сервисы — это не просто смена синтаксиса, а изменение подхода к проектированию запросов. Следуя этим рекомендациям, вы сможете не только сохранить работоспособность системы при переходе на Linux, но и значительно ускорить получение данных за счет быстрого подключения и пакетной передачи данных.

← На главную