Основы архитектуры ПО: выбор подходящего архитектурного стиля

Обсудили в рамках встречи книжного клуба {между скобок} 18-ю главу книги «Fundamentals of software architecture» за авторством Mark Richards и Neal Ford. Ниже мой краткий конспект этой главы с моими комментариями и дополнениями (курсивом).

Shifting “Fashion” in Architecture

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

Например:

  • Что важнее, простота развертывания и сопровождения в периметре клиента или масштабируемость в поддержку высокой и непредсказуемо изменяющейся нагрузке?
  • Стратегически мы ориентируемся на небольшое число больших клиентов или на огромное число небольших, возможно даже частных?
  • Есть ли в планах выход на международный рынок с развертыванием в других странах с адаптацией под местные традиции и законодательство?

Но, несмотря на сильнейшую зависимость от контекста, все же есть ряд общих рекомендаций:

  • Использование прошлого опыта Авторы приводят в пример переосмысление подходов по повторному использованию кода, есть и другие – например, переосмысление использования хранимых процедур и подходы к нормализации данных в базах данных (CQRS).
  • Изменения в экосистеме Проектирование для изменений. Авторы приводят в пример стремительность изменений, например, появление Kubernetes, который через пару лет с такой же легкостью может быть заменен на что-то еще. В качестве примера можно привести принципы эволюционной архитектуры, – архитектурные тесты, архитектурную фитнес-функцию.
  • Новые возможности (capabilities) Без сомнения не только влияют на частные архитектурные решения, но и приводят к сдвигу парадигмы. Достаточно вспомнить о влиянии Докера на всю экосистему инструментов, практик, методов.
  • Ускорение Экосистема не просто изменяется, ускоряется темп изменений.
  • Изменение домена Предметная область проектируемого решения тоже все время меняется. Пример – слияние компаний.
  • Технологии изменяются
  • Внешние факторы Например, разработчикам и архитекторам может быть вполне комфортно с каким-то инструментом, но стоимость лицензий сдерживает его использование. Например – проприетарные реализации инструментария для C4.

Авторы делают вывод о том, что архитектор должен понимать индустрию.

На мой взгляд авторы немного смешали различные уровни абстракции (при первом прочтении не обратил на это внимание). Например, то, что технологии изменяются или что происходит ускорение изменений в экосистемы имхо является составной частью пункта «Изменения в экосистеме».

Я обычно подхожу к вопросу чуть иначе. Есть три вида сложности: технологическая, социальная и доменная. Каждая со своей скоростью, компонентами и связями, но при этом они связаны друг с другом. В каждом типе сложности есть структурная сложность, а есть динамическая.

Примеры структурной сложности:

  • Множество интеграций с другими системами
  • Множество подрядчиков и вендоров
  • Множество технологических платформ
  • Множество окружений
  • Обработка множества данных в реальном времени

Они все про количество чего-то в структуре.

Динамическая сложность складывается из интенсивности взаимодействия:

  • Быстрое и частое изменение IT-инфраструктуры
  • Быстрое изменение инструментов разработки
  • Быстрое изменение архитектуры
  • Быстрое изменение технологий, от которых зависит продукт

В социальной и доменной областях все по образу и подобию, ну так вот, проанализировав эти виды сложности мы вполне можем увидеть в первом приближении какой архитектурный стиль может подойти, потому что основной задачей архитектуры как было так и остается борьба со сложностью, а именно если не снижение ее, то хотя бы удержание на каком-то приемлемом уровне.

Критерии принятия решений

Далее авторы книги перечисляют важные в принятии архитектурных решений факторы:

Далее в книге перечислены решения, которые можно принять, опираясь не эти факторы:

  • Монолит или распределенная система (см. статью «От монолита к микросервисам в разумном порядке»)
    • Являются ли архитектурные характеристики едиными или различные части архитектурного решения требуют различных характеристик?
      • Единое множество говорит о том, что монолит подходит;
      • Отличия подразумевают распределенную природу решения
  • Место расположения данных
    • В монолитных системах обычно используется одна реляционная база.
    • В распределенных архитектору предстоит решить, какой сервис хранит данные и как они будут передаваться от сервиса к сервису

Я не зря выделил слово «обычно». В действительности ничего не мешает в монолитном решении использовать множество баз данных под свои нужды. Вполне разумным решением может быть разделение использование для различных нужд в рамках одного монолита как различные логические схемы в рамках одной базы данных, так и совершенно разные базы данных, например — постгрес, монго и какую-нибудь графовую. Важно только аккуратно провести транзакционные границы, чтобы различные базы данные не участвовали в одной распределенной транзакции, пусть и в рамках единого монолитного решения.

  • Синхронный или асинхронный стиль коммуникации
    • Это решение принимается после принятия решений о распределении данных
      • Авторы пишут, что в большинстве случаев синхронный стиль более подходящий, но он может снижать масштабируемость, надежность и ряд других характеристик
      • Асинхронная коммуникация дает большие возможности в масштабируемости и производительности, но порождает ряд сложностей с синхронизацией данных, deadlocks, race conditions, отладкой и так далее
    • Авторы предлагают использовать синхронную коммуникацию по-умолчанию, прибегая к асинхронной при необходимости.

Если немного уточнить критерии выбора синхронного или асинхронного вызова, то ключевым вопросом будет «Нуждается ли вызывающий сервис в ответе от вызываемого сервиса или в статусе выполнения запроса?». Если ответ положительный, но при этом вызываемому сервису требуется значительное время на выполнение запроса или существует длинная цепочка вызовов, которую нельзя сократить с помощью рефакторинга, то стоит рассмотреть возможность использования очередей, иначе можно рассмотреть различные способы синхронного взаимодействия (gRPC, REST, GraphQL….). Если же ответ отрицательный, то для широковещательных рассылок с множественными потребителями может подойти pub/sub, а для передачи большого количества сообщений с высокими требованиями к задержке (latency) рассмотреть стриминговые решения (kafka, kinesis, …). Если же требований по latency нет, либо требуется интеграция с легаси, то разумным вариантом может быть использование общего хранилища, в том числе интеграция через обмен файлами.

На выходе получаем архитектурную топологию, которая учитывает выбранный архитектурный стиль, ADR, принятые архитектурные решения и архитектурную фитнес-функцию, которая держит под контролем важнейшие архитектурные характеристики.

Далее идет описание поясняющего кейса, с ним предлагаю ознакомится самостоятельно, он достаточно интересный но кейс есть кейс, оставлю его без комментариев 🙂

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

Конечно, вся книга максимально полезная и must read для всех разработчиков и архитекторов, читайте и приходите в книжный клуб {между скобок} обсудить и порассуждать над прочитанным.

Share

Добавить комментарий