• Уровень служб. Мы можем ограничить зависимости до уровня структур данных и взаимодействовать, обмениваясь исключительно сетевыми пакетами, чтобы каждая единица выполнения была по-настоящему независимой от изменений в исходном и двоичном коде в других (как, например, службы и микрослужбы).
Какой режим лучше?
Ответ заключается в следующем: на ранних этапах разработки проекта трудно понять, какой режим лучше. В действительности по мере взросления проекта оптимальный режим может изменяться.
Например, нетрудно представить, что система, вполне комфортно чувствовавшая себя на одном сервере, может разрастись до масштабов, когда удобнее перенести некоторые ее компоненты на отдельные серверы. Пока система действует на одном сервере, разделения на уровне исходного кода может быть вполне достаточно. Но позднее может понадобиться разделить ее на единицы развертывания или даже на службы.
Одно из решений (набирающее популярность в наши дни) заключается в изначальном разделении на службы. Однако такой подход дорог и способствует разделению на слишком крупные блоки. Какими бы «микро» ни получились микрослужбы, маловероятно, что разделение будет выполнено на достаточно мелкие блоки.
Еще одна проблема разделения на службы — дороговизна, и в отношении разработки, и в отношении системных ресурсов. Для преодоления границ между службами, когда в действительности в них нет необходимости, требуются дополнительные усилия, память и машинные такты. И да, я помню, что последние два дешевы, но первое — нет.
Я предпочитаю доводить деление до того состояния, когда при необходимости легко можно сформировать отдельные службы, но оставлять компоненты в общем адресном пространстве до тех пор, пока это возможно. Это оставляет открытой возможность организации служб.
При таком подходе компоненты первоначально разделяются на уровне исходного кода. Этого может оказаться достаточно для продолжительного развития проекта. Если возникают проблемы с развертыванием или разработкой, разделения до уровня развертывания может быть достаточно — по крайней мере на какое-то время.
По мере накопления проблем с разработкой, развертыванием и эффективной работой я тщательно отбираю единицы развертывания, которые можно преобразовать в службы, и постепенно двигаю систему в этом направлении.
Со временем требования к эффективности работы могут снижаться. И для системы, прежде требовавшей разделения до уровня служб, теперь может оказаться достаточно разделения до уровня развертывания или даже исходного кода.
Хорошая архитектура позволит создать монолитную систему, развертываемую как один файл, а затем превратить ее в набор независимых единиц развертывания и далее в независимые службы и/или микрослужбы. Позднее, когда что-то изменится, она должна позволить обратить все вспять и вновь вернуться к монолитной структуре.
Хорошая архитектура защищает большую часть исходного кода от таких изменений. Она оставляет режим разделения открытым, поэтому для крупномасштабных вариантов развертывания может использоваться один режим, а для мелкомасштабных — другой.
Да, все это непросто. Впрочем, я и не говорю, что изменение режимов разделения должно сводиться к тривиальным изменениям в конфигурации (хотя иногда такое возможно). Я говорю, что режим разделения системы на компоненты относится к числу вариантов, которые, скорее всего, будут изменяться со временем, и хороший архитектор должен предвидеть такие изменения и стремиться к упрощению.
Глава 17. Границы: проведение разделяющих линий
Разработка архитектуры программного обеспечения — это искусство проведения разделяющих линий, которые я называю границами . Границы отделяют программные элементы друг от друга и избавляют их от необходимости знать, что находится по ту сторону. Некоторые из этих линий можно провести на самых ранних этапах развития проекта — даже до появления первого программного кода. Другие проводятся намного позже. Границы, проводимые на ранних этапах, призваны отложить принятие решений на как можно долгий срок и предотвратить загрязнение основной бизнес-логики этими решениями.
Напомню, что целью архитектора является минимизация трудозатрат на создание и сопровождение системы. Что может помешать достижению этой цели? Зависимость — и особенно зависимость от преждевременных решений.
Читать дальше
Конец ознакомительного отрывка
Купить книгу