Erhalten Sie Zugang zu diesem und mehr als 300000 Büchern ab EUR 5,99 monatlich.
В архитектуре программного обеспечения нет простых решений. Напротив, есть масса сложностей — задач и проблем, для решения которых нет готовых ответов и приходится выбирать между различными компромиссами. Эта книга научит вас критически относиться к компромиссам, связанным с распределенными архитектурами. Опытные архитекторы Нил Форд, Марк Ричардс, Прамод Садаладж и Жамак Дехгани обсуждают стратегии выбора архитектуры, подходящей для тех или иных случаев. История Sysops Squad — вымышленной группы специалистов — позволяет исследовать все аспекты выбора архитектуры: от определения степени гранулярности сервисов, управления рабочими процессами и оркестрации, разделения контрактов и управления распределенными транзакциями до оптимизации таких операционных характеристик, как масштабируемость, адаптируемость и производительность.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 496
Veröffentlichungsjahr: 2023
Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:
Переводчик Л. Киселева
Нил Форд, Марк Ричардс , Прамод Садаладж , Жамак Дехгани
Современный подход к программной архитектуре: сложные компромиссы. — СПб.: Питер, 2023.
ISBN 978-5-4461-2024-6
© ООО Издательство "Питер", 2023
Все права защищены. Никакая часть данной книги не может быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав.
Эта книга — долгожданное руководство по созданию микросервисов и анализу нюансов архитектурных решений по всему стеку технологий. Она может служить каталогом архитектурных решений, которые могут приниматься при построении распределенной системы, и описывает плюсы и минусы каждого решения. Ее должен прочитать каждый архитектор, занимающийся созданием современных распределенных систем.
Александар Серафимоски (Aleksandar Serafimoski), ведущий консультант, Thoughtworks
Бесценная книга для технологов, увлеченных разработкой архитектур. Содержит превосходное описание паттернов.
Ванья Сетх (Vanya Seth), руководитель технического отдела, Thoughtworks, Индия
Кем бы вы ни были — начинающим архитектором или опытным руководителем команды, эта книга, обойдясь без словоблудия, расскажет вам, как добиться успеха на пути к созданию корпоративных приложений и микросервисов.
Д-р Венкат Субраманиам (Venkat Subramaniam), обладатель множества наград, автор и основатель Agile Developer, Inc.
Эта книга содержит ценную информацию, практические советы и примеры из реальной жизни, посвященные разделению тесно связанных систем и их повторному созданию. Приобретя навыки эффективного анализа компромиссов, вы начнете принимать более эффективные архитектурные решения.
Йост ван Винен (Joost van Weenen), управляющий партнер и сооснователь Infuze Consulting
Мне очень понравился этот всеобъемлющий труд по распределенным архитектурам! Отличное сочетание серьезного обсуждения, фундаментальных идей и множества практических советов.
Дэвид Клоэт (David Kloet), независимый архитектор программного обеспечения
Разбить большой ком грязи — непростая работа. Начиная с кода и заканчивая данными, эта книга поможет увидеть, какие сервисы следует отделить и сделать независимыми, а какие оставить работать вместе.
Рубен Диас-Мартинес (Rubén Díaz-Martínez), разработчик программного обеспечения в Codesai
Эта книга поможет вам заложить теоретическую и практическую основы и ответить на самые сложные вопросы, возникающие при разработке современных архитектур программного обеспечения.
Джеймс Льюис (James Lewis), технический директор, Thoughtworks
Работая над книгой Fundamentals of Software Architecture1, мы (Нил и Марк) постоянно сталкивались со сложными примерами архитектур, о которых нам очень хотелось рассказать, но которые были слишком трудными. Ни один из них не имел простого решения, и каждый являл собой клубок запутанных компромиссов. Мы сложили эти примеры в стопку, которую назвали «Сложные компромиссы». Как только та книга была закончена, мы посмотрели на эту огромную стопку и попытались выяснить: почему эти проблемы так трудно решить в современных архитектурах?
Мы проработали все примеры как архитекторы, применяя анализ компромиссов для каждой ситуации, а также обращая внимание на процесс, с помощью которого достигались компромиссы. Одним из наших первых открытий стало возрастающее значение данных в архитектурных решениях: кто может/должен иметь доступ к данным, кто может/должен формировать и изменять их и как управлять разделением аналитических и операционных данных. Чтобы это понять, мы пригласили экспертов в указанных областях, что позволило увидеть весь процесс принятия решений с обеих сторон: от архитектуры к данным и от данных к архитектуре.
Результатом стала эта книга: сборник сложных проблем в современной архитектуре программного обеспечения, компромиссов, усложняющих принятие решений, и, наконец, иллюстрированное руководство, показывающее, как применять тот же анализ компромиссов к вашим собственным уникальным задачам.
В этой книге приняты следующие обозначения.
Курсив
Курсивом выделены новые термины и ключевые понятия.
Моноширинный шрифт
Используется для листингов программ, а также внутри абзацев для обозначения таких элементов, как переменные и функции, базы данных, типы данных, переменные среды, операторы и ключевые слова, имена файлов и их расширений.
Моноширинный жирный шрифт
Показывает команды или другой текст, который пользователь должен ввести самостоятельно.
Моноширинный курсив
Показывает текст, который должен быть заменен значениями, введенными пользователем, или значениями, определяемыми контекстом.
Шрифт без засечек
Используется для обозначения URL, адресов электронной почты, названий кнопок, каталогов.
Этот рисунок указывает на совет или предложение.
Вспомогательные материалы (примеры кода, упражнения и т.д.) доступны для скачивания по адресу http://architecturethehardparts.com/.
Если у вас есть вопросы технического характера или возникли проблемы с использованием примеров кода, то присылайте их по адресу [email protected].
В общем случае все примеры кода из книги вы можете использовать в своих программах и в документации. Вам не нужно обращаться в издательство за разрешением, если вы не собираетесь воспроизводить существенные части программного кода. Если вы разрабатываете программу и используете в ней несколько фрагментов кода из книги, вам не нужно обращаться за разрешением. Но для продажи или распространения примеров из книги вам потребуется разрешение от издательства O’Reilly. Вы можете отвечать на вопросы, цитируя данную книгу или примеры из нее, но для включения существенных объемов программного кода из книги в документацию вашего продукта потребуется разрешение.
Мы рекомендуем, но не требуем добавлять ссылку на первоисточник при цитировании. Под ссылкой на первоисточник мы подразумеваем указание авторов, издательства и ISBN.
За получением разрешения на использование значительных объемов программного кода из книги обращайтесь по адресу [email protected].
Мы, Марк и Нил, выражаем благодарность всем, кто посещал наши (почти исключительно онлайн) занятия, семинары, конференции и встречи групп пользователей, а также всем, кто выслушивал наши доклады по данной теме и оставлял бесценные отзывы. Многократное повторное обсуждение нового материала — особенно сложная задача, когда нельзя сделать это вживую, поэтому мы очень ценим усилия всех, кто оставался с нами на протяжении множества итераций. Мы благодарим команду издательства O’Reilly, сделавшую процесс написания книги настолько безболезненным, насколько это возможно. Мы также благодарим отдельные группы, такие как Pasty Geeks и Hacker B&B, являющиеся оазисами здравомыслия и источниками искрометных идей.
Спасибо всем рецензентам нашей книги: Ванье Сетху (Vanya Seth), Венкату Субраманиану (Venkat Subramanian), Йосту ван Винену (Joost van Weenen), Грэди Бучу (Grady Booch), Рубену Диасу (Ruben Diaz), Дэвиду Клоэту (David Kloet), Мэтту Штейну (Matt Stein), Данило Сато (Danilo Sato), Джеймсу Льюису (James Lewis) и Сэму Ньюману (Sam Newman). Ваши знания и отзывы помогли улучшить эту книгу.
Мы хотим выразить особую признательность многим работникам и семьям, пострадавшим от неожиданной глобальной пандемии. Как работники умственного труда, мы столкнулись с неудобствами, которые не выдерживают никакого сравнения с массовыми потрясениями и разрушениями во всех сферах жизни, причиненными многим нашим друзьям и коллегам. Мы особенно сочувствуем и признательны работникам здравоохранения, многие из которых не думали, что когда-нибудь окажутся на переднем крае ужасной глобальной трагедии, но достойно справились с ней. Наша благодарность вам бесконечна.
В дополнение к написанному выше я хочу еще раз поблагодарить мою прекрасную супругу Ребекку (Rebecca) за то, что она терпела, пока я занимался еще одним книжным проектом. Твоя неиссякаемая поддержка и советы помогли мне написать эту книгу, и это притом, что тебе приходилось отвлекаться от работы над собственным романом. Ребекка, ты для меня — целый мир. Я также благодарю моего доброго друга и соавтора Нила Форда. Совместная работа с тобой над этой книгой (и над предыдущей) была по-настоящему ценным и полезным опытом. Ты есть и всегда будешь моим другом.
Я хотел бы поблагодарить свою большую семью: весь коллектив Thoughtworks, а также Ребекку Парсонс (Rebecca Parsons) и Мартина Фаулера (Martin Fowler). Thoughtworks — выдающаяся группа людей, которые создают для клиентов ценные решения, внимательно следят за их работой и выясняют, что еще в них можно улучшить. Компания Thoughtworks во многом поддержала эту книгу и продолжает растить мыслителей, бросающих мне вызов и вдохновляющих меня каждый день. Я также благодарю наш коктейль-клуб, находящийся по соседству, за регулярную возможность сбежать от рутины и в том числе за еженедельные встречи на свежем воздухе, этакие социально дистанцированные версии, которые помогли всем нам пережить пандемию. Я благодарю своего давнего друга Нормана Запиена (Norman Zapien), который постоянно дарит мне приятные беседы. Наконец, спасибо моей жене Кэнди (Candy), благодаря которой у меня есть возможность тратить много времени на такие занятия, как написание книг, а не на уход за нашими кошками.
Я благодарю свою супругу Рупали (Rupali) за поддержку и понимание и моих прекрасных девочек Арулу (Arula) и Архану (Arhana) за воодушевление; папа любит вас обеих. Все, что я делаю, было бы невозможно без клиентов, с которыми я работаю, и различных конференций, помогающих мне проверять и пересматривать идеи и понятия. Я благодарю AvidXchange, последнего клиента, с которым я работаю, за его поддержку и предоставленную возможность проверки новых концепций. Я также благодарю Thoughtworks за постоянную поддержку, а также Нила Форда (Neal Ford), Ребекку Парсонс (Rebecca Parsons) и Мартина Фаулера (Martin Fowler), ставших мне замечательными наставниками; вы помогаете мне стать лучше. Наконец, спасибо моим родителям, особенно моей маме Шобхе (Shobha), по которой я постоянно скучаю. Я очень скучаю по тебе, мама.
Я благодарю Марка и Нила за их приглашение внести свой вклад в эту удивительную книгу. Но это было бы невозможно без постоянной поддержки моего мужа Адриана (Adrian) и терпения моей дочери Арианны (Arianna). Я люблю вас обоих.
Ваши замечания, предложения, вопросы отправляйте по адресу [email protected] (издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.
1Форд Н., Ричардс М. Фундаментальный подход к программной архитектуре: паттерны, свойства, проверенные методы. — СПб.: Питер, 2023.
Многие из нас еще в детстве усвоили, что лучший способ понять, как что-то соединяется, — сначала разобрать это на части. Чтобы разобраться в сложных вопросах (таких как компромиссы в распределенных архитектурах), архитектор должен понять, с чего начать распутывание (untangling)6.
В книге What Every Programmer Should Know About Object-Oriented Design (Dorset House; https://oreil.ly/bLPm4) Мейлир Пейдж-Джонс (Meilir Page-Jones) сделал проницательное наблюдение, что связанность в архитектуре можно разделить на статическую и динамическую. Статическая связанность (static coupling) определяет, как архитектурные части (классы, компоненты, сервисы и т.д.) связаны друг с другом: зависимости, степень связанности, точки сопряжения и т.д. Архитектор часто может измерить статическую связанность во время компиляции, поскольку она представляет статические зависимости в архитектуре.
Динамическая связанность (dynamic coupling) определяет, как архитектурные части вызывают друг друга: как осуществляются взаимодействия, какая информация передается, строгость контрактов и т.д.
Наша цель — исследовать порядок анализа компромиссов в распределенных архитектурах; для этого мы должны разделить движущиеся части, чтобы обсудить их по отдельности и полностью понять их устройство, прежде чем собирать обратно.
Часть I главным образом посвящена архитектурной структуре — статическим связям между компонентами. В главе 2 мы решим задачу определения влияния статической и динамической связанности в архитектурах и представим полную картину, которую должны разобрать, чтобы понять ее. Глава 3 начинает этот процесс, определяя модульность и границы разделения в архитектуре. В главе 4 будут представлены инструменты для оценки и разделения базы кода, а в главе 5 — паттерны, помогающие в этом процессе.
Важность данных и транзакций в архитектуре постоянно растет, вследствие чего архитекторы и администраторы баз данных должны принимать множество компромиссных решений. Глава 6 посвящена влиянию данных на архитектуру и, помимо всего прочего, рассказывает, как согласовать границы сервисов и данных. Наконец, в главе 7 мы свяжем архитектуру с проблемами данных, чтобы определить силы интеграции и дезинтеграции, которые способствуют увеличению или уменьшению размеров сервисов.
6 Употребляя далее термин «архитектурный квант», авторы проводят параллели с квантовой механикой и, в частности, с квантовой запутанностью (это явление, при котором квантовые состояния двух или большего числа объектов оказываются взаимозависимыми). Отсюда употребление в переводе слова «распутывание». Можно интерпретировать как распутывание запутанного клубка компромиссов. — Примеч. пер.
Логан, ведущий архитектор Penultimate Electronics, вмешался в разговор небольшой группы архитекторов, обсуждавших распределенные архитектуры в кафе:
— Остин, ты опять в гипсе?
— Нет, это просто шина, — ответил Остин. — Я растянул запястье, играя в экстремальный диск-гольф на выходных, — оно почти зажило.
— Что это... а впрочем, неважно. Что это за жаркий спор, в который я вмешался?
— Мы обсуждали, стоит ли постоянно выбирать паттерн саги в микросервисных архитектурах, чтобы объединять транзакции, — ответил Остин. — Следуя этой идее, архитекторы могут делать сервисы настолько маленькими, насколько захотят.
— Но разве вместе с сагами не нужно использовать оркестрацию? — спросил Эддисон. — А как быть в случаях, когда взаимодействия должны выполняться асинхронно? И насколько сложными станут транзакции? Если разбить все на слишком мелкие части, то сможем ли мы гарантировать точность данных?
— Знаете, — ответил Остин, — если использовать сервисную шину предприятия (Enterprise Service Bus, ESB), то можно заставить ее управлять всем этим автоматически.
— Я думал, что никто больше не использует ESB. Не лучше ли использовать Kafka?
— Но они даже не одно и то же! — сказал Остин.
Логан прервал разгорающийся спор:
— Это сравнение яблок с апельсинами! Ни один из этих инструментов или подходов не является панацеей. Распределенные архитектуры, такие как микросервисы, сложны, особенно если архитекторы не могут распутать все взаимозависимости. Нам нужны подход или структура, которые помогут разобраться в сложных проблемах нашей архитектуры.
— Что ж, — сказал Эддисон, — в любом случае компоненты должны быть максимально изолированными друг от друга — во всех публикациях, которые я читал, говорится, что архитекторы должны максимально использовать разделение.
— Если вы последуете этому совету, — сказал Логан, — то компоненты окажутся настолько изолированными, что не смогут взаимодействовать между собой, — писать подобные программы очень, очень сложно! Связанность, как и многое другое, по своей сути не является чем-то плохим; архитекторы просто должны знать, как ее применять. Я помню известную цитату одного швейцарского философа...
Всё есть яд, и нет ничего неядовитого; одна лишь дозировка превращает яд в лекарство.
Парацельс
Одна из самых сложных задач, с которыми сталкиваются архитекторы, — распутывание различных взаимозависимостей и компромиссов, действующих в распределенных архитектурах. Люди, дающие советы, постоянно превозносят преимущества слабо связанных систем, но можно ли проектировать системы, в которых ничто ни с чем не связано? Архитекторы проектируют создание небольших микросервисов, чтобы добиться разделения, но в таких архитектурах оркестрация, управление транзакциями и асинхронность превращаются в огромные проблемы. Обобщенно рекомендуется «разделить», но не говорится, как сделать это, чтобы при этом получить полезные системы.
Архитекторы борются с проблемами излишне мелкого дробления и взаимодействий, поскольку не существует четких универсальных рецептов — зарекомендовавших себя решений, которые можно было бы применить к реальным сложным системам. До сих пор у архитекторов не было правильной точки зрения и терминологии, позволяющих провести тщательный анализ, чтобы определить наилучший (или наименее худший) набор компромиссов в каждом конкретном случае.
Почему архитекторам приходилось бороться с проблемами в распределенных архитектурах? В конце концов, распределенные системы создаются еще с прошлого века с помощью почти одних и тех же механизмов (очередей сообщений, событий и т.д.). Почему появление микросервисов настолько увеличило сложность?
Ответ кроется в самой философии микросервисов, основанной на идее ограниченного контекста. Создание сервисов, моделирующих ограниченные контексты, потребовало внести незначительное, но важное изменение в способ проектирования распределенных систем, вследствие чего транзакционность превратилась в архитектурную проблему. Во многих распределенных системах, которые предполагается преобразовать в набор микросервисов, обработчики событий обычно подключаются к одной реляционной базе данных, что позволяет обеспечить целостность данных и поддержку транзакций. Перемещение базы данных в границы сервиса превращает проблемы данных в архитектурные проблемы.
Как уже говорилось выше, архитектура программного обеспечения — то, о чем не расскажет Google. Современные архитекторы должны развивать в себе способность анализировать компромиссы. Конечно, есть несколько фреймворков, существующих уже не одно десятилетие (например, метод анализа компромиссов архитектуры — Architecture Trade-off Analysis Method, ATAM (https://oreil.ly/okbuO)), но они не уделяют достаточно внимания реальным проблемам, с которыми архитекторы сталкиваются ежедневно.
Эта книга рассказывает о том, как архитекторы могут анализировать компромиссы в самых разных сценариях, уникальных для их ситуации. Как и во многом другом в архитектуре, совет прост: самое трудное кроется в деталях, особенно в их сложных переплетениях, что затрудняет обзор и понимание отдельных частей, как показано на рис. 2.1.
Рис. 2.1. Волосы заплетаются в косу, из-за чего отдельные пряди трудно различить
Когда архитекторы рассматривают запутанные проблемы, им сложно анализировать компромиссы, поскольку трудно разделять задачи в целях их рассмотрения независимо друг от друга. Поэтому первый шаг в анализе компромиссов — распутывание проблем, анализ взаимосвязей между частями и определение, как эта взаимосвязанность влияет на изменения. Для этого воспользуемся простейшим определением слова «связанность» (coupling).
Две части программного обеспечения считаются связанными, если изменение одной может потребовать изменения другой.
Часто архитектура ПО создает многомерные проблемы, когда множество факторов действует взаимозависимым образом. Чтобы проанализировать компромиссы, архитектор должен сначала определить, какие силы должны идти на компромисс друг с другом.
Итак, наш совет относительно современного анализа компромиссов в архитектуре ПО звучит так.
1. Найдите части, перепутанные между собой.
2. Проанализируйте, как они связаны друг с другом.
3. Оцените компромиссы, определив влияние изменений на взаимозависимые системы.
Эти шаги кажутся простыми, но не забывайте, что сложности скрываются в деталях. Чтобы проиллюстрировать это на практике, возьмем одну из самых сложных (и, пожалуй, наиболее общих) проблем в распределенных архитектурах, которая связана с микросервисами:
Как архитекторы определяют размеры и стили взаимодействий микросервисов?
Определение надлежащего размера микросервисов кажется распространенной проблемой: слишком маленькие сервисы создают проблемы с транзакциями и оркестрацией, а слишком большие — с масштабированием и распределением.
В оставшейся части этой книги мы распутаем множество аспектов, которые необходимо учитывать при ответе на предыдущий вопрос, предложим новую терминологию для различения похожих, но все же разных паттернов и покажем практические примеры применения этих и других паттернов.
Однако главная цель книги — представить и продемонстрировать на примерах методы, которые помогут вам научиться самостоятельно анализировать компромиссы при решении уникальных проблем в своей области. Итак, начнем наше первое великое распутывание сил в распределенных архитектурах: определим квант архитектуры и два типа связанности, статическую и динамическую.
Термин «квант» широко используется в таком разделе физики, как квантовая механика. И мы выбрали это слово по тем же причинам, что и физики. «Квант» происходит от латинского слова quantus, означающего «сколь велик» или «сколь много». До заимствования физиками это слово использовалось в юриспруденции для представления «требуемой или допустимой суммы» (например, в качестве возмещения убытков). Этот термин также используется в топологии — разделе математики, изучающем свойства семейств фигур.
В архитектуре квант измеряет несколько аспектов, которые относятся к топологии и поведению ПО и связаны с особенностями соединения частей и их взаимодействий друг с другом:
• архитектурный квант — это независимо развертываемый артефакт с высокой функциональной связностью (cohesion)7, высокой статической связанностью (coupling) и синхронной динамической связанностью. Типичный пример архитектурного кванта — правильно сформированный микросервис в рабочем процессе;
• статическая связанность определяется статическими зависимостями, разрешаемыми в архитектуре с помощью контрактов. К числу таких зависимостей относятся операционная система, фреймворки и/или библиотеки, необходимые для транзитивного разрешения зависимостей, а также любые другие операционные требования, необходимые для работы кванта;
• динамическая связанность определяет, как кванты взаимодействуют во время выполнения, синхронно или асинхронно. Следовательно, функции пригодности, проверяющие эти характеристики, должны выполняться непрерывно, например, с помощью мониторов.
Статическая и динамическая связанность кажутся похожими, однако архитекторы должны помнить о двух важных различиях: статическая связанность описывает, как сервисы переплетены друг с другом, а динамическая — как сервисы вызывают друг друга во время выполнения. Например, в архитектуре микросервисов сервис должен содержать зависимые компоненты, такие как база данных, представляющие статическую связанность, — без необходимых данных сервис не сможет работать. Этот сервис может вызывать другие сервисы в процессе выполнения, и эти вызовы образуют динамическую связанность. Для работы ни одного из сервисов не требуется присутствия другого, за исключением данного рабочего процесса. Таким образом, статическая связанность определяет операционные зависимости, а динамическая — коммуникационные.
Эти определения включают важные характеристики; подробно рассмотрим каждую из них, так как они используются во многих примерах в книге.
Возможность независимого развертывания подразумевает несколько аспектов архитектурного кванта — каждый квант представляет собой модуль, развертываемый отдельно в рамках конкретной архитектуры. Соответственно, монолитная архитектура, развернутая как единое целое, по определению представляет собой единый архитектурный квант. В распределенной архитектуре, например в микросервисной, разработчики стремятся развертывать сервисы независимо, часто прибегая к использованию автоматизированных конвейеров. Таким образом, с точки зрения независимого развертывания сервис в архитектуре микросервисов — это архитектурный квант (в зависимости от связанности, как будет показано далее).
Превращение каждого архитектурного кванта в развертываемый ресурс служит нескольким полезным целям. Во-первых, граница, представленная архитектурным квантом, служит полезным общим языком для архитекторов, разработчиков и операторов. Каждый понимает общую область применения: архитекторы понимают характеристики связанности, разработчики — функциональную область, а операторы — характеристики развертывания.
Во-вторых, архитектурный квант — одна из сил (статическая связанность), которую архитекторы должны учитывать, стремясь получить надлежащее разделение на сервисы в распределенной архитектуре. Часто в микросервисных архитектурах разработчики сталкиваются со сложной проблемой выбора степени детализации сервисов, дающей оптимальный набор компромиссов. Некоторые из этих компромиссов касаются возможности развертывания: как часто должны выпускаться новые версии этого сервиса, на какие другие сервисы может быть оказано влияние, какие инженерные методы задействованы и т.д. Архитекторам выгодно четко понимать, где именно проходят границы развертывания в распределенных архитектурах. Детализацию сервисов и связанные с этим компромиссы мы обсудим в главе 7.
В-третьих, возможность независимого развертывания заставляет архитектурный квант включать в себя общие точки сопряжения, такие как базы данных. В большинстве дискуссий об архитектуре ради удобства игнорируются такие вопросы, как базы данных и пользовательские интерфейсы, но эти проблемы часто приходится решать в реальных системах. Соответственно, любая система, использующая общую базу данных, не удовлетворяет критериям квантования архитектуры с точки зрения независимости развертывания, если только развертывание базы данных не является обязательным этапом развертывания приложения. Многие распределенные системы, которые иначе могли бы состоять из множества квантов, терпят неудачу в организации независимого развертывания из-за того, что используют общую базу данных, имеющую собственную частоту развертывания. Таким образом, анализ одних лишь границ развертывания не является исключительно полезной мерой. Чтобы провести разумные границы архитектурного кванта, архитекторы должны также учитывать второй критерий — высокую функциональную связность.
Под высокой функциональной связностью (high functional cohesion) подразумевается близость связанных элементов: классов, компонентов, сервисов и т.д. В ходе исторического развития ученые-информатики определяли множество типов связности, ограничиваясь в данном случае понятием модуля, который может быть представлен в виде класса или компонента, в зависимости от платформы. С точки зрения предметной области техническое определение высокой функциональной связности пересекается с целями ограниченного контекста в предметно-ориентированном проектировании: код и данные, реализующие рабочий процесс в конкретной предметной области.
С точки зрения возможности независимого развертывания гигантская монолитная архитектура квалифицируется как архитектурный квант. Тем не менее она почти наверняка не отличается высокой функциональной связностью и скорее лишь включает в себя функциональность всей системы. Чем больше монолит, тем ниже вероятность, что он действительно имеет высокую функциональную связность.
В идеале в архитектуре микросервисов каждый сервис моделирует одну предметную область или рабочий процесс и, следовательно, демонстрирует высокую функциональную связность. Связность в этом контексте заключается не в том, как сервисы взаимодействуют для выполнения работы, а скорее в том, насколько они независимы и связаны друг с другом.
Тесная статическая связанность подразумевает тесную связь элементов внутри архитектурного кванта, что на самом деле является аспектом контрактов. Архитекторы считают контрактами такие вещи, как REST или SOAP, но сигнатуры методов и операционные зависимости (через точки сопряжения, такие как IP-адреса или URL) тоже представляют собой контракты. Соответственно, контракты тоже являются сложным компромиссом архитектуры; вопросы связанности, имеющие отношение ко всем типам контрактов, в том числе выбор подходящих контрактов, мы рассмотрим в главе 13.
Архитектурный квант частично выступает мерой статической связанности, и эта мера довольно проста для большинства архитектурных топологий. Например, на следующих диаграммах показаны архитектурные стили, представленные в книге Fundamentals of Software Architecture8, иллюстрирующие статическую связанность в архитектурном кванте.
Любой из стилей монолитной архитектуры обязательно будет иметь один квант, как показано на рис. 2.2.
Рис. 2.2. Монолитные архитектуры сами являются квантами
Как видите, любая архитектура, развертываемая как единое целое и использующая единую базу данных, всегда будет иметь единственный квант. Квантовая мера статической связанности в архитектуре включает базу данных, а система, основанная на одной базе данных, не может иметь более одного кванта. Соответственно, квантовая мера статической связанности помогает определить точки сопряжения во всей архитектуре, а не только в разрабатываемых программных компонентах. Большинство монолитных архитектур содержат единственную точку сопряжения (как правило, базу данных), что делает ее квантовую меру равной единице.
Распределенные архитектуры часто имеют развязку на уровне компонентов; рассмотрим еще один набор архитектурных стилей, начав с сервисно-ориентированной архитектуры, показанной на рис. 2.3.
Рис. 2.3. Архитектурный квант сервисно-ориентированной архитектуры
Эта модель, состоящая из отдельных сервисов, демонстрирует изоляцию, характерную для микросервисов, однако сама архитектура по-прежнему использует единую реляционную базу данных, что делает ее квантовую меру равной единице.
Сервисно-ориентированная архитектура
Говоря о сервисно-ориентированной архитектуре, мы имеем в виду не архитектуру вообще, основанную на сервисах, а скорее особый гибридный архитектурный стиль, следующий распределенной многоуровневой структуре, которая состоит из отдельно развернутого пользовательского интерфейса, отдельно развернутых удаленных сервисов и монолитной базы данных. Эта архитектура решает одну из проблем, свойственных микросервисам, — разделение на уровне базы данных. Сервисы в сервисно-ориентированной архитектуре следуют тем же принципам, что и микросервисы (на основе ограниченного контекста в предметно-ориентированном проектировании), но полагаются на единую реляционную базу данных, поскольку архитекторы не видели смысла в ее разделении (или видели слишком много негативных компромиссов).
Сервисно-ориентированные архитектуры часто используются при реструктуризации монолитных архитектур, так как позволяют выполнить декомпозицию, не изменяя существующие схемы баз данных и точки интеграции. Подробнее о паттернах декомпозиции мы поговорим в главе 5.
До сих пор мера статической связанности архитектурного кванта оценивала все топологии как единичные. Однако распределенные архитектуры создают возможность появления множества квантов, хотя и не гарантируют этого. Например, модель, реализующая архитектурный стиль «Посредник» (Mediator) и управляемая событиями, всегда будет оцениваться в качестве единственного кванта, как показано на рис. 2.4.
Рис. 2.4. Модель, управляемая событиями и реализующая архитектурный стиль Посредник (Mediator), имеет единственный архитектурный квант