При разработке высоконагруженных систем на базе 1С, активно взаимодействующих с внешними приложениями (Excel, Word, ADO, криптографические библиотеки), разработчики часто сталкиваются с необъяснимыми задержками. Типичная ситуация: код, который мгновенно отрабатывает на клиентском месте (в толстом клиенте), начинает «подвисать» при выполнении на сервере, особенно если вызовы идут через HTTP-сервисы или веб-клиент. В этом материале мы разберем причины возникновения таких очередей и научимся настраивать операционную систему для стабильной работы множества одновременных COM-сессий.
Рассмотрим классическую ситуацию: на сервере 1С развернута база, с которой работают пользователи через веб-интерфейс. Основная логика вынесена в HTTP-сервисы. В коде инициализируется COM-объект, например:
// Пример инициализации, на которой происходит зависание
Попытка
МойОбъект = Новый COMОбъект("ADODB.Connection");
// Или любой другой объект: Excel.Application, WinHttp.WinHttpRequest.5.1
Исключение
ЗаписьЖурналаРегистрации("Ошибка COM", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;
Проблема проявляется в том, что строка Новый COMОбъект выполняется недопустимо долго — от нескольких секунд до получаса. При этом ресурсы сервера (процессор, оперативная память) остаются практически свободными. Выясним причину: почему операционная система ставит создание объекта в очередь? Оказывается, корень проблемы кроется в архитектуре Windows Desktop Heap (куча рабочего стола).
Все службы Windows, включая агент сервера 1С (процессы rphost.exe), работают в так называемой «Сессии 0». Это неинтерактивная сессия, которая имеет свои жесткие ограничения на выделение системных ресурсов. Для каждого процесса в этой сессии операционная система выделяет область памяти под объекты пользовательского интерфейса и системные дескрипторы, даже если само приложение работает в фоновом режиме без графического окна.
Проанализируем ключевой параметр реестра, отвечающий за это ограничение. Он находится в ветке:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems
В этой ветке нас интересует строковый параметр Windows. В его значении содержится длинная строка, в которой есть фрагмент SharedSection=xxxx,yyyy,zzzz. Рассмотрим, что означают эти цифры:
Именно третье значение (чаще всего по умолчанию оно равно 512 или 768 КБ) является «бутылочным горлышком». Когда сервер 1С пытается создать множество COM-объектов, память в этой области заканчивается, и новые объекты ждут, пока старые освободят место. Чтобы решить проблему, необходимо увеличить это значение до 2048 или 4096 КБ.
Выполним следующие действия для устранения лимитов:
regedit.exe) от имени администратора.HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems.Windows.SharedSection=. Например, если там написано 1024,20480,768, изменим последнее число на 2048 или 4096.Если манипуляции с реестром не помогли полностью или если COM-объекты (например, Excel) часто «зависают» в памяти, проанализируем возможность выноса этих объектов в COM+ Applications. Это позволит запускать каждый объект в отдельном процессе dllhost.exe, изолируя его от рабочего процесса 1С.
Рассмотрим преимущества этого подхода:
rphost.exe.dllhost.exe, чем внутри одного огромного процесса 1С.Зачастую тормоза возникают именно при работе с Excel.Application или Word.Application. Проанализируем ситуацию: Microsoft официально не рекомендует использовать пакет Office на стороне сервера. Проблема в том, что эти приложения при запуске ищут папки профиля рабочего стола, которых у системной учетной записи может не быть.
Чтобы ускорить инициализацию офисных COM-объектов, проверим наличие следующих каталогов (и создадим их, если они отсутствуют):
C:\Windows\System32\config\systemprofile\DesktopC:\Windows\SysWOW64\config\systemprofile\Desktop (для 64-битных ОС)Наличие этих пустых папок часто магическим образом «оживляет» COM-инициализацию, так как Excel перестает ждать таймаута при попытке доступа к окружению рабочего стола.
Помимо системных настроек, обратим внимание на качество кода 1С. Основная проблема — утечки памяти из-за неявного удержания COM-объектов. Выясним, как правильно завершать работу с объектами.
Посмотрим на пример правильного цикла работы с внешним объектом:
Процедура ВыполнитьРаботуСCOM()
Попытка
Excel = Новый COMОбъект("Excel.Application");
// Выполняем действия
// ...
Исключение
Excel = Неопределено;
Возврат;
КонецПопытки;
// Обязательное явное завершение работы приложения
Excel.Quit();
// Обязательное обнуление переменной для срабатывания сборщика мусора
Excel = Неопределено;
КонецПроцедуры
Если не вызывать Quit() и не устанавливать переменную в Неопределено, процесс в диспетчере задач может висеть еще долгое время после завершения сеанса 1С, занимая те самые дескрипторы и память в Desktop Heap, о которых мы говорили ранее.
В современной разработке на 1С 8.3 рекомендуется постепенно уходить от использования COM в пользу более стабильных механизмов. Рассмотрим альтернативы:
WinHttpRequest через COM, используйте встроенный объект 1С HTTPСоединение. Он работает быстрее, стабильнее и не зависит от системной кучи рабочего стола.ЗапуститьПриложение(), передав параметры через командную строку или файл, и получить результат обратно. Это классический «Unix way», который на сервере работает гораздо предсказуемее.Подводя итог, можно сказать: если ваша система требует массового запуска COM-объектов, первым делом проверьте настройки SharedSection в реестре и убедитесь, что объекты корректно уничтожаются после завершения работы. Эти простые действия помогут избавиться от «фантомных» задержек и обеспечат стабильную работу ваших веб-сервисов.