Backend Typescript 1.0.0 Help

Микросервисная архитектура

Определение. Микросервис — это автономный процесс, реализующий узкую бизнес-возможность, владеющий своими данными и взаимодействующий с другими сервисами по явным контрактам. Цель — добиться слабой связности между компонентами при высокой внутренней связности каждого сервиса, чтобы команды могли независимо разрабатывать, тестировать, развёртывать и масштабировать части системы.

Зачем это нужно: цели и идеи

  • Независимые поставки. Каждая команда выпускает изменения в своём сервисе без координации «больших релизов».

  • Изоляция рисков. Сбой одного сервиса не «роняет» всю систему при корректной деградации и таймаутах.

  • Выбор технологий. Разные сервисы могут использовать разные стеки, если это оправдано и не ломает операционную совместимость.

  • Масштабирование по компонентам. Нагруженные сервисы масштабируются независимо, экономя ресурсы.

  • Орг-соответствие. Архитектура отражает структуру команд (закон Конвея), уменьшая коммуникационные накладные расходы.

Ключевые принципы реализации

  • Автономия данных. Каждый сервис владеет собственной схемой и не делит таблицы с соседями.

  • Явные контракты. Общение только через API с обратной совместимостью и версионированием.

  • Синхронное vs асинхронное. Синхронные вызовы (HTTP/gRPC) — для «онлайн» путей; асинхронные очереди/шины — для интеграций и фоновых реакций.

  • Идемпотентность. Повторная обработка сообщений и запросов не должна менять результат непредсказуемо.

  • Наблюдаемость по умолчанию. Логи, метрики и трассировки — часть функциональных требований.

  • Операционная готовность. Здоровье, readiness/liveness-пробы, сводные SLO и алерты — сразу в первый релиз.

  • Автоматизация. CI/CD, неизменяемые образы, декларативная инфраструктура и миграции данных.

  • Безопасность по умолчанию. Недоверие по умолчанию, mTLS, наименьшие привилегии, безопасное хранение секретов.

Как выбирать границы сервисов

Режьте систему по предметным возможностям и потокам данных, а не по техническим слоям (не «контроллеры», «репозитории», а «Платёж», «Каталог», «Доставка»). Учитывайте частоту изменений: то, что меняется вместе, должно жить вместе.

  • У каждого сервиса — собственная база, договорённости на уровне событий/контрактов.

  • Минимизируйте «сквозные» транзакции — вместо этого проектируйте локальные инварианты и чёткие реакции на факты.

  • Проверка границ: может ли сервис быть временно недоступен без обрушения пользовательского сценария? Если нет — границы выбраны плохо.

Коммуникации между сервисами

Синхронные вызовы упрощают запрос-ответ, но удлиняют критический путь: каждая новая «стыковка» увеличивает P95/таймауты. Асинхронные взаимодействия повышают устойчивость и разгружают фронт, но требуют проектирования доставки, повторов и порядка.

  • Контракты и версии. Не ломайте существующих потребителей: вводите /v2 как отдельный контракт.

  • Таймауты и повторы. Любая сеть ненадёжна: задавайте конечные таймауты, ограниченные ретраи и идемпотентные операции.

  • Корреляция. Передавайте Correlation-ID сквозь все вызовы.

openapi: 3.0.3 info: title: Orders API version: "1.0" paths: /v1/orders: post: summary: Create order parameters: - in: header name: Idempotency-Key schema: type: string responses: "201": description: created "409": description: duplicate

Данные и согласованность

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

  • Каждое изменение фиксируется локально, а затем доносится до других сервисов сообщением/вебхуком.

  • Получатели обязаны уметь безопасно обрабатывать повторы и внепорядковость.

  • Критичные инварианты (например, «баланс не уходит в минус») должны сохраняться локально, без внешних вызовов.

Деплой и инфраструктура

Стандартная операционная база: сервисы согласно доменной модели, по базе для каждого сервиса и многие другие участники микросервисной инфраструктуры. Поставляйте неизменяемые образы и конфигурации как код.

# Минимальный пример изоляции: у каждого сервиса своя БД services: users: image: example/users:1.0.0 environment: - DB_URL=postgres://users-db/... users-db: image: postgres:16 orders: image: example/orders:1.0.0 environment: - DB_URL=postgres://orders-db/... orders-db: image: postgres:16

Наблюдаемость и эксплуатация

Производственная готовность включает три столпа: логи, метрики, трассировки. Определите целевые SLO, на их основе стройте алерты и бюджет ошибок.

  • Логи: структурированные, с полями запроса/пользователя/корреляции.

  • Метрики: латентность, частота ошибок, насыщение ресурсов.

  • Трассировки: единый Correlation-ID на весь путь запроса.

Тестирование и качество

  • Юнит-тесты для предметной логики внутри сервиса.

  • Контрактные тесты потребителя и поставщика API, чтобы ловить несовместимые изменения.

  • Интеграционные тесты с локальными зависимостями (контейнеры/фейки), чтобы сценарии были воспроизводимыми.

  • E2E — немного и по критическим путям, иначе они станут хрупкими и медленными.

Безопасность

  • Аутентификация и авторизация на границе (шлюз) и внутри (межсервисные токены).

  • Шифрование на транспорте (mTLS) и в покое.

  • Секреты только в менеджере секретов, с ротацией.

  • Аудит действий и доступов.

Когда стоит и когда нет

  • Подходит, если много команд, быстрые релизы, высокие требования к масштабированию и изоляции отказов.

  • Не подходит, если домен простой, команда мала, а основные проблемы — в качестве кода и процессах, а не в архитектуре.

Чек-лист внедрения

  • Цели и ожидаемые метрики (скорость релизов, P95, надёжность).

  • Карта домена и кандидаты на сервисные границы.

  • Стандарты контрактов и версионирования.

  • Стратегии коммуникаций (где синхронно, где асинхронно).

  • Владение данными и правила согласованности.

  • Базовая наблюдаемость и пороговые SLO.

  • CI/CD, окружения, миграции, откаты.

  • Модель безопасности и работа с секретами.

  • Runbook и он-колл: кто, как и чем реагирует.

Мини-пример: идемпотентный запрос

Создание заказа должно безопасно переживать повторную отправку клиента/ретраи сети. Контракт вводит заголовок Idempotency-Key, по которому сервер распознаёт дубликаты.

POST /v1/orders HTTP/1.1 Host: api.example.com Idempotency-Key: 3f5c1f90-5a9b-4a6f-9a10-1f0e0b1c7a22 Content-Type: application/json { "items": [{"sku": "SKU123", "qty": 2}], "customerId": "cst_001" }
Last modified: 01 October 2025