Зачем мониторить производительность серверов и с чего начать
Сервер с загрузкой CPU 35% может отвечать в три раза медленнее обычного, если узкое место находится в дисковой подсистеме: время уходит в iowait, а процессор ждёт завершения операций ввода-вывода. Отслеживать общую загрузку железа бессмысленно, нужны метрики четырёх подсистем по отдельности: CPU, памяти, дисковых операций и сети.
Короткий ответ на главный вопрос: снимите с каждого сервера 5-7 базовых метрик через node_exporter на Linux или windows_exporter на Windows, сложите их в Prometheus, постройте графики в Grafana и повесьте алерты на устойчивые отклонения, а не на короткие пики. Диагностику узкого места ведите по одной схеме: симптом, метрика, команда проверки, первопричина.
Дальше разберём метрики по подсистемам с конкретными порогами, инструменты сбора, готовые дашборды и правила алертинга, а затем четыре типовых сценария деградации с пошаговыми алгоритмами.
Какие задачи решает мониторинг производительности
- Раннее обнаружение проблем. Рост iowait с 2% до 20% за сутки виден на графике задолго до того, как приложение начнёт отдавать таймауты.
- Планирование мощностей. Тренд заполнения раздела или роста RSS показывает, когда понадобится новый узел, а не когда диск уже переполнен.
- Экономия ресурсов. Проверка показывает, что 40% памяти съедает кэш неиспользуемого сервиса, а два узла из десяти простаивают.
- Сокращение MTTR. История метрик позволяет за минуты увидеть, что изменилось, вместо часов перебора гипотез.
- Разбор инцидентов и отчётность. Постмортем опирается на цифры, а не на воспоминания участников.
Пример из практики: сервер отдавал ответы с задержкой 3-5 секунд при средней загрузке CPU 25%. Метрика %util диска держалась выше 95%, await превышал 60 мс. Причина обнаружилась в бэкапе, который писался в часы пиковой нагрузки. Один алерт на await закрыл бы задачу в день появления проблемы, а не через три недели жалоб пользователей.
Простой одного сервера в час обходится малому бизнесу в несколько тысяч рублей, сервису с онлайн-оплатой - в десятки тысяч. Узел мониторинга с Prometheus и Grafana потребляет 2-4 ГБ RAM и 2 vCPU, то есть стоит на порядок дешевле даже одного часа недоступности.
Минимальный жизнеспособный мониторинг: с чего начать
Стартовый набор из семи метрик покрывает большинство инцидентов на серверах без выделенной команды наблюдаемости:
- Загрузка CPU по режимам: user, system, iowait, steal.
- Память: used и available, отдельно активность swap.
- Свободное место на каждой файловой системе.
- Дисковые операции: IOPS, пропускная способность, await, %util.
- Сетевой трафик: байты и пакеты в секунду по интерфейсам.
- Load average и его отношение к числу ядер.
- Количество процессов и потоков, если приложение создаёт их динамически.
Порядок запуска: развернуть Prometheus, поставить node_exporter на Linux-серверы, windows_exporter на Windows-хосты, подключить Grafana к Prometheus как источник данных. Retention задайте сразу: 30 дней сырых данных и год агрегированных значений достаточно для разбора сезонных проблем. Алерты настройте в тот же день, что и сбор, иначе метрики превратятся в архив для посмертного анализа. Пошаговая установка с готовым дашбордом разобрана в руководстве по мониторингу Linux-сервера с Prometheus и Node Exporter.
Без baseline невозможно отличить норму от аномалии. Собирайте данные 2-4 недели, прежде чем фиксировать жёсткие пороги: у производственной нагрузки есть суточный и недельный ритм, и порог, выставленный в понедельник утром, будет ложно срабатывать в ночь на воскресенье.
Ключевые метрики производительности сервера
Метрики четырёх подсистем читаются вместе. Высокий iowait объясняет рост времени ответа при свободном CPU, а сетевые ретрансмиты объясняют задержки, которых нет ни в дисках, ни в процессоре.
Метрики CPU: загрузка, iowait, steal time
Ядро Linux отдаёт статистику по режимам в /proc/stat и в утилите top. Что означают режимы:
- user - время в пользовательских процессах. Рост означает вычислительную нагрузку приложения.
- system - время в ядре: системные вызовы, обработка прерываний, переключения контекста. Стабильные 20-30% system на файловом сервере нормальны, внезапный рост до 60% указывает на шторм syscalls или проблему с драйвером.
- idle - простой.
- iowait - ожидание завершения дисковых операций. Значение выше 10% на протяжении 10 минут означает, что процессор простаивает из-за диска, а не занят работой.
- steal - время, украденное гипервизором в пользу других виртуальных машин. Больше 5% - сигнал, что хостер перепродал ресурсы, и никакая оптимизация внутри гостя не поможет.
Load average показывает среднее число процессов в очереди на выполнение. Сравнивайте его с числом ядер: для 4 vCPU значение 8 означает устойчивую перегрузку, значение 4 - предельную загрузку без запаса. Проверка по ядрам: mpstat -P ALL 1, по процессам: top -o %CPU и pidstat -u 1.
Метрики памяти: used, available, swap
Ключевая разница: used включает страницы файлового кэша, которые ядро отдаст под приложение при первой необходимости, а available оценивает реально доступный объём. Ориентируйтесь на available, а не на used: сервер с 90% used и 4 ГБ available работает нормально, сервер с 60% used и 200 МБ available уже в опасности.
Что смотреть:
- swap in/out. Команда vmstat 1 выводит столбцы si и so. Устойчивые значения выше нуля означают, что рабочий набор не помещается в память, и каждый промах стоит дискового обращения.
- page faults. Рост major faults (столбец majflt, файл /proc/vmstat) означает подкачку с диска.
- OOM Killer. События видны в dmesg и в системном журнале: строка с out of memory: kill process. Ядро убивает процесс с наибольшим потреблением, и этим процессом легко окажется база данных.
Быстрая проверка: free -m, vmstat 1, cat /proc/meminfo. Для разбора по процессам: smem -t -k и pmap по конкретному PID.
Дисковые I/O: latency, IOPS, throughput
Диск ломает производительность незаметно: CPU свободен, память в норме, а сервис отвечает медленно. Расширенная статистика выводится командой iostat -x 1:
- tps - число операций ввода-вывода в секунду (IOPS).
- kB_read/s, kB_wrtn/s - пропускная способность.
- r_await, w_await - средняя задержка операций чтения и записи в миллисекундах, включая время в очереди.
- avgqu-sz - средняя длина очереди к устройству.
- %util - доля времени, когда устройство обрабатывало хотя бы одну операцию.
Практические пороги: await выше 20 мс для HDD и выше 5 мс для SATA SSD означает проблему, для NVMe тревожной считается задержка выше 2-3 мс. Метрика %util, близкая к 100%, не всегда говорит о насыщении: у быстрых NVMe с параллельной обработкой она может быть высокой при нормальной задержке. Решающий признак - одновременный рост await и avgqu-sz.
Механический диск выдаёт 80-140 МБ/с при последовательном чтении, но теряет скорость на произвольном доступе к блокам 4 КБ. База данных, генерирующая thousands random IOPS на HDD, гарантированно упрётся в задержку выше 50-100 мс.
Сетевые метрики: пропускная способность, ошибки, дропы
Сеть проверяется по счётчикам интерфейса и стеку TCP:
- rx/tx bytes и packets - объём трафика. Смотрите на тренд: плавный рост до 70% от пропускной способности интерфейса требует планирования апгрейда.
- errors и drops - ошибки драйвера, кабеля или переполнение буфера кольца приёмки. Любое устойчивое ненулевое значение требует разбора.
- TCP retransmits - повторные передачи. Доля выше 1% от общего числа сегментов замедляет любой сервис, даже при свободном канале.
- число established-соединений и listen backlog - переполнение очереди соединений даёт отказы в подключении при живом приложении.
Команды для быстрой проверки: ip -s link, netstat -s, ss -s, sar -n DEV 1, ss -ti для разбора задержек конкретного соединения. Подробный разбор метрик по всем подсистемам с командами и порогами приведён в материале о мониторинге производительности сервера: метрики CPU, памяти, диска и сети в Linux.
| Подсистема | Метрика | Тревожный порог | Команда проверки |
|---|---|---|---|
| CPU | iowait | больше 10% в течение 10 минут | top, mpstat 1 |
| CPU | steal | больше 5% | mpstat -P ALL 1 |
| CPU | load average | больше числа ядер в 1,5-2 раза | uptime, nproc |
| Память | available | меньше 10% от объёма RAM | free -m |
| Память | swap in/out | устойчиво больше нуля | vmstat 1 |
| Диск | await | больше 20 мс (HDD), 5 мс (SSD) | iostat -x 1 |
| Диск | место | меньше 10% свободно | df -h |
| Сеть | errors, drops | любое устойчивое значение | ip -s link |
| Сеть | TCP retransmits | больше 1% сегментов | netstat -s |
Инструменты сбора метрик: node_exporter, collectd, perfmon
Выбор инструмента определяется операционной системой и тем, куда нужно доставить данные. Для Linux-парка стандарт де-факто - node_exporter с Prometheus, для Windows - perfmon локально и windows_exporter для интеграции, для смешанных сред с отправкой в разные бэкенды сохраняет актуальность collectd.
node_exporter: установка и настройка на Linux
node_exporter распространяется одним бинарным файлом и не требует зависимостей. Порядок действий:
- Скачайте архив для своей архитектуры с официальной страницы релизов и распакуйте в /usr/local/bin.
- Создайте системного пользователя node_exporter без права входа в оболочку.
- Опишите systemd-юнит с ExecStart=/usr/local/bin/node_exporter и включите его через systemctl enable --now.
- Проверьте метрики локально: curl http://localhost:9100/metrics. В ответе будут строки node_cpu_seconds_total, node_memory_MemAvailable_bytes, node_disk_io_time_seconds_total, node_network_receive_bytes_total.
- Ограничьте доступ: порт 9100 открывайте только для сервера Prometheus, через firewall или security group. Экспортер не имеет аутентификации и раскрывает состав пакетов, версию ядра и параметры монтирования.
Собираемые метрики охватывают процессор, память, диски, файловые системы, сеть, systemd-юниты и загрузку. Для метрик ZFS и SMART нужны отдельные экспортеры, базовая статистика пулов в node_exporter не попадает.
collectd: гибкость и плагины
collectd уместен в трёх случаях: сбор метрик с сетевого оборудования и устройств без агента, отправка данных сразу в несколько бэкендов (Graphite, InfluxDB, Kafka), собственные плагины на C или Python для нестандартных источников. Минимальная конфигурация включает плагины cpu, memory, df, disk, interface и блок write_graphite или write_influxdb с адресом приёмника.
Слабые места: отсутствие нативной модели pull, из-за чего Prometheus подключается к collectd только через промежуточный экспортер, и более высокая сложность конфигурации. Для однородного парка Linux-серверов node_exporter проще и дешевле в поддержке.
perfmon и Windows Exporter для Windows-серверов
В Windows встроенный perfmon уже даёт нужные данные. Ключевые счётчики для базового контроля: Processor(_Total)\% Processor Time, System\Processor Queue Length, Memory\Available MBytes, Memory\Pages/sec, PhysicalDisk(_Total)\Avg. Disk sec/Transfer, PhysicalDisk(_Total)\Avg. Disk Queue Length, Network Interface(*)\Packets Received Errors.
Порог по Avg. Disk sec/Transfer: до 10 мс - норма, 10-25 мс - заметная задержка, выше 25 мс - диск не справляется. Длину очереди диска выше 2 на один физический шпиндель считайте перегрузкой.
Чтобы отдавать эти счётчики в Prometheus, ставят windows_exporter (MSI-пакет, порт 9182). Он публикует метрики windows_cpu_time_total, windows_memory_available_bytes, windows_logical_disk_free_bytes, windows_net_bytes_total. Дополнительно через WMI можно забирать состояние служб и логи Event Log для корреляции инцидентов с системными событиями.
Визуализация и алертинг в Grafana
Grafana закрывает две задачи: показать состояние инфраструктуры на одном экране и уведомить о выходе метрик за пределы нормы. Разворачивать её логично рядом с Prometheus, на отдельном узле, чтобы падение Production-серверов не уносило систему наблюдаемости. Для стенда мониторинга достаточно виртуального сервера с 2 vCPU и 4 ГБ RAM, например в Timeweb Cloud, где ресурсы можно увеличить при росте числа хостов.
Подключение Prometheus и импорт дашбордов
- В Grafana добавьте источник данных типа Prometheus и укажите URL сервера, например http://prometheus.internal:9090.
- Нажмите Save & test: Grafana должна получить сообщение о рабочем источнике.
- Импортируйте готовый дашборд по ID: 1860 (Node Exporter Full) для Linux, 14694 для windows_exporter.
- Задайте переменные дашборда: instance или job, чтобы переключаться между серверами без правки панелей.
Дальше добавляйте свои панели. Базовый запрос по загрузке CPU: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100). Загрузка диска по времени операций: rate(node_disk_io_time_seconds_total[5m]). Свободное место в процентах: node_filesystem_avail_bytes / node_filesystem_size_bytes * 100.
Настройка алертов: пороги и уведомления
Правила создаются в Grafana Alerting или в Prometheus Alertmanager. Примеры, которые ловят реальные инциденты и не шумят:
- Свободное место: node_filesystem_avail_bytes / node_filesystem_size_bytes < 0.1 в течение 10 минут, severity warning; меньше 0.05 - critical.
- Iowait: rate(node_cpu_seconds_total{mode="iowait"}[5m]) > 0.2 на протяжении 15 минут.
- Загрузка CPU: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90 в течение 10 минут.
- Диск: rate(node_disk_io_time_seconds_total[5m]) > 0.9 и одновременно рост await.
- Сеть: rate(node_network_receive_errs_total[5m]) > 0 или рост retransmits.
- Доступность: up == 0 в течение 2 минут.
Уведомления направляйте в Telegram, Slack и на почту дежурного, с маршрутизацией по severity: critical будит ночью, warning ждёт рабочего времени. Каждое критичное правило сопровождайте ссылкой на runbook с шагами диагностики, иначе алерт превращается в вопрос без ответа. Полезно добавить автоматическое краткое описание инцидента на естественном языке: агрегаторы доступа к моделям, например AiTunnel, позволяют подключить LLM через единый API и получать сводку по всплеску метрик в одном сообщении. Обязательно тестируйте алерты: остановите экспортер, заполните тестовый раздел, проверьте, что уведомление дошло до дежурного.
Анализ узких мест: типовые паттерны деградации и пошаговая диагностика
Четыре сценария закрывают большую часть обращений по производительности. В каждом важно разделить симптом и первопричину: высокая загрузка CPU может быть следствием диска, а медленная сеть - следствием нехватки памяти.
Высокая загрузка CPU: кто виноват?
- Смотрите top -o %CPU: найдите процесс-лидер и уровень system против user.
- Разложите нагрузку по ядрам: mpstat -P ALL 1. Перекос на одно ядро указывает на однопоточный код или привязку процессов.
- Проверьте iowait и steal в том же выводе. Высокий iowait переводит расследование в дисковую подсистему.
- Для коротких всплесков используйте pidstat -u 1 и perf top: они показывают функции, съедающие время.
- Если профиль нагрузки легитимный, рассматривайте оптимизацию запросов, кэширование или горизонтальное масштабирование.
Частый пример: MySQL потребляет 6 из 8 ядер на запросах с полным сканированием таблицы. Добавление индекса снимает нагрузку без замены железа.
Нехватка памяти и утечки
- Снимите free -m и vmstat 1: активность swap и majflt подтверждают нехватку.
- Сравните потребление по процессам: smem -t -k и pmap -x PID.
- Отследите динамику RSS за 30-60 минут: устойчивый рост при стабильной нагрузке означает утечку.
- Проверьте журнал на события OOM Killer: dmesg с фильтром out of memory.
- Действия: ограничить потребление через systemd MemoryMax, перезапустить сервис по расписанию как временную меру, искать утечку в коде.
Классический случай: Java-приложение с настройкой -Xmx, превышающей доступную память узла. Heap растёт до лимита, затем следует серия Full GC и падение по OOM. Решение - согласовать размер heap с RAM и вынести кэш из процесса.
Дисковые проблемы: latency и очередь
- Запустите iostat -x 1 и смотрите await, avgqu-sz и %util по каждому устройству.
- Найдите процессы, создающие нагрузку: iotop -o и pidstat -d 1.
- Определите тип операций: последовательные чтения большими блоками терпят HDD, произвольные 4 КБ - нет.
- Проверьте, нет ли конкуренции между бэкапом, репликацией и рабочим трафиком в одни часы.
- Решения: вынести журналы и данные на NVMe, разделить нагрузку по расписанию, добавить кэш на уровне приложения.
Показательный пример: база данных на HDD с произвольным доступом показывает await выше 100 мс и очередь 8-10 запросов. Перенос на NVMe снижает задержку в 20-30 раз при том же объёме данных.
Сетевые аномалии: потери и ретрансмиты
- Проверьте счётчики интерфейсов: ip -s link. Рост errors и drops говорит о кабеле, порту или драйвере.
- Оцените стек TCP: netstat -s и ss -s. Доля ретрансмитов выше 1% замедляет сервис.
- Разберите конкретное соединение: ss -ti показывает rtt, retrans и cwnd.
- При подозрении на потери между узлами снимите дамп: tcpdump -i eth0 -nn port 443.
- Причины по сторонам: переполнение буфера приёмки лечится тюнингом ring buffer, потери у провайдера решаются сменой маршрута, ошибки на порту - заменой кабеля или трансивера.
Общий принцип диагностики: подтвердите причину метрикой, проверьте её командой, устраните первопричину и зафиксируйте новое значение как baseline. Пошаговые методы поиска узких мест в CPU, памяти, хранилище, сети и приложении собраны в статье про то, как найти узкое место в системе и повысить производительность без лишних затрат.
Типичные ошибки при настройке мониторинга и как их избежать
- Отсутствие baseline. Пороги выставлены на глаз, алерты срабатывают на нормальные пики резервного копирования. Собирайте статистику 2-4 недели и учитывайте суточный профиль.
- Слишком высокие пороги. Алерт на CPU выше 95% срабатывает, когда сервис уже деградировал. Для веб-серверов полезнее правило на рост времени ответа p95, чем на загрузку процессора.
- Мониторинг без уведомлений. Красивые дашборды никто не открывает в 3 часа ночи. Правило без маршрута доставки не работает.
- Шумные алерты. Десятки срабатываний в сутки приводят к привыканию и отключению уведомлений. Объединяйте связанные правила, используйте группировку и задержку for 10m.
- Мало данных в истории. Retention в 3 дня не позволяет разобрать проблему, которая проявляется раз в неделю.
- Игнорирование трендов. Алерт на заполнение диска нужен не при 90%, а при прогнозе переполнения через 14 дней.
- Отсутствие проверки после изменений. После обновления или смены конфигурации метрики нужно сравнивать с baseline: подход описан в руководстве по мониторингу производительности после обновления.
- Мониторинг только серверов. Без проверки доступности сервисов извне вы узнаете о падении от пользователей, а не от системы.
Рекомендации, которые снижают число пропущенных инцидентов: пересматривайте правила раз в квартал, удаляйте те, что не срабатывали ни разу за полгода, и дополняйте те, после которых разбор показал недостаток данных. Хороший старт для построения корректных порогов даёт материал о том, как оценить производительность системы: ключевые метрики, методы и первые шаги.
Масштабирование мониторинга и поддержка актуальности
На 20-50 серверах один Prometheus справляется с запасом. Проблемы начинаются при росте до сотен хостов и тысяч series: растёт потребление памяти, замедляются запросы, а retention приходится сокращать.
Рабочие варианты масштабирования:
- Федерация Prometheus. Отдельные серверы собирают метрики по сегментам, центральный забирает агрегаты. Подходит, когда нужна изоляция между командами.
- Remote write и долгосрочное хранение. Thanos и VictoriaMetrics принимают поток данных и хранят метрики годами в объектном хранилище, экономя локальный диск.
- Service discovery. Автоматическое добавление целей через file_sd, Consul или API Kubernetes избавляет от ручного ведения списка серверов и убирает класс ошибок с забытым хостом.
- Обновление экспортеров. Держите версии node_exporter и windows_exporter в одном релизном окне с обновлением ОС: новые метрики и исправления поведения счётчиков появляются регулярно.
- Ревизия дашбордов. Раз в квартал удаляйте панели, которые никто не открывает, и дополняйте те, к которым обращаются во время инцидентов.
Отдельное направление - контроль самой системы мониторинга: следите за временем выполнения тяжёлых запросов, размером базы Prometheus и задержкой доставки алертов. Молчащая система наблюдаемости опаснее её отсутствия, потому что создаёт ложную уверенность.
Заключение: внедряем мониторинг правильно
Мониторинг производительности строится не из покупки инструмента, а из последовательности решений: какие метрики отвечают за инциденты, кто получает уведомления, что делать по каждому алерту. Начните с семи базовых метрик, добавьте второй уровень детализации после накопления baseline и пересматривайте пороги по фактам, а не по ощущениям.
Чек-лист для запуска:
- Определите 5-10 критичных сервисов и их владельцев.
- Разверните Prometheus и Grafana на отдельном узле.
- Установите node_exporter на Linux и windows_exporter на Windows, закройте порты экспортеров от внешнего доступа.
- Импортируйте дашборды 1860 и 14694, проверьте, что графики строятся.
- Настройте retention: 30 дней сырых данных, год агрегатов.
- Создайте правила на доступность, место на диске, iowait, нагрузку CPU, ошибки сети и задержку диска.
- Подключите каналы уведомлений и проверьте доставку тестовым срабатыванием.
- Опишите runbook для каждого критичного алерта.
- Собирайте baseline 2-4 недели и только затем фиксируйте пороги.
- Проведите первый разбор инцидента по метрикам и обновите правила по его итогам.
Следующий шаг после запуска - проверить систему на устойчивость: остановите экспортер на тестовом сервере и убедитесь, что алерт дошёл до дежурного за отведённые минуты. Если уведомление не пришло, у вас нет мониторинга, а есть только графики.