← Блог

Мониторинг WebSocket: health check без ложных зелёных

REST API зелёный во всех дашбордах, а чат и live-обновления мертвы. Это ложный зелёный WebSocket: HTTP-проверки доказывают, что веб-сервер отвечает, но не то, что realtime upgrade и долгая сессия работают. Решение — GET sidecar, который мапит сбой WS в HTTP 503, и регистрация URL в StillOnline.

Краткий ответ

HTTP 200 на / или /api/health не доказывает WebSocket upgrade (HTTP 101) и ping/pong. StillOnline шлёт только HTTP GET — без native WSS probe. Добавьте GET /health с 503 при падении WS-процесса или heartbeat. Free: один URL, ~5 мин, только код статуса.

WebSocket — долгий двусторонний канал после короткого handshake. AWS ALB не проверяет WebSocket health — только HTTP GET на отдельный path. Мониторинг только REST /health пропускает nginx без Upgrade, упавший WS-worker и просроченный WSS-сертификат.

База: дизайн health endpoint · мониторинг API-only SaaS.

1. Почему HTTP 200 не доказывает работу WebSocket

Три слоя: L1 transport, L2 handshake (101), L3 session (ping/pong). StillOnline через sidecar — L1–L2; L3 — метрики в приложении → 503 или native WSS.

СимптомСлойПервая проверка
WS DOWN + HTTP UPL2/L3nginx Upgrade, WS-процесс, лимиты
Оба DOWNL1Хост, TLS, firewall
WS UP + HTTP DOWNМаршрутНеверный probe URL

Делайте: понять, куда бьёт монитор. Не делайте: считать зелёный REST аптаймом чата.

Triage: алерт → curl GET /health503 → логи WS → 200, но жалобы пользователей → L3 или proxy false green.

2. Sidecar GET /health vs синтетический WSS

GET sidecar200/503. Synthetic WSS — handshake снаружи. StillOnline — только первое.

ПодходStillOnlineNative WS
ПротоколHTTP GETWSS + ping
FreeКод статусаЗависит от вендора

Не делайте: 200 с ws_ok: false на Free — JSON не парсится.

app.get("/health", (req, res) => {
  const ok = !wsProcessCrashed && Date.now() - lastHandshakeMs < 300000;
  if (!ok) return res.status(503).json({ status: "down" });
  res.json({ status: "ok", connections: wss.clients.size });
});

Паттерн как у GraphQL и FastAPI — здесь сигналы WS-подсистемы.

3. Таймауты, TLS и reverse proxy

proxy_read_timeout nginx по умолчанию 60 с — idle WS обрывается. Heartbeat ≈ 75% от таймаута proxy.

False green: proxy отвечает на ping (0x9), не форвардя в backend — sidecar читает in-process stats.

  1. Upgrade / Connection через nginx.
  2. proxy_read_timeout > heartbeat.
  3. Срок WSS-сертификата.
  4. Логи 503.
  5. curl /health снаружи.

Редиректы и antibot: probe redirects.

4. Когда выделять отдельный probe URL

Один канонический HTTPS URL. Free — обычно GET /health с WS-проверками внутри. Ответ < 2 с.

Делайте: Cache-Control: no-cache, без JWT на probe. Не делайте: auth на URL монитора.

Native WSS — дополнение, не замена sidecar для StillOnline.

5. StillOnline и runbook оператора

StillOnline: GET probe, страница статуса, алерт после двух неудачных probe. wss:// не регистрируйте.

  1. stillonline.tech/app → проект.
  2. Check: GET https://api.yourapp.com/health, ожидание 200.
  3. Компонент «Realtime» на статусе.
  4. Один канал алертов на Free (Telegram).
  5. 2–3 цикла перед выводами о шуме.

При алерте: curl с домашней сети, логи WS и nginx, лимиты соединений, сертификат. REST может быть UP при WS-only outage.

Free — ~5 мин между probe. Pro/Ultimate — больше URL и каналов — тарифы.

Что дальше

Sidecar, таймауты proxy = heartbeat, StillOnline на /health, репетиция WS DOWN + HTTP UP в staging.

Дашборд StillOnline → sidecar URL → канал алертов.

Связанные материалы

FAQ

StillOnline проверяет WebSocket natively?

Нет — только HTTP GET и код статуса. Sidecar GET /health → 503 при сбое WS. wss:// не поддерживается.

Почему StillOnline зелёный, а чат мёртв?

Probe бьёт в REST/landing, не в WS-aware sidecar. Нужен 503 при падении handshake/heartbeat.

Что проверяет StillOnline Free?

Только код статуса, один URL, ~5 мин.

WS DOWN + HTTP UP — с чего начать?

curl /health снаружи → 503 → логи WS и nginx Upgrade → 200 при жалобах — усилить sidecar или добавить WSS.

/health или /ws/health?

На Free — один URL, обычно /health с WS внутри.

Когда нужен native WS-монитор поверх StillOnline?

Когда realtime — ядро выручки и нужен внешний WSS handshake. StillOnline остаётся на GET sidecar для статуса.