Распределенные системы. Паттерны проектирования - [21]
Надо отметить, что паттерны проектирования предназначены не только для их непосредственного применения в приложениях, но и для развития сообществ, участники которых могут взаимо-действовать между собой и делиться результатами. Часть II
Паттерны
проектирования обслуживающих систем В предыдущей главе мы рассмотрели паттерны группирования наборов контейнеров, совместно исполняемых на одной ма-шине. Подобные группы представляют собой тесно связанные, симбиотические системы. Они зависят от совместно исполь-зуемых локальных ресурсов: дискового пространства, сетевых интерфейсов, а также от межпроцессного взаимодействия. Та-кие наборы контейнеров являются не только важными паттер-нами, но и строительными блоками для более крупных систем. Требования к надежности, масштабируемости, разделению обязанностей обуславливают то, что реальные системы состоят из множества различных компонентов, развернутых на многих машинах. Компоненты в многоузловых паттернах связаны сла-бее, чем в одноузловых. Хотя эти паттерны и диктуют схему взаимодействия компонентов между собой, само взаимодей-ствие осуществляется через сетевые вызовы. Кроме того, па-раллельно выполняется множество вызовов, координируемых путем нестрогой синхронизации, а не с помощью ограничений реального времени.
Введение в микросервисы
С недавних пор термин «микросервисы» стал модным словеч-ком, описывающим системы с многоузловыми распределен-ными архитектурами. Микросервисами называются системы, созданные из множества разных компонентов, работающих в разных процессах и взаимодействующих посредством за-ранее определенных программных интерфейсов. Микросер-висы противопоставляются монолитным системам, которые Часть II. Паттерны проектирования обслуживающих систем 79 сосредотачивают функциональность сервиса в одном строго скоординированном приложении. Эти два подхода изображены на рис. II.1 и II.2.
Рис. II.1. Монолитный сервис, вся функциональность которого сосредоточена в одном контейнере
Рис. II.2. Микросервисная архитектура, в которой под каждую функцию выделяется отдельный контейнер
Микросервисный подход имеет немало преимуществ, многие из которых связаны с надежностью и гибкостью. Микросервисы делят приложение на небольшие части, каждая из которых от-вечает за предоставление определенной услуги. За счет сужения 80 Часть II. Паттерны проектирования обслуживающих систем области действия сервисов каждый сервис в состоянии разра-батывать и поддерживать команда, которую можно накормить двумя пиццами> 1 . Уменьшение размера команды также снижает расходы на поддержание ее деятельности.
Кроме того, появление формального интерфейса между микросер-висами ослабляет взаимозависимость команд и устанавливает на-дежный контракт между сервисами. Такой формальный контракт снижает потребность в тесной синхронизации команд, поскольку команда, предоставляющая API, понимает, в каком объеме необхо-димо обеспечивать совместимость, а команда, потребляющая API, может рассчитывать на стабильное обслуживание, не заботясь о деталях реализации потребляемого сервиса. Такая декомпозиция позволяет командам независимо управлять темпом разработки и графиком выпуска новых версий, что дает им возможность вы-полнять итерации, улучшая тем самым код сервиса. Наконец, разделение на микросервисы повышает масштаби-руемость. Поскольку каждый компонент выделен в отдельный сервис, его можно масштабировать независимо от остальных. Нечасто случается так, что все сервисы в рамках более крупного приложения развиваются в одном темпе и масштабируются оди-наковым образом. Некоторые системы не имеют внутреннего состояния, и их можно масштабировать горизонтально, в то же время в других системах оно есть и требует шардирования или других подходов к масштабированию. Когда сервисы отделены друг от друга, каждый из них можно масштабировать наиболее подходящим способом. Это невозможно, когда все сервисы яв-ляются частями большого монолитного приложения. Микросервисный подход к проектированию систем, безусловно, имеет и свои недостатки. Два наиболее очевидных недостатка Часть II. Паттерны проектирования обслуживающих систем 81 состоят в том, что связи внутри системы становятся слабее, а значит, отладка системы в случае отказа становится намного сложнее. Больше не получится загрузить в отладчик одно при-ложение и выяснить, что идет не так. Любая ошибка оказыва-ется следствием того, что большое количество систем работает на большом количестве машин. Такую среду сложно воспроиз-вести в отладчике. Неизбежным итогом этого является также и то, что микросервисные системы сложно проектировать и от-лаживать. Системы, основанные на микросервисах, используют различные способы и схемы взаимодействия между сервисами (синхронный, асинхронный, передача сообщений и т. п.), а так-же множество различных паттернов координации и управления сервисами.
Эти проблемы обуславливают потребность в распределенных паттернах. Когда микросервисная архитектура состоит из хо-рошо известных паттернов, ее проще проектировать, поскольку многие принципы проектирования уже закодированы в паттер-нах. Кроме того, паттерны упрощают отладку систем, поскольку позволяют разработчикам применять опыт, полученный при отладке других систем, спроектированных с использованием таких же паттернов.