Программная архитектура

Проработать

  1. Монолитная vs Микросервисная архитектура
  2. Микросервисы на Java: практическое руководство
  3. Взаимодействие в архитектуре микросервисов
  4. Системный дизайн

  5. Архитектурная Ката / Максим Чернухин, Глеб Гончаров
  6. Что нужно знать новичку о системном дизайне? | Все о системном проектировании с примерами
  7. Системний Дизайн - Резервування Слоту Під Навантаженням - Java: Про ІТ під каву - #47
  8. DDD

  9. Что такое DDD за 10 минут с примерами
  10. TDDx2, BDD, DDD, FDD, MDD и PDD, или все, что вы хотите узнать о Driven Development
  11. Денис Пинчук: Как внедряли DDD в Яндекс 360. Интервью с руководителем команды backend
  12. Практические вопросы архитектуры ПО, из чего строить будем?

Основные разделы

Монолит

Монолитное приложение(монолит) представляет собой приложение, доставляемое через единое развертывание. Таким является приложение, доставленное в виде одной WAR или приложение Node с одной точкой входа. Содержит: UI слой, сервис слой, слой работы с БД и тд.

Multitier

Разделение монолита на несколько частей. Отличие от микросервисов - каждый микросервис может иметь все слои в себе. Это значит микросервис - маленький монолит.

Обычно разделяется на:

  1. Presentation layer(Front-end)
  2. Logic layer(Back-end)
  3. Data layer(Database administrators)

Распределённые системы

Распределённые системы — это общая концепция, в которой вычисления распределены между несколькими узлами (компьютерами, серверами, сервисами), работающими вместе для достижения общей цели.

Примеры распределенных систем на java

  1. Microservice(Микросервисы) - Стек: Spring Boot, Spring Cloud, Docker, Kubernetes. Стек: Spring Boot, Spring Cloud, Docker, Kubernetes.
  2. Распределённые вычисления (Big Data, Machine Learning) - Стек: Apache Hadoop, Apache Spark. Пример: Аналитическая система для обработки больших данных.
  3. Распределённые базы данных - Стек: Apache Cassandra, Apache Ignite, Redis Cluster. Пример: Глобально распределённая база данных для социальной сети.
  4. Распределённые системы на основе акторов - Стек: Akka, Java, Scala. Пример: Чат-приложение с обработкой сообщений в реальном времени, где каждый пользователь представлен актором.
  5. Peer-to-Peer (P2P) системы - Стек: JXTA, WebRTC, Netty. Пример: Торрент-клиент или децентрализованное приложение для обмена файлами.

Виды процессов разработки:

  1. TDD(Test-driven development)
  2. DDT(Data-driven testing)
  3. BDD(Behavior-driven development)
  4. DDD(Domain-Driven Design)

Event-Driven Architecture (EDA)

Event-Driven Architecture - это архитектурный стиль, основанный на идее обработки событий как основного способа взаимодействия между компонентами системы. В такой архитектуре приложения реагируют на события, которые могут быть как внутренними (например, изменение состояния системы), так и внешними (например, действия пользователя или события, происходящие в других системах).

Основные принципы

  1. Производители событий генерируют события, которые могут быть асинхронными и происходить в любой момент времени.
  2. Потребители событий реагируют на эти события, принимая меры или изменяя свое состояние в ответ.
  3. Обмен событиями может происходить через системы обмена сообщениями, такие как Kafka, RabbitMQ или AWS SNS.
  4. Асинхронность и декуплинг между компонентами — компоненты не зависят друг от друга напрямую, а взаимодействуют через события.
  5. Масштабируемость — благодаря асинхронности система может легче масштабироваться и выдерживать нагрузку.

Domain-Driven Design (DDD)

Domain-Driven Design (Проектирование, ориентированное на предметную область) — это подход к проектированию программных систем, который ставит в центр внимания бизнес-логику (предметную область) и требует тесного сотрудничества между разработчиками и экспертами в предметной области. В DDD выделяются такие важные концепции, как ограниченные контексты, агрегаты, сущности и события домена.

Основные принципы

  1. Domain Model - центрирование на предметной области. Вся разработка фокусируется на точном моделировании и понимании бизнес-процессов. Она не просто структура данных, а объединение данных и логики (например, классы с методами, а не просто DTO).
  2. Ubiquitous Language - Вся команда (разработчики, аналитики, бизнес) использует единый язык, основанный на бизнес-терминах. Этот язык отражается в коде — имена классов, методов и т.п.
  3. Bounded Contexts - Большой бизнес-домен делится на поддомены, каждый из которых реализуется в своем ограниченном контексте. Например, "Платежи", "Пользователи", "Отчеты" — это могут быть отдельные модули или микросервисы.
  4. Entities и Value Objects. Entity (Сущность) — объект с уникальным идентификатором, который сохраняет свою личность во времени (например, User, Order). Value Object (Объект-значение) — определяется только своим содержимым (например, Money, Address).
  5. Aggregates и Aggregate Root. Aggregate — группа связанных сущностей и объектов-значений, объединённых вокруг одной главной сущности (Aggregate Root). Извне доступ только через корень (например, Order с OrderLines).
  6. Domain Events - cобытия, которые описывают что-то важное, что произошло в домене (например, OrderPlaced, UserRegistered).

Когда применять:

Не подходит если:

Correlation ID

Correlation ID - уникальный идентификатор, который используется для отслеживания запросов в распределённых системах и микросервисах. Он помогает связывать связанные запросы и упрощает диагностику, логирование и мониторинг.

Зачем нужно

Как работает

Генерация

Correlation ID создаётся на входе в систему (например, при запросе от клиента).

Если запрос приходит с уже существующим Correlation ID (например, от другого микросервиса), он сохраняется.

Передача

Correlation ID передаётся через HTTP-заголовки (например, X-Correlation-ID).

Может использоваться в логах каждого сервиса.

Использование в логах

Логи всех сервисов включают Correlation ID, что упрощает анализ.

Пример использования:

  1. Отправляем запрос в веб-приложение.
  2. API-шлюз создаёт Correlation ID и передаёт его дальше.
  3. Backend получает этот ID и использует его в логах.
  4. Backend вызывает другие микросервисы, передавая тот же ID.
  5. Все сервисы логируют свои действия с этим ID.
  6. В случае ошибки или долгого запроса можно легко проследить, где возникла проблема.