При проведении регламентных работ в клиент-серверных базах 1С:Предприятие (будь то обновление конфигурации «Зарплата и управление персоналом», резервное копирование или оптимизация базы данных) администраторы часто сталкиваются с проблемой: пользователи оставляют программу открытой на ночь. Попытки завершить их работу программно через стандартные скрипты с использованием COM-соединения иногда заканчиваются неудачей — соединения вроде бы разрываются, но монопольный доступ получить всё равно не удается.
В этой статье мы подробно разберем, почему стандартный метод отключения соединений Disconnect может не работать, чем «сеансы» отличаются от «соединений», а также рассмотрим несколько надежных способов гарантированного отключения пользователей, включая готовые программные скрипты, механизмы БСП и современные консольные утилиты платформы 1С 8.3.
Для начала проанализируем ситуацию, с которой столкнулся автор темы. В его исходном коде использовался метод Disconnect, вызываемый для объекта рабочего процесса. Этот метод физически обрывает низкоуровневое сетевое соединение между клиентским приложением и сервером приложений 1С. Однако в современных версиях платформы 1С:Предприятие 8.3 логика работы с пользователями устроена сложнее и базируется на двух разных сущностях:
rphost.Когда вы используете метод Disconnect, вы лишь уничтожаете сетевой канал. При этом сам сеанс пользователя на сервере остается активным еще некоторое время (он переходит в так называемый «спящий» режим). Платформа держит этот сеанс открытым в надежде, что клиентское приложение восстановит связь после кратковременного сбоя сети. В результате лицензия остается занятой, транзакции не откатываются, а база данных продолжает считать пользователя активным, блокируя любые монопольные операции.
Выяснив причину, мы приходим к логичному решению: для принудительного выгона пользователей необходимо закрывать именно сеансы с помощью метода TerminateSession (или ЗавершитьСеанс).
Рассмотрим рабочий вариант скрипта, который перебирает все активные сеансы информационной базы на сервере 1С и принудительно закрывает их, игнорируя служебные соединения (например, консоль администрирования или сам сеанс выполнения скрипта).
Ниже представлен исправленный программный код, который вы можете использовать во внешней обработке или встроить в регламентное задание:
Процедура ПринудительноЗавершитьСеансы() Экспорт
// Задаем параметры подключения к кластеру сервера 1С
ИмяСервера = "BUH-APP"; // Имя или IP-адрес сервера 1С
ИмяБазы = "zup_31"; // Имя информационной базы на сервере
Порт = 1540; // Порт управляющего процесса (по умолчанию 1540)
Попытка
// Создаем COM-соединитель для управления сервером
КомКоннектор = Новый COMОбъект("V83.COMConnector");
// Подключаемся к агенту сервера
АгентКластера = КомКоннектор.ConnectAgent(ИмяСервера);
// Получаем массив кластеров сервера
Кластеры = АгентКластера.GetClusters();
// Будем использовать первый доступный кластер
РабочийКластер = Кластеры.GetValue(0);
// Проходим авторизацию в кластере (если заданы логин/пароль администратора кластера)
АгентКластера.Authenticate(РабочийКластер, "", "");
// Получаем рабочие процессы для выбранного кластера
РабочиеПроцессы = АгентКластера.GetWorkingProcesses(РабочийКластер);
Для Каждого Процесс Из РабочиеПроцессы Цикл
// Строим строку подключения к рабочему процессу
СтрокаСоединенияРП = Процесс.HostName + ":" + Формат(Процесс.MainPort, "ЧГ=");
// Подключаемся напрямую к конкретному рабочему процессу
СоединениеРП = КомКоннектор.ConnectWorkingProcess(СтрокаСоединенияРП);
// Авторизуемся в базе данных от имени администратора ИБ
СоединениеРП.AddAuthentication("АдминистраторБазы", "ПарольАдминистратора");
// Создаем описание нашей информационной базы
ОписаниеИБ = СоединениеРП.CreateInfoBaseInfo();
ОписаниеИБ.Name = ИмяБазы;
// Получаем список активных СЕАНСОВ (а не соединений!)
СписокСеансов = СоединениеРП.GetInfoBaseSessions(ОписаниеИБ);
Для Каждого ТекущийСеанс Из СписокСеансов Цикл
// Пропускаем служебные сеансы консоли кластера
Если ТекущийСеанс.AppID = "COMConsole" Тогда
Продолжить;
КонецЕсли;
// Пропускаем наш текущий сеанс, из-под которого запущен скрипт
Если Найти(ТекущийСеанс.userName, "АдминистраторБазы") > 0 Тогда
Продолжить;
КонецЕсли;
// Завершаем сеанс пользователя принудительно
Попытка
СоединениеРП.TerminateSession(ТекущийСеанс);
ЗаписьЖурналаРегистрации("Администрирование.ВыгонПользователей",
УровеньЖурналаРегистрации.Информация,,,,,
"Успешно завершен сеанс пользователя: " + ТекущийСеанс.userName);
Исключение
ЗаписьЖурналаРегистрации("Администрирование.ВыгонПользователей",
УровеньЖурналаРегистрации.Ошибка,,,,,
"Не удалось завершить сеанс пользователя " + ТекущийСеанс.userName + ". Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
КонецЦикла;
Сообщить("Процедура принудительного завершения сеансов успешно выполнена.");
Исключение
Сообщить("Критическая ошибка администрирования кластера: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Важное примечание: Чтобы этот код корректно отработал, на компьютере, где выполняется данный код, должна быть зарегистрирована библиотека comcntr.dll соответствующей разрядности (32 или 64 бита в зависимости от разрядности клиента/сервера 1С).
Если вы работаете в конфигурации 1С:ЗУП 3.1, вам совсем не обязательно писать код. В состав этой программы входит БСП (Библиотека Стандартных Подсистем), которая содержит мощный готовый функционал для выгона пользователей.
Разберем по шагам, как настроить блокировку сеансов через интерфейс программы:
Service2024). Данный код позволит вам зайти в базу во время активной блокировки для выполнения административных задач.После этого система автоматически разошлет предупреждения всем активным клиентам и по истечении указанного времени закроет их приложения. Чтобы зайти в заблокированную базу самому администратору, вам потребуется изменить параметры запуска ярлыка программы, добавив в строку запуска специальный ключ /UCКодРазблокировки. Например:
"C:\Program Files\1cv8\common\1cestart.exe" ENTERPRISE /S "BUH-APP\zup_31" /C"ИмяПользователя" /UC Service2024
Очень часто лицензии и сеансы расходуются впустую из-за пользователей, которые ушли на обед, совещание или домой, оставив программу открытой. Платформа 1С 8.3 позволяет настроить автоматический перевод таких сеансов в спящий режим с последующим удалением. Для этого выполним следующие действия:
1200 секунд (20 минут). Если пользователь не совершает никаких действий в течение этого времени, его сеанс «заснет», освободив лицензию 1С обратно в пул свободных лицензий.7200 секунд (2 часа). По истечении этого времени сервер 1С полностью удалит данный сеанс из списка активных.Если сервер 1С работает под управлением операционной системы Linux или использование технологии COM-объектов невозможно по соображениям безопасности и разрядности системы, на помощь приходит современная утилита администрирования RAC, поставляемая вместе с платформой 1С.
Для автоматизации выгона пользователей (например, перед выполнением ночного бэкапа базы средствами СУБД) мы можем написать простой командный файл (скрипт автоматизации). Выясним, как это работает на практике.
Предварительно на сервере должна быть запущена служба администрирования RAS (обычно она работает на порту 1545). Пример команды для создания пакетного bat-файла в Windows, который сбросит сеансы:
@echo off
set RAC_PATH="C:\Program Files\1cv8\8.3.23.1865\bin\rac.exe"
set SERVER=BUH-APP:1545
set CLUSTER_ID=00000000-0000-0000-0000-000000000000
set DB_NAME=zup_31
rem Шаг 1. Получаем список сеансов и завершаем их циклом через вызовы RAC
rem Для полной автоматизации рекомендуется написать парсер вывода rac на PowerShell или Python.
rem Простейший пример удаления одного конкретного зависшего сеанса по его ID:
%RAC_PATH% session --cluster=%CLUSTER_ID% terminate --session=1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d
echo Все сеансы обработаны.
pause
Использование утилиты RAC является наиболее предпочтительным и современным подходом для крупных корпоративных систем, так как данный метод полностью независим от архитектуры операционной системы и не требует регистрации нестабильных DLL-библиотек.
Иногда администраторы сталкиваются с аномальным поведением сервера 1С: сеанс пользователя отображается в консоли кластера, но попытка завершить его вручную или программно выдает ошибку, либо не приводит ни к какому результату. Такие сеансы называют «фантомными».
Это происходит из-за внутренних сбоев в работе процессов rphost.exe. Когда рабочий процесс перегружен или аварийно зависает, он перестает отвечать на внешние управляющие запросы менеджера кластера.
В такой ситуации у нас есть два пути решения:
rphost, а старый зависший процесс завершит.rphost.exe, который держит мертвую сессию (это можно определить по объему потребляемой памяти или ID процесса), и завершите его вручную (команда «Снять задачу»). Сервер 1С мгновенно запустит новый рабочий процесс взамен уничтоженного, при этом зависшие сеансы пропадут.Используя предложенные методики и понимая разницу между механизмами управления сеансами и соединениями, вы сможете легко автоматизировать рутинные процессы администрирования 1С:ЗУП 3.1 и всегда иметь монопольный доступ к базам данных в запланированное время.