Проблема зависших или «фантомных» сеансов — одна из самых распространенных и неприятных задач, с которыми сталкиваются администраторы и разработчики 1С, особенно на платформе версии 8.3.12. Суть проблемы заключается в том, что пользователи уже закрыли программу или отключились от сети, но их сеансы продолжают отображаться в консоли администрирования кластера, занимая лицензии и потребляя ресурсы сервера. В этой статье мы подробно разберем, как автоматизировать очистку таких сеансов и какие настройки сервера помогут минимизировать их появление.
Прежде чем переходить к радикальным мерам, давайте разберем, почему сеансы остаются активными. Основными факторами являются:
Terminate hibernated session по каким-то причинам его не завершает.Keep-Alive на уровне операционной системы приводит к тому, что серверные сокеты остаются открытыми бесконечно долго.Рассмотрим наиболее эффективный метод — создание самописного регламентного задания, которое будет запускаться по расписанию (например, ночью) и принудительно завершать все активные сеансы, кроме административных. Этот метод особенно полезен, когда штатные средства кластера не справляются.
Для реализации этого метода нам потребуется использовать средства администрирования 1С. Поскольку на Linux-серверах использование COM-объектов невозможно, мы будем ориентироваться на универсальный механизм RAS (Remote Administration Server).
Проанализируем программный код процедуры, которая выполняет очистку сеансов:
Процедура УдалениеСеансовВНазначенноеВремя() Экспорт
// Инициализируем параметры подключения к кластеру
пАдресСервераАдминистрирования = "localhost"; // Адрес, где запущен ras
пПортСервераАдминистрирования = "1545"; // Стандартный порт RAS
пИмяИнформационнойБазыВКластере = "WorkBase";
пИмяАдминистратораКластера = "Admin";
пПарольАдминистратораКластера = "P@ssw0rd";
// Определяем типы клиентских приложений, которые подлежат отключению
КлиентскиеПриложения = Новый Массив;
КлиентскиеПриложения.Добавить(ВРег("1CV8")); // Толстый клиент
КлиентскиеПриложения.Добавить(ВРег("1CV8C")); // Тонкий клиент
КлиентскиеПриложения.Добавить(ВРег("WebClient")); // Web-клиент
// Получаем текущие сеансы информационной базы
СеансыИнформационнойБазы = ПолучитьСеансыИнформационнойБазы();
НомераСеансов = Новый Массив;
Для Каждого СеансИБ Из СеансыИнформационнойБазы Цикл
// Проверяем, относится ли сеанс к пользовательским приложениям
Если КлиентскиеПриложения.Найти(ВРег(СеансИБ.ИмяПриложения)) <> Неопределено Тогда
// Исключаем из списка на удаление текущего администратора, под которым работает задание
Если СеансИБ.Пользователь.Имя <> "Admin" Тогда
НомераСеансов.Добавить(СеансИБ.НомерСеанса);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если НомераСеансов.Количество() > 0 Тогда
// Настраиваем параметры администрирования для RAS
ПараметрыАдминистрирования = Новый Структура();
ПараметрыАдминистрирования.Вставить("ТипПодключения", "RAS");
ПараметрыАдминистрирования.Вставить("АдресСервераАдминистрирования", пАдресСервераАдминистрирования);
ПараметрыАдминистрирования.Вставить("ПортСервераАдминистрирования", Число(пПортСервераАдминистрирования));
ПараметрыАдминистрирования.Вставить("ПортКластера", 1541);
ПараметрыАдминистрирования.Вставить("ИмяАдминистратораКластера", пИмяАдминистратораКластера);
ПараметрыАдминистрирования.Вставить("ПарольАдминистратораКластера", пПарольАдминистратораКластера);
// Описываем параметры ИБ
ПараметрыАдминистрированияИБ = АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера();
ПараметрыАдминистрированияИБ.ИмяВКластере = пИмяИнформационнойБазыВКластере;
// Формируем фильтр по номерам сеансов
СтруктураСеанса = Новый Структура("Свойство, ВидСравнения, Значение", "Номер", ВидСравнения.ВСписке, НомераСеансов);
Фильтр = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(СтруктураСеанса);
// Вызываем штатную функцию удаления
АдминистрированиеКластераКлиентСервер.УдалитьСеансыИнформационнойБазы(ПараметрыАдминистрирования, ПараметрыАдминистрированияИБ, Фильтр);
ЗаписьЖурналаРегистрации("ОчисткаСеансов", УровеньЖурналаРегистрации.Информация, , , "Удалено сеансов: " + НомераСеансов.Количество());
КонецЕсли;
КонецПроцедуры
Разберем важные моменты этого кода. Во-первых, мы используем массив КлиентскиеПриложения, чтобы случайно не завершить работу системных процессов, таких как BackgroundJob (фоновые задания) или Designer (Конфигуратор). Во-вторых, крайне важно корректно настроить службу ras на сервере, так как именно она является «прослойкой» между кодом 1С и кластером.
Если программная очистка кажется вам слишком радикальной, давайте выясним причину задержки завершения сеансов в настройках самого кластера. Откройте консоль администрирования и проанализируйте следующие параметры:
rphost помечается как выключаемый, и новые сеансы в него не заходят, а старые (в том числе зависшие) постепенно ликвидируются вместе с процессом.Если ваш сервер работает на Linux, проблема может крыться в сетевых тайм-аутах. Когда клиентское соединение обрывается без уведомления (например, при выключении ноутбука), Linux может держать TCP-соединение открытым до двух часов. Посмотрим, как это изменить.
Необходимо отредактировать файл /etc/sysctl.conf и добавить или изменить следующие параметры Keep-Alive:
net.ipv4.tcp_keepalive_time = 300 — уменьшаем время проверки активности соединения до 5 минут.net.ipv4.tcp_keepalive_intvl = 45 — интервал между повторными проверками, если первая не удалась.net.ipv4.tcp_keepalive_probes = 5 — количество неудачных проверок перед закрытием сокета.После внесения изменений выполните команду sysctl -p для применения настроек. Это заставит операционную систему быстрее закрывать «мертвые» сетевые сеансы, что, в свою очередь, позволит серверу 1С корректно завершить связанные с ними сеансы пользователей.
При использовании веб-клиента (через Apache или IIS) зависание сеансов часто происходит на стороне веб-сервера. Проанализируем настройки файла default.vrd. Убедитесь, что параметр sessionMaxAge соответствует вашим ожиданиям по времени жизни сеанса.
Что касается PostgreSQL, то старые версии (например, 9.1, упомянутая в проблеме) не умеют автоматически сбрасывать «брошенные» транзакции. Если сеанс 1С завис внутри транзакции (статус idle in transaction в базе данных), он может блокировать таблицы и не давать серверу 1С завершить сеанс. В современных версиях Postgres (начиная с 9.6) рекомендуется настраивать параметр idle_in_transaction_session_timeout, который принудительно обрывает такие соединения на уровне СУБД.
Подведем итог: для стабильной работы платформы 8.3.12 рекомендуется комбинированный подход — настройка тайм-аутов в консоли кластера, оптимизация сетевых параметров ОС и внедрение регламентного задания для «ночной» очистки забытых сеансов. В долгосрочной перспективе оптимальным решением будет обновление платформы до более стабильных релизов (например, ветки 8.3.18 или 8.3.22), где многие из описанных проблем решены на уровне ядра.