Перейти к основному содержимому

Node.js

Для чего модуль

Освоить Node.js как серверную платформу, а не только как «среду запуска JS»: понимать runtime, проектировать устойчивые API и сопровождать сервис в production.

Результат после прохождения

  1. Вы объясняете Event Loop и поведение асинхронности в Node без путаницы.
  2. Вы проектируете API-слой с контрактом ошибок, таймаутами и защитой от деградации.
  3. Вы понимаете, как работать с памятью, логированием, health-check и graceful shutdown.
  4. Вы умеете разбирать инциденты через метрики, логи и воспроизводимый runbook.

Термины и аббревиатуры

ТерминКоротко
Event LoopЦикл обработки задач
BackpressureКонтроль скорости потока
IdempotencyБезопасный повтор операции
ReadinessГотовность принимать трафик
p95/p99Хвостовые метрики задержки

Фокус по грейдам

  1. Junior: понимать базовые механики и объяснять их простыми примерами.
  2. Middle: применять тему в продуктовых сценариях с учетом рисков и ограничений.
  3. Senior: управлять архитектурными trade-offs, метриками и эволюцией решения.

Как работать с модулем

  1. Каждый урок связывайте с одним сервисом (реальным или учебным): API + DB + внешняя зависимость.
  2. Любое решение формулируйте через SLA/SLO и риск-профиль.
  3. После урока добавляйте минимум один технический артефакт: код, runbook, checklist.

Программа модуля

Урок 1. Runtime и async

Цель: понимать, как Node обрабатывает нагрузку и почему «иногда тормозит».

Event Loop и очередь задач

Ключевые элементы:

  1. Phases Event Loop (timers, poll, check и т.д.).
  2. Microtasks queue (Promise callbacks).
  3. process.nextTick и риск starvation.

I/O-bound vs CPU-bound

Node отлично работает с I/O, но CPU-heavy вычисления могут блокировать loop.

// Плохо: тяжелая синхронная работа в request path
app.get('/report', (req, res) => {
const data = buildHugeReportSync();
res.json(data);
});

Streams и backpressure

Для больших данных используйте stream pipeline, чтобы не раздувать память.

import { pipeline } from 'node:stream/promises';

await pipeline(readable, transform, writable);

Где ломается в проде

  1. Блокирующие операции в hot-path endpoint.
  2. Чтение больших файлов/ответов «целиком в память».
  3. Непонимание разницы nextTick/setImmediate/setTimeout.

Мини-задача (обязательная)

Сравните два варианта обработки большого файла: readFile и stream pipeline. Зафиксируйте разницу по памяти и latency.

Что спросит интервьюер: почему setImmediate, setTimeout и process.nextTick ведут себя по-разному.

Критерий готовности по уроку: вы можете по симптомам определить, упирается ли сервис в CPU, I/O или архитектурный bottleneck.

Урок 2. Сервисная архитектура API

Цель: построить API-слой, который предсказуем в ошибках и удобен в эксплуатации.

Структура и границы

  1. Route/controller слой.
  2. Service/use-case слой.
  3. Infra layer (DB, внешние API, cache, queue).

Принцип: бизнес-правила не смешиваются с transport/infra кодом.

Error contract

Стабильный контракт снижает время диагностики и улучшает UX.

{
"error": {
"code": "ORDER_CONFLICT",
"message": "Order already confirmed",
"traceId": "f1f5..."
}
}

Таймауты, retry, idempotency

  1. Таймаут обязателен на внешние вызовы.
  2. Retry только для транзиентных ошибок и с backoff.
  3. Для критичных операций используйте idempotency key.

Где ломается в проде

  1. API возвращает хаотичные форматы ошибок.
  2. Retry без лимита усиливает деградацию.
  3. Секреты и конфиги «зашиты» в код/образ.

Мини-задача (обязательная)

Опишите контракт ошибок для 5 типовых сценариев: валидация, auth, conflict, external timeout, unknown error.

Что спросит интервьюер: как вы отделяете бизнес-ошибки от инфраструктурных.

Критерий готовности по уроку: вы можете показать API-контур, в котором ошибки и таймауты контролируются, а не «случайны».

Урок 3. Надежность под нагрузкой

Цель: проектировать сервис так, чтобы он деградировал контролируемо, а не падал каскадно.

Protection patterns

  1. Rate limiting и throttling.
  2. Queue/buffer для всплесков нагрузки.
  3. Circuit breaker и bulkhead-подход.

Worker threads и cluster

  1. worker_threads — для CPU-bound задач.
  2. cluster/multi-process — масштабирование по ядрам и отказоустойчивость процесса.

Cache и consistency trade-offs

  1. Кэш снижает latency, но может отдавать stale данные.
  2. Нужна стратегия invalidation и fallback на cache miss.
  3. Hot key и cache stampede должны быть предусмотрены.

Где ломается в проде

  1. Нет лимитов на дорогие endpoint.
  2. Очередь не ограничена и становится «черной дырой».
  3. Нет плана деградации при отказе внешнего сервиса.

Мини-задача (обязательная)

Подготовьте план защиты endpoint при росте трафика x10: лимиты, деградация ответа, очереди, алерты, rollback критерии.

Что спросит интервьюер: что вы будете делать первым делом при росте p95 latency.

Критерий готовности по уроку: вы можете описать надежностный контур сервиса и объяснить, как он ведет себя при отказах.

Урок 4. Эксплуатация

Цель: сопровождать Node-сервис в проде как инженерную систему.

Наблюдаемость

  1. Structured logs (JSON) с traceId/requestId.
  2. Метрики: latency, error rate, saturation.
  3. Health/readiness probes.

Память и диагностика

  1. Разница между heap leak и внешним ростом памяти.
  2. Heap snapshots и профилирование.
  3. Корреляция роста памяти с конкретными сценариями нагрузки.

Graceful shutdown и релизы

  1. Перестать принимать новый трафик.
  2. Дождаться завершения in-flight запросов.
  3. Закрыть соединения к DB/queue/cache.

Где ломается в проде

  1. Rollout без readiness checks.
  2. Логи без корреляции, невозможно собрать таймлайн инцидента.
  3. При рестарте теряются in-flight операции.

Мини-задача (обязательная)

Соберите post-release checklist и incident runbook: что проверяем в первые 30 минут после релиза и при каких условиях откатываемся.

Что спросит интервьюер: как вы расследуете утечку памяти в живом сервисе.

Критерий готовности по уроку: вы можете провести расследование инцидента от симптома до root cause и описать превентивные меры.

Практика

1. Runtime pressure и expensive work

Связка: Node q-1..q-5, Senior q-15.

Что сделать:

  1. Составьте runtime pressure table: symptom -> event loop lag -> CPU -> memory -> I/O -> first check.
  2. Для тяжелой операции выберите worker_threads, cluster/multi-process, queue или обычный async I/O и объясните trade-off.
  3. Подготовьте mini-runbook: что проверить первым при росте p95 latency и event loop lag.

Артефакт: runtime pressure table + worker/process decision note.

Критерий готовности: вы отличаете CPU-bound, I/O-bound, memory pressure и process-level scaling, а не называете Event Loop общими словами.

2. API endpoint reliability

Связка: Node q-7, Node q-9, Nest q-19.

Что сделать:

  1. Опишите endpoint с timeout, retry guard, idempotency key и единым error contract.
  2. Заполните policy table: operation -> timeout -> retry? -> idempotency -> fallback -> public error -> alert.
  3. Добавьте negative paths: external timeout, duplicate request, validation error, overload/rate limit, partial dependency outage.

Артефакт: API reliability policy table + error envelope compatibility table.

Критерий готовности: вы показываете, как endpoint ведет себя при сбое зависимости, перегрузке и повторном запросе, а не только на happy path.

3. Observability, health и release guard

Связка: Node q-8, Node q-10, Node q-13, Nest q-14.

Что сделать:

  1. Опишите health и readiness: что проверяет каждый endpoint, что не должен проверять, когда instance выводится из трафика.
  2. Составьте observability signal map: signal -> tags -> owner -> alert threshold -> dashboard -> runbook.
  3. Соберите post-release checklist: первые 30 минут после релиза, rollback criteria, какие метрики смотрим.

Артефакт: health/readiness spec + observability signal map + release checklist.

Критерий готовности: вы связываете logs/metrics/traces с конкретным runbook и rollback decision, а не просто добавляете structured logging.

4. Incident drill: external API degradation

Связка: Node q-8, Node q-10, Node q-17.

Что сделать:

  1. Смоделируйте кейс рост latency + рост ошибок внешнего API.
  2. Заполните incident timeline: detect, scope, dependency check, mitigation, customer impact, rollback/feature flag, postmortem actions.
  3. Отдельно добавьте memory investigation branch: как отличить leak от нормального роста под нагрузкой.

Артефакт: incident runbook + memory investigation branch.

Критерий готовности: вы можете расследовать инцидент от симптома до root cause и назвать preventive controls.

Связь с треками и вопросами

  1. Runtime fundamentals: Node q-1..q-5.
  2. API/reliability operations: Node q-7..q-10, Node q-13, Node q-17.
  3. Security/config/cache/API compatibility: Node q-11, Node q-14..q-15, Node q-20.
  4. Framework continuation: Nest q-6, Nest q-14, Nest q-19.
  5. Data-access continuation: Node q-18..q-19, Nest q-11, Databases q-5, SQL-песочница: оплаченные заказы без дублей.
  6. Повторение: завтра заново пройдите один incident drill и один query-count drill, если любой шаг требует догадки.

Критерий готовности

Ready: вы объясняете Node-сервис как production-систему: runtime pressure, API reliability, overload controls, observability, release guard и incident response.

Partial: вы знаете Node API и Event Loop, но не можете показать timeout/retry/idempotency policy, readiness semantics или rollback criteria.

Not ready: вы отвечаете про Node как про набор методов, не показывая поведение сервиса при сбоях, перегрузке и релизах.

Артефакты после модуля

  1. Runtime pressure table + worker/process decision note.
  2. API reliability policy table.
  3. Error envelope compatibility table.
  4. Health/readiness spec.
  5. Observability signal map.
  6. Release checklist + rollback criteria.
  7. Incident runbook для external API degradation.
  8. Data-access decision table: ORM/query builder/raw SQL, query count, index expectation, transaction boundary.
  9. N+1 guardrail: before/after query count and one regression assertion.

Куда дальше

  1. NestJS: перенесите Node reliability в modules, providers, guards and repositories.
  2. Базы данных: закрепите query plan, transaction and consistency decisions.
  3. SQL-песочница: проверьте join cardinality/N+1 мышление на исполняемой задаче.
  4. Node.js