При построении сложных систем интеграции между несколькими информационными базами 1С разработчики часто используют COM-соединение. Однако при одновременном подключении из одной базы (например, базы интернет-магазина) сразу к нескольким внешним информационным базам служба сервера 1С (агент сервера ragent) может аварийно завершать свою работу. Проанализируем, почему возникает эта проблема и как правильно организовать работу с COM-соединениями.
Рассмотрим основные факторы, которые приводят к падению рабочего процесса rphost или службы агента сервера ragent при массовой инициализации COM-соединений:
rphost имеет ограничение по объему виртуальной памяти (около 2–3 ГБ). При одновременном открытии COM-соединений с крупными конфигурациями (такими как Управление производственным предприятием) в память процесса параллельно загружаются структуры метаданных и кэш сразу нескольких баз. Это приводит к резкому скачку потребления памяти и критической ошибке (Access Violation).comcntr.dll могут вступать в конфликт. При вызове объекта V81.COMConnector из контекста сервера 8.2 происходят сбои в общем адресном пространстве процесса.Наиболее эффективное и быстрое решение — отказаться от одновременного хранения внешних COM-соединений в памяти. Разберем по шагам правильный алгоритм работы с несколькими базами в цикле:
Посмотрим на пример реализации правильной последовательной обработки:
Для Каждого СтрокаБазы Из ТаблицаИсточников Цикл
// Формируем строку подключения для текущей базы
СтрокаПодключения = СформироватьСтрокуПодключения(СтрокаБазы);
Попытка
COMПодключение = Новый COMОбъект("V81.COMConnector");
Соединение = COMПодключение.Connect(СтрокаПодключения);
Исключение
ЗаписатьЗаписьРегистраРегистрации("Ошибка подключения к базе " + СтрокаБазы.Имя);
Продолжить;
КонецПопытки;
// Получаем данные и сворачиваем их в примитивные типы
ВыборкаДанных = Соединение.Документы.ЗаказПокупателя.Выбрать();
Пока ВыборкаДанных.Следующий() Цикл
// Обработка данных
КонецЦикла;
// ОБЯЗАТЕЛЬНО: обнуляем COM-объекты для освобождения памяти
Соединение = Неопределено;
COMПодключение = Неопределено;
// Вызываем принудительный сбор мусора при необходимости
ОчиститьПамять();
КонецЦикла;
Важно: Не сохраняйте ссылки на COM-объекты (выборки документов, строки таблиц базы-источника) в основных переменных вызывающей базы. Все полученные данные необходимо конвертировать в простые типы данных 1С (числа, строки, даты) или в локальные таблицы значений до закрытия соединения.
Чтобы обезопасить службу сервера 1С от падения при сбойных COM-соединениях, разберем настройку изолированного приложения в Windows:
Приложения COM+ и создайте новое приложение.V81.COMConnector (или соответствующий вашей платформе comcntr.dll).После этой настройки все COM-соединения будут исполняться во внешнем системном процессе dllhost.exe. Если при подключении произойдет утечка памяти или сбой, аварийно завершится только процесс dllhost.exe, а служба сервера 1С ragent продолжит штатную работу.
Проанализируем альтернативные архитектурные решения, которые полностью исключают использование нестабильных COM-компонентов:
WSПрокси. Вызовы выполняются по протоколу HTTP/HTTPS, сеансы быстро создаются и моментально завершаются, исключая падение агента сервера.Если служба сервера продолжает падать, настройте расследование через Технологический журнал. Добавьте в файл logcfg.xml отслеживание событий аварийного завершения процессов и ошибок работы с COM:
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="C:\LOGS\1C_Crash" history="24">
<event>
<eq property="Name" value="EXCP"/>
</event>
<event>
<eq property="Name" value="PROC"/>
</event>
<property name="All"/>
</log>
</config>
Событие EXCP зафиксирует точную причину аварийного завершения процесса (Access Violation, исчерпание памяти или сбой внешней библиотеки comcntr.dll), что позволит точно локализовать проблему.