Проектирование распределённых систем — декомпозиция монолита на модули/сервисы (критерии границ), синхронное vs асинхронное взаимодействие (очереди, события), уровни масштабирования 100 → 10k RPS (кэш → реплики → шардинг), отказоустойчивость, наблюдаемость, что рисовать на архитектурной диаграмме. Use при проектировании архитектуры, обсуждении границ сервисов, очередей, масштабирования, отказоустойчивости.
Scanned 9/11/2026
Install to Claude Code
npx -y skills add Vitammiin/agent-vorcl-flow --skill system-design --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of System Design?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/vitammiin-system-design)More formats (shields.io, HTML) on the badges page.
---
name: system-design
description: Проектирование распределённых систем — декомпозиция монолита на модули/сервисы (критерии границ), синхронное vs асинхронное взаимодействие (очереди, события), уровни масштабирования 100 → 10k RPS (кэш → реплики → шардинг), отказоустойчивость, наблюдаемость, что рисовать на архитектурной диаграмме. Use при проектировании архитектуры, обсуждении границ сервисов, очередей, масштабирования, отказоустойчивости.
---
# Навык: System Design
## Декомпозиция: монолит → модули → сервисы
Дефолт — **модульный монолит** (структура — `$backend-architecture`): модули с жёсткими границами внутри одного деплоя. Отдельный сервис выделяй, только когда у куска есть *своя* причина жить отдельно.
Критерии границы (модуля или сервиса):
- **Своя предметная область** (bounded context): свой словарь, свои инварианты. «Биллинг» и «Уведомления» — разные контексты; «UserUtils» — не граница.
- **Свои данные**: модуль владеет своими таблицами; чужие данные — только через его публичный API, не JOIN'ом в его схему.
- **Своя причина меняться**: релизится/масштабируется независимо (рассылки идут пачками ночью, API — днём).
- **Свой профиль нагрузки или команда**: CPU-тяжёлый рендер PDF рядом с латентно-чувствительным API — кандидат на вынос.
Пример: интернет-магазин → модули `catalog` (товары, поиск), `orders` (корзина, инварианты заказа), `billing` (платежи, вебхуки провайдера), `notifications` (email/push, ретраи). Первый кандидат в отдельный сервис — `notifications`: асинхронный, независимый ритм, безопасен при отставании. Плохая декомпозиция — по техслоям («сервис контроллеров», «сервис БД») или по CRUD-сущностям без инвариантов.
## Синхронно vs асинхронно
| Признак | Синхронно (HTTP/gRPC) | Асинхронно (очередь/событие) |
|---|---|---|
| Ответ нужен прямо в этом запросе | ✅ | — |
| Результат можно отдать позже (email, отчёт, вебхук) | — | ✅ |
| Вызываемый может лежать, а мы должны жить | — | ✅ (очередь буферизует) |
| Пики нагрузки надо сглаживать | — | ✅ |
| Несколько независимых потребителей одного факта | — | ✅ (событие, pub/sub) |
| «Проверь и сразу реши» в одной транзакции запроса | ✅ | — |
- **Команда** («сделай X», один получатель, важен результат) → очередь задач с подтверждением и ретраями (Redis Streams / RabbitMQ / SQS).
- **Событие** («X случилось», реагирует кто подписан) → pub/sub; producer не знает потребителей.
- Асинхронность тянет обязательства: идемпотентные потребители (at-least-once = дубли будут), DLQ для «ядовитых» сообщений, eventual consistency в UX («заказ обрабатывается»).
## Масштабирование: 100 → 10k RPS
1. **~100 RPS** — один сервер приложения + одна БД. Хватает индексов и вменяемых запросов. Не усложняй.
2. **~1k RPS** — сначала **кэш**: Redis cache-aside для горячих чтений, CDN для статики. Затем **горизонтально масштабируй stateless-приложение** за балансировщиком (сессии — в Redis/JWT, не в памяти процесса).
3. **~5k RPS** — узкое место обычно БД → **read-реплики** (чтения на реплики, записи в primary; учитывай лаг репликации), пул соединений (pgbouncer), тяжёлые операции — в фоновые очереди.
4. **~10k+ RPS** — **шардинг** (партиционирование записей по ключу: user_id, tenant). Последний ход, дорог в поддержке (cross-shard-запросы, решардинг); прежде чем шардить, проверь, что не хватило кэша, реплик и выноса горячих таблиц.
Каждый уровень включай, только когда упёрся **измеримо** (метрики), а не «на вырост».
## Отказоустойчивость (минимум)
Таймаут на каждый сетевой вызов → ретраи с экспонентой и jitter только для идемпотентных операций → circuit breaker к падающей зависимости → graceful degradation (рекомендации отвалились — каталог работает). Идемпотентность записи — ключи идемпотентности (`$api-design`).
## Наблюдаемость
- **Логи** — структурные (JSON), с `traceId`/`requestId`, сквозным через все сервисы.
- **Метрики** — RED на каждый эндпоинт и зависимость: Rate, Errors, Duration (p50/p95/p99, не среднее).
- **Трейсинг** — OpenTelemetry: один trace через сервисы и очереди; без него распределённую задержку не найти.
## Что рисовать на архитектурной диаграмме
(Строить — `$mermaid-diagrams` / `$drawio-diagrams`.)
- **Уровень C4-container**: по блоку на деплоймент-единицу — сервисы, БД, кэш, очереди, внешние API. Не по классу и не по функции.
- **Стрелки = вызовы**, с протоколом и направлением инициации: `API → Postgres (SQL)`, `API → Billing (HTTP, sync)`, `Orders → queue → Notifications (async)`. Sync и async визуально различай (сплошная/пунктир).
- **Границы доверия/сети** (VPC, публичное/приватное) — рамками; точки входа (LB, gateway) — явно.
- Не тащи всё в одну диаграмму: контекст — отдельно, контейнеры — отдельно, критичные потоки — sequence-диаграммой.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!