Тезисы по системному дизайну

Канал о системном и бизнес-анализе, продуктовом мышлении и архитектуре. Как выявлять реальные проблемы, строить работающие решения и не терять здравый смысл в IT. Все вопросы - @innokentyB

системный дизайнскейлингмикросервисы

Всем привет!

Вчера провели встречу посвященая системному дизайну — зачем он нужен, как проводить интервью по нему, какие подходы считаются хорошими, а какие — не очень.

  • Системный дизайн — не про создание YouTube с нуля, а про умение подходить к архитектуре решений адекватно: понимать, зачем ты проектируешь, какие есть ограничения, сколько пользователей и как это будет масштабироваться.
  • Неправильный подход — сразу делать «миллиард пользователей и микросервисы».
  • Правильный подход — начать с MVP, понимать, что будет меняться, где узкие места, и проектировать с возможностью постепенного роста.

🧪 Пример с телеграм-ботом:

  • Сделан за 2 часа, с SQLite под капотом, без вебхуков (используется long polling).
  • Простая реализация, которая работает, справляется со своей задачей. Когда нагрузка вырастет — заменят SQLite на PostgreSQL.
  • Главный месседж: если знаешь, где слабые места, это окей — мониторь и улучшай по мере необходимости.

📈 Скейлинг и автоскейлинг:

  • Что такое горизонтальное масштабирование (новые инстансы).
  • Как определить, когда надо скейлиться — метрики (CPU, кол-во соединений).
  • Примеры настройки автоскейлинга на AWS.

💬 Обсуждение API и архитектуры:

  • Клиент-серверная модель: браузер — клиент, сервер — отвечает.
  • API — это контракт взаимодействия, желательно публичный и документированный.
  • SQLite хорош для простых приложений, но не для больших нагрузок.

🧵 Асинхронность, очереди, шины:

  • Асинхронная обработка запроса: клиент отправил — сервер положил задачу в очередь.
  • Уведомление о завершении задачи — через почту, пуш, или API polling.
  • Шины сообщений (RabbitMQ, Kafka) — удобны для микросервисов и снижения связанности.
  • Kafka используется для логирования и анализа, Rabbit — для событий и коммуникаций между сервисами.

🔄 Eventual Consistency и проблемы шины:

  • Данные не синхронны — это нормально.
  • Нужны механизмы переигрывания (реплей), контроля доставки, обработки неудачных сообщений.
  • Сага — шаблон управления распределёнными транзакциями: как откатить, если шаг провалился.

🧱 Монолит vs микросервисы:

  • Не надо уходить в микросервисы просто потому что модно.
  • Сначала вырастите монолит, поймите, где границы, потом уже выносите в сервисы.
  • Закон Конвея: архитектура повторяет оргструктуру.
  • Проблема распределённого монолита — усложнение без выигрыша в независимости.

🧭 Domain-Driven Design (DDD):

  • DDD — это про мышление бизнес-доменами, а не про базы данных.
  • Разделение логики по бизнес-смыслу: в одной системе может быть понятие «пользователь» в разных контекстах (например, в биллинге и в доступах).
  • Bounded Context — ключевое понятие: внутри него — свои модели, вне — взаимодействие через контракты (например, API).

“Нельзя взять модель одного сервиса и напрямую использовать в другом — лучше через API.”


🧩 Модульность и выделение сервисов:

  • Пример: систему делят на сервис заказов, пользователей, биллинга и т.д.
  • Между сервисами — минимальные связи, общение через API/шину событий.
  • Вынос сервисов логичен, когда они эволюционно становятся самостоятельными.
  • Не нужно «микросервисить» с самого начала — это усложнит всё.

🛑 Антипаттерны распределённых систем:

  • Распределённый монолит: вроде бы микросервисы, но при этом жёсткие связи между сервисами, деплой одного влияет на другой.
  • Отсутствие автономии — главный враг микросервисов.
  • Ошибка начинающих: каждый микросервис имеет свою базу, но по сути — всё равно связан жёстко через логику.

💥 Разграничение ответственности:

  • Надо разделять: кто отвечает за сохранение данных, кто за их обработку, кто за их показ.
  • Важно, чтобы команды были привязаны к сервисам, а не к слоям (как фронтенд, бекенд, база).

🎨 Микрофронтенды:

• Очень больная тема. Теоретически позволяют разным командам независимо пилить фронт.

• На практике — огромная сложность:

  • • Конфликты версий библиотек
  • • Разные подходы к сборке, роутингу
  • • Долгие загрузки и проблемы UX

“Проще использовать условно iframe, чем пытаться сшить всё красиво.”