Node.js Internals
Production Patterns: Node.js в продакшене
В 3 часа ночи тебе звонит бот: "Error rate 50%, latency 10 секунд, пользователи в панике". Ты открываешь Grafana и за 2 минуты находишь проблему - медленный SQL запрос. Откатываешь деплой. Всё работает. Вот зачем нужен production monitoring.
- **GitHub outage 2018:** База упала, но readiness probe не было. Kubernetes продолжал слать трафик на мёртвые поды. 24 часа даунтайма. После этого добавили health checks.
- **Stripe:** Используют Canary deployments — сначала 1% трафика на новую версию. Если error rate вырос — автоматический rollback за 30 секунд.
- **Netflix:** Chaos Engineering — специально убивают случайные сервисы в продакшене, чтобы проверить resilience. Помогло пережить AWS outage без даунтайма.
Введение: 12-factor app
**Production** - это совсем другой мир. Код, который отлично работает на localhost, может умереть в продакшене от первого же деплоя. Нужны паттерны, которые делают приложение надёжным, наблюдаемым и масштабируемым.
**12-factor app** - это методология разработки SaaS-приложений, которая описывает 12 принципов для production-ready сервисов. Самые важные для Node.js:
**Ключевые принципы:** 1. **Конфиг в переменных окружения** - порты, DB credentials, API ключи в ENV 2. **Stateless процессы** - не храни данные в памяти, используй Redis/БД 3. **Логи как event streams** - пиши в stdout, а не в файлы 4. **Graceful shutdown** - корректно завершай запросы при SIGTERM
**Containerization (Docker):** Упаковка приложения с зависимостями в изолированный контейнер. Это решает проблему "работает на моей машине".
**Orchestration (Kubernetes):** Управление контейнерами в продакшене - автоматический перезапуск, масштабирование, балансировка нагрузки.
Почему конфигурация должна быть в переменных окружения, а не в коде?
Health Checks
**Health checks** - это способ для оркестратора (K8s, Docker Swarm) проверить, жив ли контейнер и готов ли он обрабатывать запросы. Без них оркестратор не знает, когда контейнер упал и нужен перезапуск.
**Два типа проб в Kubernetes:** 1. **Liveness probe** - жив ли процесс? Если нет - убить и перезапустить 2. **Readiness probe** - готов ли принимать трафик? Если нет - не слать запросы
**Liveness vs Readiness:** - **Liveness:** Процесс завис в deadlock? Event Loop заблокирован? → Перезапуск - **Readiness:** База недоступна? Кеш не прогрелся? → Не слать трафик, но не убивать
**Важно:** Readiness probe НЕ должен убивать контейнер. Если БД временно недоступна (network glitch), контейнер просто ждёт восстановления.
**Проверка зависимостей:** Не проверяй внешние сервисы в liveness (они могут упасть). Liveness - только для проверки самого приложения.
Что произойдёт, если liveness probe вернёт 503 три раза подряд?
Structured Logging
**Structured logging** - это логи в формате JSON, а не обычный текст. Это позволяет легко парсить, фильтровать и анализировать логи в системах мониторинга (ELK, Grafana Loki, DataDog).
**Проблема с console.log:** Он не даёт контекста - уровня логирования, timestamp, metadata. В продакшене это бесполезно.
**Log levels (от DEBUG до FATAL):** - **trace/debug:** Детальная информация для отладки - **info:** Общая информация о работе (startup, shutdown) - **warn:** Предупреждения (deprecated API, retry) - **error:** Ошибки, которые не ломают приложение - **fatal:** Критические ошибки, приложение не может работать
**Pino** - самый быстрый JSON logger для Node.js. Он асинхронный и не блокирует Event Loop.
**Correlation ID** - это уникальный ID запроса, который прокидывается через всю цепочку сервисов. Это позволяет отследить весь путь запроса в distributed системе.
**Winston** - альтернатива Pino с поддержкой транспортов (файлы, БД, external services).
**Best practices:** 1. Логи пишутся в stdout/stderr (12-factor app) 2. Используй JSON формат для парсинга 3. Добавляй correlation ID для трейсинга 4. Не логируй секреты (пароли, токены, API ключи) 5. Используй правильные log levels (не всё должно быть error)
Зачем нужен correlation ID?
Zero Downtime Deployments
**Zero-downtime deployment** - это способность деплоить новую версию приложения без прерывания обслуживания пользователей. Ни одного 503 ответа, ни одного разорванного соединения.
**Проблема обычного деплоя:** 1. Останавливаем старую версию → пользователи получают 503 2. Запускаем новую версию → приложение стартует 10-30 секунд 3. Всё это время сервис недоступен
**Три стратегии zero-downtime:** 1. **Rolling deployment** - постепенная замена старых подов новыми (K8s default) 2. **Blue-Green deployment** - две полные копии (старая и новая), переключение в один момент 3. **Canary deployment** - сначала 5% трафика на новую версию, потом 100%
**Rolling deployment:** Kubernetes запускает новые поды, ждёт readiness probe, затем убивает старые. Постепенно все поды заменяются.
**Graceful shutdown:** При получении SIGTERM приложение должно: 1. Перестать принимать новые запросы 2. Завершить текущие запросы (дать время, например 30 секунд) 3. Закрыть соединения с БД/Redis 4. Выйти с кодом 0
**Blue-Green deployment:** Два полных окружения (синее и зелёное). Деплоим в зелёное, тестируем, переключаем трафик. Если что-то сломалось - мгновенный rollback на синее.
**Canary deployment:** Постепенное переключение трафика. Сначала 5% на новую версию, потом 25%, 50%, 100%. Если метрики плохие - откатываем.
В чём главное отличие Blue-Green от Rolling deployment?
Monitoring & Alerting
**Monitoring** - это сбор метрик приложения (CPU, память, latency, error rate) и визуализация в real-time. **Alerting** - это уведомления, когда метрики выходят за пределы нормы.
**Prometheus** - это стандарт для сбора метрик в Kubernetes. Он pull-based: сам опрашивает приложения через /metrics endpoint.
**Golden Signals (Google SRE):** 1. **Latency** - время ответа (p50, p95, p99) 2. **Traffic** - requests per second (RPS) 3. **Errors** - процент ошибок (4xx, 5xx) 4. **Saturation** - использование ресурсов (CPU, memory, disk)
**Prometheus конфигурация:** Указываем, где найти /metrics endpoints приложений.
**Grafana dashboards:** Визуализация метрик из Prometheus. Можно создать дашборд с графиками latency, RPS, error rate.
**Alerting:** Prometheus AlertManager отправляет уведомления (Slack, PagerDuty, Email), когда метрики выходят за пределы.
**APM (Application Performance Monitoring):** DataDog, New Relic, Sentry предоставляют более глубокий анализ - distributed tracing, code profiling, error tracking.
**Best practices:** 1. Мониторь Golden Signals (latency, traffic, errors, saturation) 2. Настрой алерты для критичных метрик (error rate > 5%, p95 > 2s) 3. Используй distributed tracing для микросервисов 4. Храни метрики минимум 30 дней для анализа трендов 5. Создай runbook для каждого алерта (что делать при срабатывании)
Логов достаточно для мониторинга. Зачем нужны метрики?
Логи и метрики решают разные задачи. Метрики показывают тренды (RPS растёт, latency увеличивается), логи - детали конкретного запроса
Метрики агрегированные (1 число в секунду), их можно хранить годами. Логи детализированные (1 строка на запрос), их хранят 7-30 дней. Метрики для алертов и трендов, логи для debugging.
Что такое P95 latency и почему это важнее среднего (average)?
Ключевые идеи
- **12-factor app:** Конфиг в ENV, stateless процессы, логи в stdout, graceful shutdown. Это фундамент для production-ready приложения.
- **Health checks:** Liveness (жив ли процесс?) и Readiness (готов ли принимать трафик?). Без них Kubernetes не знает, когда перезапускать поды.
- **Structured logging:** JSON логи + correlation ID. Это позволяет искать проблемы в distributed системах (5 микросервисов, 1 запрос).
- **Zero-downtime deployment:** Rolling (постепенная замена), Blue-Green (instant rollback), Canary (постепенный трафик). Graceful shutdown — must have.
- **Monitoring:** Prometheus + Grafana для метрик, AlertManager для уведомлений. Мониторь Golden Signals (latency, traffic, errors, saturation).
Связанные темы
Production patterns связывают все аспекты Node.js:
- Cluster Module — Graceful shutdown должен корректно завершать workers. PM2 автоматически делает zero-downtime reload.
- Event Loop — Health check должен проверять, что Event Loop не заблокирован. Метрика event_loop_lag в Prometheus.
- Memory Management — Мониторинг heap usage + автоматический restart при превышении лимита (K8s limits).
Вопросы для размышления
- Как бы ты реализовал zero-downtime deployment для WebSocket сервера? Учти, что соединения long-lived.
- Зачем нужны и liveness, и readiness probes? Можно ли обойтись одним?
- Какие метрики ты бы добавил для мониторинга Node.js API? Назови 5 самых важных.