Один рабочий процесс сервера приложений вырос с 7,22 до 12,72 гигабайта за одиннадцать суток. Ровно полгигабайта в сутки, темп держится линейно. Сбрасывается только перезагрузкой, потому что лимиты памяти в кластере не выставлены вообще.
Это первая из двух находок разбора, и обе оказались про память. Искали при этом процессор.
Вторая находка дешевле и обиднее: шесть мёртвых сеансов терминального сервера держат около десяти гигабайт круглосуточно, а лечится это одной настройкой политики, без единой строчки кода.
Но самое полезное здесь то, как мы чуть не ушли не туда: график честно показывал другое узкое место, и мы почти поверили.
Машина, на которой это происходит
Одна виртуальная машина: четыре ядра, 32 гигабайта памяти. На ней одновременно живут сервер терминалов, сервер приложений 1С 8.3.27, локальная СУБД PostgreSQL 18, толстые и тонкие клиенты, браузеры пользователей.
Совмещение спорное, но так сложилось. Важно следствие: при такой конфигурации процессор физически не может стать узким местом раньше памяти. Каждый пользовательский сеанс здесь стоит гигабайты и десятки мегагерц. Память кончится первой всегда.
Наблюдение - две недели, шаг метрик - пятнадцать секунд.
Гипотеза, которую пришлось отбросить
Начинали мы совсем с другого вывода, и он был красивый.
Первым делом посмотрели сводную таблицу суточных максимумов. Дисковая подсистема - 97-99 % каждый день, без исключений. Читается однозначно: диск постоянно упирается в потолок, не справляется, надо расширять. На этом месте обычно и заканчивают: вывод удобный, объясняет всё разом и упирается в бюджет.
Потом посчитали среднее. 4,24 %.
Разрыв в двадцать три раза - сам по себе диагноз: ресурс свободен, просто у него есть короткий пик, и именно пик попадает в максимум.
Дальше посчитали долю времени выше порога. За неделю наблюдений диск был выше 80 % в семи пятиминутных интервалах из 2016. Треть процента времени.
2016 - это неделя, нарезанная по пять минут. Семь интервалов на семь суток - ровно по одному на ночь: ночное окно резервного копирования, около шести минут по журналу.
Ни в какой потолок диск не упирается. Есть бэкап, который делает свою работу и в эти минуты занимает диск целиком, как и положено.
Практический вывод, и он стоит всей статьи. Суточный максимум - худшая из доступных метрик, чтобы судить о перегрузке. Он сообщает, что ресурс *однажды* был занят, и молчит о том, сколько времени. Правильный порядок чтения: сначала среднее, потом доля времени выше порога, и только потом максимум, уточнением к первым двум. Сам по себе он не значит почти ничего.
Та же ошибка в другую сторону
Метод врёт и в другую сторону.
Чтобы графики строились быстрее, ряд прореживали до пятиминутного шага: одно значение на интервал. На таком ряде свободное место на диске выглядело спокойно.
На сыром пятнадцатисекундном разрешении видно, что почти каждый день свободное место проваливается до 27-450 мегабайт. Это минимум по дням, и брать из такого диапазона надо нижнюю границу. 27 мегабайт свободного места - состояние, из которого база уже не пишется.
Механика простая: пятнадцатисекундное событие попадает в пятиминутную выборку примерно один раз из двадцати. Минимум по прореженному ряду минимумом только называется - по факту это случайное значение из интервала.
И вот главное. Одна и та же ошибка метода дала два противоположных ложных вывода из одних и тех же данных: «диск загружен постоянно» там, где он свободен, и «со свободным местом всё хорошо» там, где оно кончалось. Прежде чем спорить о выводах, спросите, на каком разрешении построен график и какая величина по нему считалась. Половина споров про производительность после этого вопроса просто заканчивается.
Находка первая: рабочий процесс растёт и не отдаёт
Рабочий процесс сервера приложений - один экземпляр. За одиннадцать суток его потребление выросло с 7,22 до 12,72 гигабайта, ровно полгигабайта в сутки.
Рост линейный, без ступеней и без плато, сброс только перезагрузкой сервиса.
Лимиты памяти рабочих процессов в кластере не выставлены ни одного. Встроенный механизм, который должен был это ограничить, просто выключен - свойства придётся заполнять с нуля.
Скажу сразу: полгигабайта в сутки - это симптом. Что именно не освобождается, мы не нашли. Лимиты и перезапуск - обвязка вокруг проблемы: она не даёт росту уронить сервер и ничего не лечит.
Что выставить в кластере
Механизм живёт в свойствах рабочего сервера в консоли администрирования кластера. Соседний случай, когда процесс вместо роста внезапно падает, лечится совсем другим: там нужны дампы и обращение в поддержку, разбор лежит отдельно. Рабочему процессу задаётся порог потребления и интервал превышения: когда процесс держится выше порога дольше интервала, кластер перестаёт отдавать ему новые соединения, дожидается завершения текущих и поднимает рядом новый процесс. Пользователь при удачном раскладе этого не замечает.
Смотреть надо на четыре свойства - отрабатывают они в разных ситуациях.
«Объём памяти рабочих процессов, до превышения которого сервер считается производительным» - мягкий порог, с которого начинается вежливый перезапуск. Считается от объёма машины: суммарный потолок процессов должен оставлять запас системе, СУБД и клиентам, если они на той же машине. При 32 гигабайтах и одном процессе порог заметно ниже двенадцати - там, где рост ещё не мешает соседям.
«Интервал превышения допустимого объёма памяти» - сколько секунд превышение терпится. Он нужен, чтобы не перезапускать процесс на разовом всплеске: тяжёлый отчёт имеет право съесть память на минуту и вернуть её. Отталкиваться стоит от темпа роста: при полугигабайте в сутки счёт идёт на часы, минутные интервалы тут ни к чему.
«Максимальный объём памяти рабочих процессов» - жёсткий потолок, аварийный стоп. В норме он срабатывать не должен, поэтому вплотную к мягкому порогу его не ставят: нужен зазор, в котором мягкий механизм успеет отработать.
«Безопасный расход памяти за один вызов» - лимит на один серверный вызов. Ловит запрос, который решил поднять в память полбазы; до постепенного роста ему дела нет. Выставить его всё равно стоит: без него один неудачный отчёт кладёт процесс вместе со всеми, кто в нём сидел.
Отдельно - число рабочих процессов. Один процесс на установку означает, что его перезапуск виден всем сразу; два и больше дают кластеру переселять соединения. Прямой настройки «сделать три» нет: новый процесс поднимается сам, когда упирается в «Количество информационных баз на процесс» или «Количество соединений на процесс». Каждый процесс сам стоит памяти, так что за плавность перезапусков платим гигабайтами.
Как поймать такой рост у себя
Отдельный инструмент не нужен: снимайте потребление процессов сервера раз в минуту чем угодно и храните месяц. Смотрите на наклон линии, текущее значение само по себе не говорит ничего. Выросла за неделю и ни разу не спустилась к исходной точке - та же история. Ступеньки вниз - память возвращается, это нормальная работа под нагрузкой.
Один нюанс. После перезагрузки сервиса ряд начинается с чистого места, и на графике за месяц с перезагрузками каждую неделю рост выглядит как безобидная пила. Наклон считайте внутри отрезка между перезагрузками. По всему окну он смажется до нуля.
Находка вторая: десять гигабайт за одну настройку
Отключённые сеансы терминального сервера не завершались никогда. Все три таймаута политики выставлены в ноль, а ноль здесь означает «бесконечно». Ошибка ровно на этом и держится: администратор видит нули и читает их как «ограничений нет».
Итог: шесть мёртвых сеансов держали 9-11,6 гигабайта круглосуточно. Полтора-два гигабайта на сеанс с толстым клиентом и открытым браузером - нормальная цена.
Это самое дешёвое исправление всего разбора: одна настройка политики возвращает треть памяти машины, в прикладном коде не меняется ничего.
Проверьте свои три таймаута - групповая политика, ограничения сеансов узла удалённых рабочих столов:
- ограничение по времени для отключённых сеансов - это про пользователя, который закрыл окно крестиком и ушёл;
- ограничение по времени для активных, но бездействующих сеансов - про открытую сессию, в которой никто ничего не делает;
- ограничение по времени для активных сеансов - самое агрессивное, его как раз стоит трогать осторожно.
Первые два - это память, лежащая мёртвой круглые сутки. Рядом отдельный параметр: завершать сеанс при достижении лимита или только отключать. «Отключать» вернёт сеанс в первую категорию, так что настраивать их надо парой.
Честная поправка к собственному объяснению
Теперь то, что обычно вырезают из таких статей.
В середине наблюдения был день с провалом производительности. Объяснение напрашивалось само: рабочий процесс держит 12,7 гигабайта, мёртвые сеансы держат ещё десять, вместе 22,7 из 32, свободного почти нет, отсюда и провал.
Объяснение красивое и арифметически неверное. Пик 12,72 гигабайта - это одиннадцатые сутки, а провал случился на пятые. На дату провала рост давал 7,22 плюс четыре дня по полгигабайта, то есть около 9,2 гигабайта. Вместе с сеансами получается 19,2 вместо 22,7 - на три с половиной гигабайта меньше.
И вот что из этого следует. Свободного по такому расчёту оставалось около 12,8 гигабайта, а фактически доступно было 3,15. Значит на дату провала ещё примерно девять с половиной гигабайт съело что-то третье - клиенты, браузеры или локальная СУБД, и в разборе это не закрыто.
Механизм в исходном объяснении был верный. Числа к нему взяли с конца периода и приложили к событию из середины. Ошибка типичная и незаметная: когда объяснение уже сложилось и всем понравилось, проверять его арифметику никто не идёт. Заметил я это только потому, что полез считать остаток свободной памяти для другой цели.
Косвенное подтверждение, что памяти действительно не хватало: выделено 33,49 гигабайта при 32 физических. При таком превышении подкачка обязана включиться, и в отчёте она зафиксирована. Чинить надо не её.
Что мешало разбору и стоит проверить заранее
Три вещи, каждая стоила времени.
Служба сбора метрик не поднимается после перезагрузки и умирает молча. Отложенный автозапуск не укладывается в тридцатисекундный тайм-аут менеджера служб, действия восстановления не заданы. Результат: дыры в рядах ровно там, где интереснее всего - сразу после перезагрузок.
Служба администрирования кластера не зарегистрирована, консольная утилита не отвечает, настройки приходится читать из файла кластера. Плюс ловушка в именах: одноимённые системные службы Windows к 1С отношения не имеют, а в списке служб выглядят так, будто всё на месте.
Мониторинга сеансов прикладной системы нет, правил оповещения ноль. Плюс исходящий трафик к сервису уведомлений с этой машины не проходит: даже настроенное правило ничего бы не доставило. Канал доставки проверяйте в тот же день, когда завели первое правило.
Чего в этом разборе нет
Причина роста памяти не найдена. Есть темп и линейность, нет ответа, что именно не освобождается. Лимиты только страхуют.
Нет измеренного «после» ни по одной из двух находок. Таймауты и лимиты - предложения на момент разбора, обещать результат в гигабайтах не могу.
Доля времени выше порога посчитана по неделе, а наблюдение шло две. На полном окне она вдвое меньше, то есть вывод «диск свободен» только крепнет, но само число к другому окну не применяйте.
Другие наши инструменты диагностики 1С:
- Чек-ап СУБД под 1С - на такой же совмещённой машине СУБД стоит рядом с сервером приложений и ест ту же память: 40 с лишним проверок с вердиктом, что настроено не так.
- Карта объёмов базы 1С - если следом за памятью кончается диск, начинать надо с того, из чего база вообще состоит.
Вопрос в зал. Полгигабайта в сутки на рабочий процесс - многие живут с таким и перезапускают по расписанию. Кто-нибудь докапывался до настоящей причины? Интересно, чем она обычно оказывается.
Вступайте в нашу телеграмм-группу Инфостарт