Как решить проблему с зависшими сессиями пользователей в 1С:Предприятие 8.2?

Системный администратор IT и автоматизация бизнеса
← На главную

В процессе администрирования клиент-серверных баз данных на платформе 1С:Предприятие 8.2 (особенно при работе в связке с MS SQL Server и службами удаленных рабочих столов RDS) часто возникает неприятная ситуация: пользователи закрывают программу или отключаются от терминального сервера, но их сессии продолжают «висеть» в консоли администрирования 1С. Такие «зомби-сессии» не просто засоряют список активных пользователей, но и продолжают удерживать дефицитные клиентские лицензии (например, ключи защиты «Альфа-Авто» или программные лицензии 1С), блокируя работу других сотрудников.

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

Выясняем причины: почему сессии 1С зависают?

Прежде чем переходить к устранению проблемы, проанализируем ситуацию и выделим основные причины появления зависших сессий:

  1. Некорректное завершение терминальных сессий (RDP). Пользователи часто закрывают терминальное окно «крестиком» вместо штатного выхода из системы (Пуск -> Выход). При этом сессия на сервере переходит в состояние «Отключена» (Disconnected), но процессы внутри нее (включая клиентское приложение 1С) продолжают выполняться и удерживать лицензии.
  2. Зависание системных процессов печати. В 64-битных операционных системах Windows Server при печати документов из 32-битного клиента 1С запускается служба-посредник splwow64.exe. После закрытия 1С этот процесс продолжает работать в фоне и не дает операционной системе завершить терминальный сеанс пользователя.
  3. Сетевые микроразрывы. При нестабильном подключении (Wi-Fi, VPN) связь между клиентом и сервером 1С может оборваться без отправки пакета закрытия соединения. Сервер приложений считает сессию живой до истечения длительных системных таймаутов.

---

Решение 1. Программное отключение сессий через COM-соединение

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

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


СоединениеНомер = НомерСоединенияИнформационнойБазы; 
СоединениеПараметры = Инт_Строка.СтрокаСоответствие(СтрокаСоединенияИнформационнойБазы); 
СерверПортИмя = СоединениеПараметры.Получить("Srvr"); 
БазаИмя = НРег(СоединениеПараметры.Получить("Ref")); 

// Инициализируем COM-соединитель для платформы 8.2
Соединитель = Новый COMОбъект("V82.COMConnector"); 

РазделительПозиция = Найти(СерверПортИмя, ":"); 
Если РазделительПозиция > 0 Тогда 
    СерверИмя = Лев(СерверПортИмя, РазделительПозиция - 1); 
    СерверКластерПорт = Число(Сред(СерверПортИмя, РазделительПозиция + 1)); 
Иначе 
    СерверКластерПорт = Соединитель.RMngrPortDefault; 
КонецЕсли; 

СерверАгентИмя = СерверИмя; 
Если ЗначениеЗаполнено(Вход_СерверАгентПорт) Тогда 
    СерверАгентИмя = СерверАгентИмя + ":" + Инт_Строка.ЧислоСтрока(Вход_СерверАгентПорт); 
КонецЕсли; 

// Подключаемся к агенту сервера приложений
Агент = Соединитель.ConnectAgent(СерверАгентИмя); 
Кластеры = Агент.GetClusters(); 

Для Каждого Кластер Из Кластеры Цикл 
    Если Кластер.MainPort <> СерверКластерПорт Тогда 
        Продолжить; 
    КонецЕсли; 
    
    // Авторизуемся в кластере
    Агент.Authenticate(Кластер, Вход_КластерАдминистратор, Вход_КластерАдминистраторПароль); 
    Процессы = Агент.GetWorkingProcesses(Кластер); 
    
    Для Каждого Процесс Из Процессы Цикл 
        // Подключаемся к рабочему процессу
        КластерСоединение = Соединитель.ConnectWorkingProcess("tcp://" + СерверИмя + ":" + Инт_Строка.ЧислоСтрока(Процесс.MainPort)); 
        КластерСоединение.AddAuthentication(Вход_Администратор.ПользовательИмяИБ, Вход_АдминистраторПароль); 
        
        ИБОписание = КластерСоединение.CreateInfoBaseInfo(); 
        ИБОписание.Name = БазаИмя; 
        
        // Получаем список всех активных соединений
        Соединения = КластерСоединение.GetInfoBaseConnections(ИБОписание); 
        
        Для Каждого Соединение Из Соединения Цикл 
            // Отключаем все соединения, кроме текущего сеанса администратора
            Если Соединение.ConnId <> СоединениеНомер Тогда 
                КластерСоединение.Disconnect(Соединение); 
            КонецЕсли; 
        КонецЦикла; 
    КонецЦикла; 
КонецЦикла;

Важное примечание по авторизации: Если в вашей организации используется сквозная доменная (Active Directory) авторизация, при создании COM-соединения параметры имени пользователя и пароля на стороне клиента можно передавать пустыми. В этом случае 1С автоматически подтянет учетные данные текущей учетной записи Windows. Если же код выполняется на сервере (в фоновом задании), библиотека comcntr.dll будет использовать права служебной учетной записи, из-под которой запущен `rphost.exe` (например, USR1CV8). Для корректной работы в таком сценарии рекомендуется настроить библиотеку comcntr.dll как COM+ приложение в службах компонентов Windows с указанием выделенной доменной учетной записи администратора.

---

Решение 2. Очистка сессий, потерявших связь с рабочим процессом

Иногда в процессе эксплуатации серверов 1С возникает специфический сбой: сеансы пользователей теряют связь с рабочим процессом (rphost.exe), но продолжают числиться активными на уровне кластера. Посмотрим на пример кода, который находит и принудительно удаляет сессии, у которых рабочий процесс не определен:


Для Каждого Кластер Из Кластеры Цикл 
    Агент.Authenticate(Кластер, Вход_КластерАдминистратор, Вход_КластерАдминистраторПароль); 
    Сеансы = Агент.GetSessions(Кластер); 
    
    Для Каждого Сеанс Из Сеансы Цикл 
        // Проверяем, привязан ли сеанс к рабочему процессу
        Если Сеанс.process = Неопределено Тогда 
            // Принудительно завершаем зависшую сессию
            Агент.TerminateSession(Кластер, Сеанс); 
            Сообщить("Успешно удалена зависшая сессия пользователя: " + Сеанс.UserName); 
        КонецЕсли; 
    КонецЦикла; 
КонецЦикла;

Использование метода TerminateSession позволяет безопасно завершить логические сеансы на сервере 1С без необходимости перезапуска всей службы.

---

Решение 3. Настройка завершения процесса SplWOW64.exe на терминальном сервере

Если ваши пользователи работают в терминальном режиме (RDS) и сессии 1С «зависают» из-за того, что RDP-сеанс не закрывается до конца, причиной почти наверняка является системный процесс печати splwow64.exe. Настроим операционную систему Windows Server на автоматическое и быстрое завершение этого процесса при выходе пользователя из 1С.

Для этого выполним следующие шаги в системном реестре сервера:

  1. Откройте редактор реестра (нажмите Win + R, введите regedit и нажмите Enter).
  2. Перейдите к ветке реестра: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print.
  3. Найдите или создайте параметр с именем SplWOW64TimeOut (тип DWORD (32 бита)) и установите его значение равным 1. Это уменьшит таймаут ожидания закрытия процесса печати до минимума.
  4. Перейдите к ветке реестра: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\SysProcs.
  5. Создайте параметр с именем SPLWOW64.EXE (тип DWORD (32 бита)) и установите его значение равным 0. Данная настройка указывает операционной системе принудительно закрывать этот процесс при выходе пользователя из терминальной сессии.

После внесения изменений в реестр рекомендуется перезагрузить терминальный сервер для применения настроек.

---

Решение 4. Настройка групповых политик (GPO) для отключенных сессий

Чтобы исключить появление «мертвых душ» из-за некорректного закрытия окон RDP пользователями, настроим принудительное завершение отключенных сеансов на уровне операционной системы.

Разберем по шагам настройку локальной групповой политики на терминальном сервере:

  1. Запустите редактор политик через команду gpedit.msc.
  2. Перейдите по пути: Конфигурация компьютера -> Административные шаблоны -> Компоненты Windows -> Службы удаленных рабочих столов -> Узел сеансов удаленных рабочих столов -> Ограничение сеансов по времени.
  3. Найдите политику «Задать предел времени для отключенных сеансов».
  4. Переведите ее в состояние «Включено» и выберите период времени (например, 5 или 10 минут).

Теперь, если пользователь закроет терминал крестиком, система подождет 10 минут и полностью завершит его сеанс, автоматически закрыв зависшее приложение 1С и освободив используемую им лицензию.

---

Решение 5. Настройка системных таймаутов TCP (Keep-Alive)

Для борьбы с разрывами связи на уровне сетевых сокетов (когда клиент отключился физически, а сервер 1С продолжает ждать от него данных) мы можем настроить параметры TCP Keep-Alive в Windows Server. Это позволит серверу быстрее определять потерю связи с клиентом.

Для этого в реестре по пути HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters создадим два параметра типа DWORD:

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

← На главную