MAATRIX / Блог / Синтетические проверки: следим за сайтом глазами пользователя

Синтетические проверки: следим за сайтом глазами пользователя

MAATRIX

Дашборд с CPU, памятью и диском зелёный, все процессы живы, а вам всё равно пишут в поддержку «сайт не открывается» или «не могу зарегистрироваться». Знакомая ситуация: обычный мониторинг смотрит на сервер изнутри и не видит того, с чем реально сталкивается человек снаружи. Синтетические проверки закрывают именно этот разрыв — они имитируют действия настоящего пользователя и бьют тревогу раньше, чем это сделают жалобы.

Чем синтетический мониторинг отличается от мониторинга метрик сервера

Обычный мониторинг (Zabbix, Prometheus, Netdata и подобные) отвечает на вопрос «что происходит внутри сервера прямо сейчас»: загрузка CPU, свободная память, место на диске, жив ли процесс nginx, отвечает ли PostgreSQL на порту 5432. Это необходимая база — про то, как выбирать пороги для таких алертов и разбирать типичные сбои, у нас есть отдельная статья про три сигнала проблемы до падения: она как раз про признаки, которые видны изнутри сервера, ещё до того как всё рухнуло.

Синтетический мониторинг задаёт другой вопрос: «может ли реальный человек снаружи открыть сайт и сделать то, что ему нужно». Это принципиальная разница в точке наблюдения:

  • Внутренний мониторинг — агент или экспортёр работает на самом сервере (или рядом, в локальной сети), читает /proc, системные счётчики, логи, отвечает локальными командами (systemctl status, запросы к localhost).
  • Синтетический мониторинг — скрипт запускается снаружи, из другой точки интернета, и обращается к вашему сайту так же, как обращается браузер обычного посетителя: через публичный DNS, через интернет-провайдера, через реальный HTTP-запрос к публичному домену.

Из этого вытекает главный практический эффект: сервер может быть полностью здоров по всем внутренним метрикам и при этом быть недоступным или нерабочим для части или всех пользователей. Внутренние метрики отвечают «сервер жив», а вопрос пользователя другой — «сайт работает или нет». Это два разных вопроса, и синтетический мониторинг — единственный способ автоматически отвечать именно на второй.

Три класса проблем, которые видит только внешняя проверка

Разберём конкретно, где внутренний мониторинг молчит, а пользователь уже упёрся в проблему.

1. Сетевая проблема между пользователем и сервером. CPU на 8%, память свободна, nginx отвечает на curl localhost за 12 мс — но пограничный маршрутизатор апстрима роняет пакеты к вашей подсети, DNS-резолвер у части провайдеров отдаёт устаревшую запись после смены IP, или истёк TLS-сертификат и браузер показывает предупреждение вместо страницы. Сервер в этот момент «жив и здоров» с его собственной точки зрения — но это не имеет значения, если пользователь физически не может до него достучаться.

2. Проблема на уровне высокоуровневой логики конкретной функции. Форма регистрации возвращает HTTP 200, сервер отработал запрос без единой ошибки в логе, значит с точки зрения инфраструктуры всё в порядке. Но, например, после деплоя сломался JS-обработчик кнопки «Отправить», или письмо с подтверждением email перестало уходить из-за смены SMTP-креда, или в форме заказа отвалилась интеграция с платёжным шлюзом — и пользователь физически не может завершить регистрацию или оплату, хотя все серверные метрики зелёные. Это классический слепой пятно: ошибка не в инфраструктуре, а в прикладной логике конкретного пользовательского сценария, и обычный мониторинг сервера её принципиально не ловит, потому что он не выполняет саму бизнес-операцию — он смотрит только на процессы и коды ответа.

3. Деградация без падения. Главная страница отдаётся, но за 25 секунд вместо ожидаемых 1-2 (из-за забытого индекса в БД, утёкшей сессии с внешним API, разросшегося кэша). Формально «работает», по факту — пользователь уходит, не дождавшись загрузки.

Во всех трёх случаях внутренние метрики (CPU, память, статус процессов из статьи про три сигнала проблемы) остаются в норме или почти в норме — проблема целиком лежит в зоне, которую эти метрики не наблюдают.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Базовый принцип: скрипт, который ведёт себя как пользователь

Синтетическая проверка — это заранее написанный сценарий, который автоматически и регулярно (обычно раз в 1-5 минут) выполняет конкретную последовательность действий с внешней точки и сверяет результат с ожидаемым.

Простейший вариант — HTTP-проверка без браузера, curl из cron на отдельном мониторинговом хосте (не на проверяемом сервере — это важно, иначе вы снова мониторите «изнутри»):

#!/bin/bash
# synthetic-check-home.sh — запускается с ВНЕШНЕГО хоста, не с проверяемого сервера
URL="https://example.com/"
EXPECTED="Добро пожаловать"

RESPONSE=$(curl -s -o /tmp/resp.html -w "%{http_code} %{time_total}" --max-time 10 "$URL")
HTTP_CODE=$(echo $RESPONSE | cut -d' ' -f1)
TIME_TOTAL=$(echo $RESPONSE | cut -d' ' -f2)

if [ "$HTTP_CODE" != "200" ]; then
  echo "ALERT: главная вернула $HTTP_CODE вместо 200"
  exit 1
fi

if ! grep -q "$EXPECTED" /tmp/resp.html; then
  echo "ALERT: на странице нет ожидаемого текста — вероятно, отдана страница ошибки или заглушка"
  exit 1
fi

echo "OK: код $HTTP_CODE, время ответа ${TIME_TOTAL}с"

Это уже полезно (проверяет и доступность, и что содержимое не подменено страницей ошибки), но не покрывает сценарии с формами, JS и многошаговыми действиями. Для них нужен headless-браузер — Playwright имитирует реальные клики и заполнение полей:

// synthetic-check-signup.js — Playwright, запускается по расписанию с внешнего хоста
const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  const start = Date.now();

  try {
    await page.goto('https://example.com/register', { timeout: 15000 });
    await page.fill('#email', `synthetic-check+${Date.now()}@example.com`);
    await page.fill('#password', 'TestPassword123!');
    await page.click('button[type="submit"]');

    // Ждём конкретный результат, а не просто "страница загрузилась"
    await page.waitForSelector('.registration-success', { timeout: 10000 });

    console.log(`OK: регистрация прошла за ${Date.now() - start} мс`);
    process.exit(0);
  } catch (err) {
    console.error(`ALERT: сценарий регистрации сломан — ${err.message}`);
    process.exit(1);
  } finally {
    await browser.close();
  }
})();

Ключевая деталь — проверка не останавливается на «страница загрузилась», а идёт до конца сценария и сверяет именно ожидаемый финальный результат (.registration-success). Если по пути сломалась любая ступенька — валидация, отправка формы, редирект, показ подтверждения — проверка провалится, и именно это нужно поймать.

Важный практический нюанс: тестовые действия (регистрация, оформление заказа) выполняются на реальном продакшене, поэтому либо заводите отдельный синтетический тестовый аккаунт с понятным префиксом (как в примере выше), либо на бэкенде явно исключайте такие записи из аналитики и уведомлений менеджерам, чтобы не заваливать реальных сотрудников фейковыми «заказами».

Практическая ценность: находите раньше, чем пожалуются

У синтетического мониторинга есть два конкретных практических эффекта, которые обычный мониторинг не даёт в принципе.

Во-первых, он ловит проблемы, невидимые изнутри — те самые три сценария из раздела выше. Без внешней проверки о сломанной для части пользователей форме регистрации вы узнаете только из тикетов в поддержку, а тикеты приходят не мгновенно: часть недовольных пользователей просто уходит молча, не написав ничего.

Во-вторых — и это часто недооценивают — синтетическая проверка обычно обнаруживает деградацию быстрее, чем успевают накопиться первые жалобы. Проверка каждые 1-5 минут даёт алерт до того, как о проблеме напишут в саппорт, соберутся негативные отзывы или это заметит владелец бизнеса, открыв сайт лично. Это переход от реактивной модели («ждём, пока пожалуются») к проактивной («узнаём первыми и чиним, пока пользователи почти не заметили»). Ровно из-за этого соблазна многие ограничиваются мыслью «раз есть мониторинг, я и так узнаю первым» — почему это не всегда так и как разрыв между «мониторинг настроен» и «я реально узнаю первым» возникает на практике, разобрано в статье про миф «мониторинг — я узнаю первым».

Разница по времени реакции сильно зависит от продукта, аудитории и заметности поломки — универсального числа тут нет, любые «в среднем на N минут быстрее» без контекста конкретного проекта воспринимайте как грубый ориентир, а не гарантию.

Что проверять синтетически, а что нет

Соблазн — попытаться синтетически покрыть каждую кнопку и каждую страницу сайта. Это ошибка: такой подход дорог в поддержке (каждый редизайн ломает десятки сценариев), генерирует шум из ложных срабатываний на некритичных элементах и размывает внимание, когда действительно важный алерт тонет среди мелких.

Правильный фокус — только по-настоящему критичные для бизнеса пути:

СценарийСтоит проверять синтетическиПочему
Главная страница открывается и отдаёт 200ДаПервая точка контакта, ломается редко, но фатально
Вход/регистрация проходит до концаДаПрямая потеря новых пользователей
Оформление заказа — от корзины до подтверждения оплатыДаПрямая потеря выручки, часто ломается тихо (сломанная интеграция с платёжным шлюзом)
Поиск по сайту возвращает результатыОбычно да, если это ключевая функцияЗависит от продукта — для маркетплейса критично, для лендинга не нужно
Второстепенные страницы (блог, о компании)НетНизкий бизнес-риск, ломается редко, не стоит внимания и алертов
Каждая мелкая кнопка и виджет на страницеНетИзбыточно, дорого поддерживать, создаёт шум

Практическое правило: если сценарий сломается на 2 часа, а вы узнаете об этом через тикеты в саппорт — насколько это будет больно бизнесу? Если ответ «очень» — это кандидат на синтетическую проверку. Если «переживём» — не тратьте на него отдельный скрипт.

И главное — синтетические проверки дополняют полноценное тестирование (unit, интеграционные, e2e-тесты в CI), а не заменяют его. Цель синтетики — раннее обнаружение проблем именно в продакшене на нескольких критичных путях, а не исчерпывающее покрытие тестами всей функциональности сайта. Это разные инструменты для разных задач: тесты в CI ловят регрессии до деплоя, синтетика — то, что просочилось в прод несмотря на тесты (внешняя сетевая проблема, отвалившаяся интеграция, деградация стороннего сервиса).

Инструменты и с чего начать

Не обязательно писать всё с нуля. Варианты по уровню сложности:

  • Uptime Kuma — self-hosted инструмент с HTTP(s)-проверками, проверкой ключевых слов на странице, TCP/DNS-проверками и push-уведомлениями (Telegram, email, вебхуки). Хорошая отправная точка для проверок «страница отдаётся и содержит ожидаемый текст» без написания кода — у нас есть отдельный разбор настройки Uptime Kuma для мониторинга сайта и сервера.
  • Playwright / Puppeteer по cron — для сценариев с формами, JS и многошаговыми действиями, как в примере выше. Требует немного кода, но даёт полный контроль над сценарием.
  • Внешние SaaS-сервисы синтетического мониторинга (Pingdom, UptimeRobot, Checkly и аналоги) — готовая инфраструктура проверок с разных географических точек, не нужно поднимать свой мониторинговый хост. Платно, но экономит время на инфраструктуру самого мониторинга.
  • Healthchecks.io и аналоги — немного другой класс задачи (проверка, что регулярная фоновая задача, например ночной бэкап, действительно отработала), но идейно близко: сервис ждёт «сигнал жизни» снаружи, а не опрашивает сервер сам. Если вам актуальнее мониторинг именно cron-задач, у нас есть отдельная статья про мониторинг cron-задач через healthchecks.io.

Для обзора инструментов конкретно проверки доступности сайта — от простого curl до полноценных SaaS-решений — см. статью про инструменты мониторинга доступности сайта.

Технически удобно запускать проверки с отдельного лёгкого VPS в другом регионе или дата-центре, чем основной сервер — это даёт честную внешнюю точку наблюдения и заодно позволяет заметить региональные сетевые проблемы (сайт недоступен только для части стран из-за маршрута или блокировки у конкретного провайдера).

Частота, ложные срабатывания и откуда проверять

Частота проверки — компромисс между скоростью обнаружения и нагрузкой/стоимостью. Для критичных путей (главная, вход, оформление заказа) разумный ориентир — каждые 1-5 минут; для менее критичных можно реже, раз в 15-30 минут. Слишком частые проверки тяжёлых сценариев (полный проход регистрации через headless-браузер) могут сами создавать заметную нагрузку — здесь тоже стоит соотносить частоту с реальной критичностью сценария.

Ложные срабатывания — постоянная головная боль синтетики: разовый сетевой затык у самого мониторингового хоста, таймаут из-за временной перегрузки, флап при деплое. Стандартные меры:

  • Алертить не на первый провал, а на N подряд неудачных проверок (например, 2-3 подряд) — это фильтрует единичные сетевые всплески.
  • Проверять с нескольких географических точек одновременно, если аудитория распределена — недоступность с одной точки может быть локальной сетевой проблемой конкретного провайдера, а не проблемой сайта.
  • Держать таймауты разумными (10-15 секунд для страницы, больше для многошагового сценария) — слишком короткий таймаут сам генерирует ложные алерты на обычных пиках нагрузки.

Про то, как в принципе настраивать пороги алертов так, чтобы они не превращались в шум и не приводили к игнорированию уведомлений, у нас есть отдельная статья про алерты, которые не бесят — принципы оттуда напрямую применимы и к синтетическим проверкам.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Синтетический мониторинг заменяет Zabbix/Prometheus на сервере?

Нет, это дополнение, а не замена. Внутренний мониторинг нужен, чтобы понимать причину проблемы (кончилась память, диск, упал процесс), синтетический — чтобы узнать о самом факте проблемы с точки зрения пользователя. Используйте оба уровня вместе.

Можно ли обойтись без headless-браузера, только curl-запросами?

Для простых случаев (страница отдаётся, содержит ожидаемый текст, отвечает быстро) — да, curl-скрипт из примера выше вполне рабочий и лёгкий вариант. Для сценариев с JS-логикой, формами и многошаговыми действиями (регистрация, оформление заказа) без браузера не обойтись, потому что реальное поведение страницы формируется на клиенте.

Где физически запускать синтетические проверки?

С отдельного хоста вне вашей основной инфраструктуры — иначе вы теряете весь смысл внешней проверки. Подходит недорогой VPS в другом регионе, cron-задача на нём или запуск с внешнего SaaS-сервиса мониторинга.

Сколько сценариев нужно проверять синтетически для небольшого проекта?

Обычно 3-7 действительно критичных сценариев достаточно для старта: главная страница, вход, ключевая бизнес-функция (заказ, регистрация, оформление). Расширяйте список только когда появляется конкретный опыт, что именно ломается незаметно для внутренних метрик.

Как понять, что скрипт проверки сам не даёт ложных алертов?

Дайте ему поработать несколько дней без реальных алертов пользователям (в тестовом режиме, только с логом) и посмотрите на частоту срабатываний — если алерты идут пачками без реальных причин, скорее всего таймауты или логика проверки слишком строгие.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →