При организации обмена данными между устаревшей, но все еще популярной платформой 1С:Предприятие 7.7 и современными конфигурациями на платформе 1С:Предприятие 8.3 разработчики часто используют механизм OLE (Automation-сервер). Долгое время эта связка работала стабильно. Однако, начиная с релиза платформы 8.3.14 и выше, многие специалисты столкнулись с критической проблемой: после завершения сеанса обмена процесс 1cv8.exe (или 1cv8c.exe) перестает автоматически выгружаться из оперативной памяти сервера или рабочей станции. С каждым новым циклом обмена количество зависших процессов увеличивается, что неизбежно приводит к перерасходу системных ресурсов и полной остановке работы операционной системы.
В этой статье мы подробно проанализируем причины такого поведения системы, разберем быстрые «костыли» для временного решения проблемы и детально рассмотрим наиболее правильный, современный и производительный способ интеграции — переход на использование HTTP-сервисов с передачей данных в формате JSON.
Для начала выясним причину сбоя. В релизе платформы 8.3.14 фирма «1С» провела глубокую модернизацию внутренних механизмов. В частности, произошел переход с устаревшего движка отображения веб-контента Internet Explorer на современный движок Chromium (WebKit). При инициализации соединения через V83.Application запускается полноценное клиентское приложение. Вместе с ним стартует целый ряд скрытых фоновых потоков: службы рендеринга интерфейса, механизмы проверки обновлений, фоновые задания защиты лицензирования и компоненты взаимодействия с сервером Системы Взаимодействия.
При уничтожении COM-объекта в коде 1С 7.7 операционная система пытается выгрузить библиотеку и закрыть процесс. Однако из-за зависания одного из вспомогательных фоновых потоков (которые не успевают или не могут корректно завершить работу по требованию родительского процесса) основной процесс 1cv8.exe переходит в состояние «зомби» — он не выполняет никаких полезных действий, но продолжает занимать оперативную память и удерживать системные дескрипторы.
Рассмотрим по шагам все возможные варианты решения этой проблемы: от простых административных мер до архитектурной перестройки обмена.
---
Если вам необходимо восстановить работоспособность обмена «прямо сейчас», а времени на переписывание кода нет, можно применить временные обходные пути.
Шаг 1. Откат на платформу 8.3.13. Как показывает практика, на релизах линейки 8.3.13 и ниже проблема с зависанием отсутствует. Если используемые конфигурации 1С 8.3 (например, «Бухгалтерия предприятия 3.0» или «Зарплата и управление персоналом 3.1») технически позволяют работать на старой версии платформы, это временно решит проблему.
Шаг 2. Использование скриптов автоматического закрытия. Можно настроить принудительное завершение всех зависших процессов 1С после окончания транзакции обмена. Для этого в операционной системе Windows создается сценарий PowerShell, который запускается по расписанию через Планировщик задач либо вызывается непосредственно из кода 1С 7.7 после завершения обмена.
Пример команды для принудительного закрытия всех процессов тонкого и толстого клиентов, запущенных в режиме автоматизации:
Stop-Process -Name "1cv8" -Force
Недостаток метода: жесткое убийство процессов по имени может прервать сеансы реальных пользователей, работающих в данный момент в других базах 1С 8.3 на этом же сервере.
---
Чтобы избежать взаимного влияния процессов и обеспечить гарантированное освобождение памяти, мы можем вынести COM-соединение в отдельное изолированное приложение COM+ под управлением системного процесса dllhost.exe.
Проанализируем алгоритм настройки этой конфигурации:
dcomcnfg.exe в строке выполнения).1C_COM_Connector) и установите способ активации — «Серверное приложение».comcntr.dll, расположенной в каталоге bin установленной версии платформы 1С 8.3.После этой настройки при обращении из 1С 7.7 операционная система будет запускать процесс dllhost.exe. Если в течение 3 минут к нему не будет запросов, Windows автоматически уничтожит этот процесс вместе со всеми зависшими внутренними потоками 1С, полностью очистив оперативную память.
---
Зачастую разработчики в коде 1С 7.7 инициализируют подключение через полноценное приложение:
База83 = СоздатьОбъект("V83.Application");
Этот метод крайне расточителен. Он инициализирует графический интерфейс платформы, загружает лишние библиотеки и плагины. Гораздо эффективнее и стабильнее использовать внутрипроцессный COM-соединитель, который не создает отдельного видимого процесса 1cv8.exe, а работает в адресном пространстве вызывающей программы (или внутри процесса dllhost.exe при использовании COM+).
Рассмотрим пример кода на языке 1С 7.7 для работы через COM-соединитель:
// Создаем экземпляр легкого COM-коннектора
Попытка
V8Connector = СоздатьОбъект("V83.COMConnector");
Исключение
Предупреждение("Не удалось зарегистрировать V83.COMConnector на компьютере!");
Возврат;
КонецПопытки;
// Формируем строку подключения к базе данных
СтрокаПодключения = "File=""C:\1C_Bases\Accounting"";Usr=""ExchangeUser"";Pwd=""ExchangePassword"";";
// Пытаемся установить соединение
Попытка
База83 = V8Connector.Connect(СтрокаПодключения);
Исключение
Предупреждение("Ошибка авторизации или подключения к 1С 8.3: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// Выполняем экспортные методы конфигурации-приемника
// Например, создаем и записываем документ
НовыйДокумент = База83.Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();
// ... Заполнение реквизитов ...
НовыйДокумент.Записать();
// ВАЖНО: Принудительно очищаем ссылки в 1С 7.7 для освобождения памяти
База83 = 0;
V8Connector = 0;
При использовании V83.COMConnector память высвобождается значительно быстрее и корректнее. Тем не менее, если даже этот метод дает сбои на вашей конфигурации, перейдем к самому надежному и современному ИТ-решению.
---
Использование COM-технологий (OLE) в современном мире считается устаревшим подходом. Оно жестко привязывает вас к операционной системе Windows, требует одинаковой разрядности операционных систем и программ (32-bit vs 64-bit), а также крайне чувствительно к обновлениям платформы. Лучшая альтернатива — перевести обмен на HTTP-сервисы.
Разберем по шагам, как настроить этот высокопроизводительный механизм.
В конфигураторе 1С 8.3 (это можно сделать через расширение конфигурации, чтобы не снимать основную базу с поддержки) создадим новый объект метаданных HTTP-сервисы:
ОбменСемеркаexchange/v1/send_dataЗаписатьДанныеИз77.В модуле HTTP-сервиса пишем код, который будет принимать данные в формате JSON, разбирать их и создавать нужные документы:
Функция ЗаписатьДанныеИз77(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
// Получаем тело запроса в виде строки JSON
СтрокаJSON = Запрос.ПолучитьТелоКакСтроку("UTF-8");
// Читаем JSON во временную структуру
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
Попытка
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
// Начинаем транзакцию для записи данных
НачатьТранзакцию();
// Пример обработки: создание документа "Поступление товаров и услуг"
НовыйДок = Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();
НовыйДок.Дата = ТекущаяДата();
НовыйДок.Контрагент = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", Данные.ИННКонтрагента);
// Заполняем остальные реквизиты и табличную часть из структуры "Данные"
НовыйДок.Записать(РежимЗаписиДокумента.Запись);
ЗафиксироватьТранзакцию();
// Формируем успешный ответ
Результат = Новый Структура;
Результат.Вставить("Success", Истина);
Результат.Вставить("Ref", Строка(НовыйДок.Ссылка.УникальныйИдентификатор()));
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, Результат);
Ответ.УстановитьТелоИзСтроки(ЗаписьJSON.Закрыть(), "UTF-8");
Исключение
ОтменитьТранзакцию();
// В случае ошибки возвращаем код 500 и описание проблемы
Ответ.КодСостояния = 500;
ОшибкаСтруктура = Новый Структура("Success, ErrorDescription", Ложь, ОписаниеОшибки());
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ОшибкаСтруктура);
Ответ.УстановитьТелоИзСтроки(ЗаписьJSON.Закрыть(), "UTF-8");
КонецПопытки;
Возврат Ответ;
КонецФункции
После написания кода опубликуйте базу данных 1С 8.3 на веб-сервере (например, IIS или Apache).
В платформе 1С 7.7 нет встроенных современных средств для работы с JSON и HTTP, но мы можем легко использовать стандартные системные COM-объекты Windows, такие как MSXML2.ServerXMLHttp. Они работают быстро, надежно и не оставляют никаких «висячих» процессов в памяти.
Посмотрим на пример кода отправки данных из обработки обмена в 1С 7.7:
Процедура ВыполнитьЭкспортНаВебСервис()
// Инициализируем HTTP-клиент
Попытка
HttpЗапрос = СоздатьОбъект("MSXML2.ServerXMLHttp");
Исключение
Предупреждение("На компьютере не установлен MSXML2.ServerXMLHttp! Обратитесь к администратору.");
Возврат;
КонецПопытки;
// Адрес опубликованного HTTP-сервиса базы 1С 8.3
АдресСервиса = "http://server-1c/AccountingBase/hs/exchange/v1/send_data";
// Формируем тело запроса в формате JSON вручную
// (для сложных структур можно использовать специализированные внешние компоненты)
ТелоЗапроса = "{";
ТелоЗапроса = ТелоЗапроса + """ИННКонтрагента"": ""7701020304"",";
ТелоЗапроса = ТелоЗапроса + """СуммаДокумента"": 154000.50,";
ТелоЗапроса = ТелоЗапроса + """Валюта"": ""RUB""";
ТелоЗапроса = ТелоЗапроса + "}";
// Открываем соединение (метод POST, асинхронный режим = Ложь)
HttpЗапрос.open("POST", АдресСервиса, 0);
// Устанавливаем заголовки авторизации и типа контента
HttpЗапрос.setRequestHeader("Content-Type", "application/json; charset=utf-8");
// Если на веб-сервере включена базовая авторизация, передаем логин и пароль
// HttpЗапрос.setRequestHeader("Authorization", "Basic " + КодироватьВBase64("Админ:Пароль"));
Сообщить("Отправка данных на веб-сервер...");
Попытка
HttpЗапрос.send(ТелоЗапроса);
Исключение
Сообщить("Ошибка отправки HTTP-запроса: " + ОписаниеОшибки(), "!");
Возврат;
КонецПопытки;
// Анализируем результат ответа сервера 1С 8.3
КодСтатуса = HttpЗапрос.status;
Если КодСтатуса = 200 Тогда
Сообщить("Данные успешно доставлены и обработаны!");
Сообщить("Ответ сервера: " + HttpЗапрос.responseText);
Иначе
Сообщить("Произошла ошибка при обработке данных на сервере!", "!");
Сообщить("Код ошибки HTTP: " + КодСтатуса, "!");
Сообщить("Текст ошибки: " + HttpЗапрос.responseText, "!");
КонецЕсли;
// Очищаем объект
HttpЗапрос = 0;
КонецПроцедуры
---
Выделим основные плюсы перехода от технологии OLE к HTTP-сервисам, которые вы заметите сразу после внедрения решения:
MSXML2.ServerXMLHttp, который корректно уничтожается операционной системой сразу после завершения вызова. На стороне 1С 8.3 запросы обрабатываются внутри стандартных рабочих процессов сервера (rphost.exe) без создания зависающих оконных клиентов.Таким образом, несмотря на то, что OLE-соединение долгое время служило надежным мостом для интеграции старых версий 1С с современными программными продуктами, современные реалии и особенности новых платформ 1С требуют перехода на веб-технологии. Настройка HTTP-сервисов позволит вам раз и навсегда забыть о мониторинге зависших процессов в диспетчере задач и обеспечит стабильную работу систем учета.