В процессе эксплуатации клиент-серверных баз 1С на платформе 8.3 (особенно версий 8.3.9–8.3.12) многие разработчики сталкиваются с крайне неприятной проблемой: после некоторого времени стабильной работы HTTP-сервисы или интерфейс OData начинают возвращать ошибку «Session request timeout expired» (или «Истекло время ожидания сеанса»). Проблема осложняется тем, что удаление сеансов через консоль кластера 1С не приносит результата, и единственным временным спасением остается перезапуск службы 1C:Enterprise 8.3 Server Agent. В этой статье мы подробно разберем, почему это происходит, и как настроить систему для стабильной работы.
Давайте проанализируем ситуацию. Начиная с версии платформы 8.3.9, компания 1С внедрила механизм Session Pooling (пул сеансов) для веб-сервисов. Основная цель этого нововведения — повысить производительность за счет исключения затрат времени на авторизацию пользователя и инициализацию параметров сеанса при каждом чих-запросе. За управление этим механизмом отвечает параметр reuseSessions в файле публикации .vrd.
Рассмотрим, как это работает в теории: когда запрос приходит на IIS или Apache, модуль расширения 1С проверяет наличие свободного «спящего» сеанса в пуле. Если такой сеанс есть, он подхватывает запрос, выполняет код и возвращается в пул. Если сеанса нет — создается новый.
Однако на практике в версиях 8.3.10 и при использовании режима совместимости с 8.2 этот механизм работает некорректно. Происходит «залипание» сеансов: система считает, что сеанс занят обработкой, хотя фактически он бездействует. В итоге новые запросы выстраиваются в очередь, ждут освобождения сеанса из пула и, не дождавшись, выдают ошибку таймаута.
Если ваша конфигурация работает в режиме совместимости или вы используете платформу ниже 8.3.12, самым эффективным решением будет полный отказ от автоматического использования пула сеансов. Разберем по шагам, как это сделать:
C:\inetpub\wwwroot\).default.vrd и откроем его любым текстовым редактором.reuseSessions с "autouse" на "dontuse".Пример того, как должен выглядеть блок в файле .vrd:
<httpServices publishByDefault="false">
<service name="MyService"
rootUrl="my_service"
enable="true"
reuseSessions="dontuse"/>
</httpServices>
Установка reuseSessions="dontuse" заставляет платформу создавать новый сеанс для каждого входящего запроса и завершать его сразу после отправки ответа. Это увеличивает нагрузку на сервер (время на авторизацию), но полностью устраняет проблему «мертвых» сеансов и таймаутов.
Если нагрузка на ваш сервис очень велика и создание сеанса на каждый запрос обходится слишком «дорого» для процессора, попробуем оставить reuseSessions="autouse", но скорректировать параметры самого пула. Для этого в файле .vrd внутри тега point (или zone) добавим описание пула сеансов.
Проанализируем следующие атрибуты:
poolSize — максимальное количество сеансов в пуле. Если запросов много, стандартного значения может не хватать.poolTimeout — время ожидания (в секундах) свободного сеанса из пула. Если за это время сеанс не освободится, пользователь получит ошибку таймаута.sessionMaxAge — время жизни сеанса в пуле. Установка небольшого значения (например, 300 секунд) поможет принудительно обновлять сеансы, не давая им «зависать» вечно.Пример настройки пула:
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
base="/MyBase"
ib="Srvr=ServerName;Ref=BaseName;">
<sessionPool size="20" timeout="60" maxAge="300"/>
<httpService name="MyService" rootUrl="v1" reuseSessions="autouse"/>
</point>
Часто нестабильность HTTP-сервисов 1С связана с тем, что в настройках IIS (Internet Information Services) включено использование нескольких рабочих процессов для одного пула приложений. В терминологии IIS это называется Web Garden.
Выясним причину конфликта: каждый рабочий процесс IIS создает свой собственный экземпляр модуля расширения 1С, и каждый из них пытается управлять своим пулом сеансов. Это часто приводит к коллизиям и блокировкам на уровне серверных вызовов.
Для исправления выполним следующие действия:
Важно: Для работы 1С через веб-сервер это значение всегда должно быть равно единице, если только вы не используете специфические сценарии балансировки.
Рассмотрим еще один важный аспект. При использовании reuseSessions="autouse" сеанс не завершается. Это означает, что все глобальные переменные, объявленные в Модуле сеанса или Глобальном модуле, сохраняют свои значения между запросами. Если в коде вашего HTTP-сервиса используются тяжелые массивы, таблицы значений или структуры, которые не очищаются в конце выполнения запроса, объем памяти, занимаемый процессом rphost, будет постоянно расти.
В режиме совместимости с 8.2 механизмы сборки мусора могут работать не так эффективно, как в новых версиях. Мы рекомендуем в конце каждого метода HTTP-сервиса явно очищать созданные объекты:
Функция МойМетодГЕТ(Запрос)
// Какой-то код обработки
Результат = Новый Структура;
// Выполняем логику
// ...
// Перед возвратом ответа очищаем тяжелые объекты
ТяжелаяТаблица.Очистить();
Ответ = Новый HTTPСервисОтвет(200);
Ответ.УстановитьТелоИзСтроки(СформироватьJSON(Результат));
Возврат Ответ;
КонецФункции
Для стабильной работы HTTP/REST интерфейсов на платформе 1С 8.3.10 в клиент-серверном варианте мы рекомендуем следующую стратегию:
reuseSessions="dontuse". Это самый надежный способ забыть об ошибках таймаута.autouse, обязательно настройте sessionMaxAge в файле .vrd, чтобы сеансы принудительно пересоздавались раз в несколько минут.Соблюдение этих правил позволит вашим интеграциям работать бесперебойно, исключая необходимость ежедневного перезапуска серверов.