Кэширование COM-соединения. Три способа

Статья о трех способах кэширования COM-соединения в 1С:Предприятии 8.x.

Предисловие

Решали ли Вы задачи интеграции на платформе 1С:Предприятие? Если да, то Вам наверняка приходилось настраивать обмен данными между информационными базами 1С:Предприятия или с другими информационными системами через COM-соединение. С ростом интенсивности использования подобного обмена начинает вставить вопрос оптимизации — сокращение времени на выполнение обмена или даже создания обмена в реальном времени. 

В подобных условиях использовать COM-объект соединения становится проблематичным, ведь при каждом подключении к другой базе он полностью загружает конфигурацию. А если в качестве конфигурации выступает, скажем, «Управление производственным предприятием», где размер конфигурации давно превысил 200 МБ? Тогда время на инициализацию соединения будет значительным. А использовать COM-соединение для обмена по «тонким» каналам связи будет вообще не возможно!

В статье рассмотрим три способа кэширования COM-объекта соединения с целью оптимизации скорости подключения и обмена.

 

Подробнее

Для наглядного представления путей решения подобной задачи обратимся к следующей схеме:

Три способа кэширования COM-соединения

Самым простым, но наименее универсальным является способ кэширования объекта соединения в глобальной переменной модуля формы. Такой способ подойдет, если COM-соединение используется редко в какой-либо обработке или другом объекте конфигурации. Для постоянного использования соединения этот способ вряд ли подойдет, ведь при открытии формы будет необходимо вновть инициализировать соединение, что займет значительное время из-за загрузки конфигурации подключаемой базы. Практический пример использования такого способа Вы можете посмотреть в статье «Поддержка COM-соединения. Часть №1».

 

В противовес первому способу по сложности предлагается кэшировать COM-соединение на отдельной машине, веб-сервере. Например, можно создать веб-сервис, который будет инициализировать соединение через COM-объект при первом обращении. Далее подключаемые к веб-сервису клиенты смогут работать с кэшированным соединением, выполняя все необходимые методы объекта. С точки зрения производительности и экономии лицензий сервера 1С:Предприятия это идеальный вариант, но его выбор обоснован только в том случае, если в дальнейшем работа с этим соединением будет интенсивным. Иначе получится, что мы поставим купим и настроим отдельную машину с веб-сервером, который будет кэшировать соединение для нескольких пользователей. А это не рационально. Статью о практической реализации такого способа кэширования COM-соединения Вы можете посмотреть здесь: «Поддержка COM-соединения. Часть №2».

 

Но что, если использоваться COM-соединение будет часто, но не настолько, чтобы тратиться на реализации последнего предложенного варианта, при этому использовать глобальные переменные модуля формы также не вариант — соединение должно кэшироваться не для одной формы, а для нескольких объектов (обработка, отчет, документ). Тогда более правильнее было бы использовать вариант «золотой середины» — кэшировать соединение во временном хранилище в рамках каждого отдельного сеанса, которому это соединение необходимо. Этот вариант действительно подходит для большинства возникающих подобных задач. Небольшой пример его использования продемонстрирован в статье «Поддержка COM-соединения. Часть №3. Золотая середина».

 

Заключение

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

Надеюсь, что статья поможет Вам найти решение по оптимизации работы COM-соединения и совершенствовании интеграции на Вашем предприятии.

 

33 Comments

  1. Sergoninfostarru

    COM-соединение хорошо использовать при пакетных задачах : перетяжка справочников, документов, остатков и т.д., когда за ОДНО соединение вытягивается максимум информации. В случае постоянного «дёргания» данных из другой БД, скорость значительно снижается. В примерах показан простой вариант, а когда дело доходит до документов, то скорость резко падает.

    Reply
  2. YPermitin

    (1) Sergoninfostarru, возможно Вы правы.

    При решении реальной задачи с помощь COM-соединение передаю двоичные данные. Работает быстро. Единственным узким местом была скорость установки соединения. Вот ее и решили.

    А почему для документов скорость медленная?

    Reply
  3. gaglo

    Разве нельзя вместо временного хранилища использовать переменную в модуле приложения? Как раз и получится сохранение в рамках отдельного сеанса.

    Reply
  4. YPermitin

    (3) gaglo, фактически это будет тоже самое, что и хранить в переменной модуля формы.

    Да, в рамках сеанса, но на стороне клиента. А последнее отрицательно влияет на стабильность. Мало ли какая у клиента линия связи, а COM-соединение такого ой как не любит =)

    К тому же тогда необходимо регистрировать COM-объект соединения на клиентской машине.

    А временное хранилище сохранит его на стороне сервера.

    Reply
  5. a.p.soft

    Уважаемые, скажите пожалуйста, а предваряющее обработку чтение всего XLS-файла (точнее всех нужных ячеек, во всех строках) — может считаться кешированием COM-соединения, о котором идет речь в статье? В принципе, учитывая возможные практические проблемы я пришел именно к такому способу работы с COM объектами. Реально, это ускоряет скорость работы обработки в несколько раз. Т.е сначала одним циклом всё считывается в массив, а уже потом обработка «пережёвывает» все данные.

    Reply
  6. YPermitin

    (5) a.p.soft, немного не по теме вопрос. В статье идет речь о кэширования COM-объекта соединения, который используется для связи между собой разных баз или для связи с базой 1С:Предприятия из других программ.

    Вот подробнее: http://v8.1c.ru/overview/IntegrationCOM.htm

    Вы же говорите о кэшировании любого COM-объекта, в частотности для чтения XLS. В принципе описанный подход тоже подойдет, проблем с этим не вижу. Обратите внимание на первые два способа. Думаю последний с веб-сервером будет излишним, чтобы прочитать файл XLS =)

    Reply
  7. seermak

    Все хорошо, но: на платформе 8.3 (хоть в совместимости хоть нет) в процедуре СохранитьСоединение(Соединение) в строке ПараметрыСеанса.АдресCOMСоединения = ПоместитьВоВременноеХранилище(Соединение, Новый УникальныйИдентификатор); = рушится с ошибкой «Переданное значение не может быть помещено во временное хранилище». Можно это как-то пояснить или подсказать (если кто знает)

    PS в 8.2 проблем нет

    Reply
  8. YPermitin

    (7) seermak, интересная информация.

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

    В платформе 8.2 не смотря на это можно было сохранить соединение во временное хранилище. Так сказать, недокументированные возможности платформы.

    Ну а в версии 8.3 видимо это дело прикрыли.

    Reply
  9. seermak

    Да и еще — если платформа установлена в каталог с русскими буквами — соединения по СОМ невозможны (Проверено на себе (с)seermak)

    Reply
  10. YPermitin

    (9) seermak, странный баг.

    А зачем использовали каталог с русскими буквами для этого?

    Reply
  11. gaglo

    (4) Ну во-первых, не совсем «то же самое», а именно в рамках сеанса, а не на время жизни открытой формы; во-вторых, если все происходит в локальной сети предприятия, то на клиенте или на сервере хранить — безразлично, в-третьих, приходится еще раз пожалеть, что в рубрикации на сайте нет разделений вроде «управляемые / обычные формы / WEB-приложения» (но это не к автору ;-])

    Кстати, для меня не явилось очевидным, что по третьему способу и регистрация COM-соединения проходит на стороне сервера…

    Reply
  12. YPermitin

    (11) gaglo, качество локальной сети тоже бывает разной.

    В третьем способе нет очевидности =) К кэшированному соединению на веб-сервере можно обращаться как с клиентской, так и с серверной стороны. Все зависит от прав доступа.

    Reply
  13. petrov_al

    А почему не используете внешние источники данных?

    Reply
  14. YPermitin

    (13) petrov_al, они могут использоваться только для чтения данных. Для модификации, увы, не получится использовать в отличии от предложенного варианта.

    Reply
  15. gaglo

    (12)

    качество локальной сети тоже бывает разной

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

    в сокращении:

    — Гиви, вот представь, пошел ты в лес, а навстречу тебе медведь. Что будешь делать?



    — Ну на дерево залезу.

    — А нету дерева.

    — Как нету дерева?? Это ведь лес!!

    — Ну вот такой лес!!



    За ответы спасибо. Вашу позицию я понял.

    Reply
  16. YPermitin

    (15) gaglo, может для Вас это и анекдот, но когда сталкиваешься с этим на практике, то становится не до шуток.

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

    А если в локалке 10 юзеров, то смысла кэшировать соединение вообще нету)

    Reply
  17. gaglo

    (16)

    200 пользователей, из них у части скорость в локальной сети не блещет стабильностью

    …имеет смысл задумываться о построении сети, а не пытаться исправить чужие огрехи???

    Да, для меня это анекдот… У нас 120 пользователей одновременно. Три больших здания. Сеть проводная плюс WiFi-сегмент. Скорость стабильна. Две работающих системы. COM-соединения присутствуют. Кэшируются в переменной модуля приложения. Пока работает стабильно.

    Я же сказал «Вашу позицию я понял». Спасибо!

    Reply
  18. aspirator23

    Любопытные варианты. Сам использую, но пока только вариант номер 2.

    Reply
  19. bulpi

    «Например, можно создать веб-сервис, который будет инициализировать соединение через COM-объект при первом обращении.»

    Автор, уж извините за неграмотность, но если Вы уже используете веб-сервер, зачем Вам вообще com-соединение? Ну наваяйте в 1с свой веб-сервис с нужными методами и разом избавитесь от всех проблем с com-соединением.

    Reply
  20. YPermitin

    (19) bulpi, веб-сервис, «наваяеный» в 1С будет использовать клиентские лицензии для каждого подключенного сеанса. Если же мы будем кэшировать COM-соединение на веб-сервере и обращаться через него, то лицензия всегда будет использоваться одна. В этом главное отличие.

    Reply
  21. galich

    Самый примитивный вариант хранения созданного COM-объекта:

    Создаем общий клиентский модуль, устанавливаем Повторное использование возвращаемых значений «На время сеанса», создаем функцию, типа этой:

    Функция ПолучитьСоединениеСБД(СтрокаПодключения) Экспорт

    COM = Новый COMОбъект(«V82c.Application»);

    COM.Connect(СтрокаПодключения);

    COM.Visible = Ложь;

    Возврат COM;

    КонецФункции

    И каждый раз, когда нужен COM, обращаемся к ней. Если нужно убить COM — делаем ОбновитьПовторноИспользуемыеЗначения(). Не забываем вызвать эту функцию перед завершением работы системы, а то отладка не будет отпускать сервер. ПРОФИТ 🙂

    Reply
  22. ZLENKO

    (21) galich, для регламентного задания такой способ подойдет ? В смысле для хранения COM объекта в интервалах между выполнением регламентного задания на сервере ?

    Reply
  23. galich

    К сожалению, нет. Разные запуски регламентных заданий в разных сессиях запускаются.

    Кроме того, регламентные задания запускаются на стороне сервера, а не клиента.

    Reply
  24. YPermitin

    (22) ZLENKO.PRO, можно, но только способом, где COM-объект кэшируется на веб-сервере. Тогда его использовать можно из любого сеанса.

    Reply
  25. YanTsys

    (15) gaglo, это тот где «- я не понял ты чей друг, мой друг, или медведя друг?»

    Reply
  26. gaglo

    (26) Ага.

    Reply
  27. Serginio

    Еще один вариант это использование статического поля класса .Net. Так как после загрузки Dll она не выгружается, то и статические поля будут содержать значения пока не выгрузится рабочий процесс

    Reply
  28. =Kollega=

    В свое время решал подобную задачу. Проблема была в том, что пользователям время от времени приходилось соединяться с одной базой, для поиска инфы. Кеширования на стороне клиента с одной стороны хорошо, но со стороны лицензий плохо — постоянно не хватало. С другой стороны web-сервера собственного тоже не было, пришлось копать в другую сторону. На Delphi написал собственный простой com-сервер и зарегистрировал его на сервере, где сама 1с-ка крутится. При первом обращении к нему, система его автоматически запускала и он инициировал соединение с удаленной базой. В дальнейшем он просто крутился в памяти сервера, поддерживая com-соединение с базой.

    По сути получалось, что ждет только 1-й пользователь, пока установится соединение, остальные получали уже готовое соединение.

    Reply
  29. intehof

    (29) Если возможно, поделитесь исходниками пожалуйста…

    Reply
  30. GreenDragon

    (20) Используйте http-сервисы. Лицензия используется только на время соединения. Как правило, это время при адекватной передаче данных, меньше секунды. По-факту, время необходимое от получения пакета данных вэб-сервером до отправки ответа отправителю. Обрабатывать полученные данные вы можете дальше на сервере без потребления какой-либо клиентской лицензии.

    Ваш метод:

    1. Не кросплатформенный.

    2. Отдельное шаманство в случае нескольких установленных платформ — к примеру, несколько версий 8.3

    3. Ресурсоёмкость — по факту запускается полный экземпляр приложения.

    4. Нестабильность com — на своём опыте познали прелесть подвисающих com-подключений

    5. Лицензия потребляется на время жизни com-объекта.

    Да и зачем вот это всё, если у вас же публикация: https://infostart.ru/public/427026/ ?

    Reply
  31. YPermitin

    (31) посмотрите на даты публикации. Уже сколько времени прошло, были ли тогда нормальные HTTP-сервисы 🙂

    Reply
  32. GreenDragon

    (32) *Стыдливо удаляюсь в кусты, пытаясь оттереть со лба печать «некропостер»*

    Reply
  33. YPermitin

    (33) =D

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *