От хаоса к порядку: принципы построения масштабируемых систем
Всем привет! Вы когда-нибудь работали с системой, которую боялись трогать? Где каждое изменение вызывало лавину багов, а обновление базы данных превращалось в операцию с многодневным даунтаймом? Я тоже. И чаще всего виной всему — не плохие разработчики, а слабая архитектура.
На основе книги "Software Architecture in Practice (SEI Series in Software Engineering)" собрал несколько практических принципов, позволяющих строить системы, которые будут поддерживаемыми длительный срок.
Модули с чёткими границами
Архитектура должна содержать четко определенные модули на основе принципа сокрытия зависимостей и разделения обязанностей. Модули должны инкапсулировать функциональность, которая, скорее всего, будет меняться. Каждый модуль должен обладать хорошо определенным интерфейсом, чтобы скрывать изменяемую часть. Эти интерфейсы позволят разрабатывать компоненты независимо друг от друга.
Используйте проверенные паттерны
В разработке программного обеспечения редко бывают абсолютно уникальные требования. Вопросы ранее уже решались в индустрии. Используйте опыт других. Применяйте и адаптируйте готовые архитектурные паттерны (CQRS, Event Sourcing, CDC и т.д.).
Не завязывайтесь на конкретные версии продуктов
Система должна быть гибкой. Привязка к конкретной версии БД или фреймворка превращает ее в заложника. Архитектура должна позволять обновление версии без значительного рефакторинга. В идеале — допускать замену инструмента (фреймворка, БД и т.п.) без катастрофических переделок.
Разделяйте модули, производящие и потребляющие данные
Отделение компонентов, генерирующих данные, от компонентов, потребляющих данные, даст системе большую гибкость. Хотя изменения обычно затрагивают и потребителя, и производителя данных. Это позволит обновлять и развивать компоненты по отдельности, без каскадных изменений по всей системе.
Модуль ≠ компонент
В реальных системах не стоит ожидать отношения компонентов к модулям как 1 к 1. Например, в системах с параллельной обработкой множество компонентов могут быть запущены одновременно, и каждый из этих компонентов может быть построен на основе одного модуля. Также в многопоточных системах каждый поток может использовать сервисы из различных компонентов, принадлежащих различным модулям.
Гибкость процессов
Каждый процесс должен быть написан таким образом, чтобы среду его выполнения можно было легко заменить. Это важный фактор, который позволит создавать приложения, работающие в виртуальных средах и облаках. Перенос приложения из одной вычислительной среды в другую должен быть максимально простым.
Простые и единообразные взаимодействия
Архитектура системы должна содержать небольшое разнообразие паттернов взаимодействия между компонентами. Эта практика позволит сделать систему понятнее и проще в разработке. Увеличит надежность, расширяемость и гибкость системы.
Минимизируйте зоны конкуренции за ресурсы
Архитектура системы должна содержать определенный (и небольшой) набор проблемных зон, решение и разрешение которых ясно определено, задокументировано. Например, если узким местом является использование сети, то архитектура должна содержать выработанные правила использования сети, а главное, эти правила должны соблюдаться в командах, чтобы привести к приемлемым уровням сетевого трафика.
Подписывайся на мой телеграм-канал