Подпишитесь на официальный аккаунт WeChat «Front-End Backward», и вы получите серию «Оригинальных» высококачественных технических статей по темам, включая, помимо прочего, интерфейс, Node.js и серверные технологии.
Эта статья была впервые опубликована вayqy.net, оригинальная ссылка:www.ayqy.net/blog/Микросервисная архитектура (…
Ноль. Начните с монолитного приложения
Monolith means composed all in one piece. The Monolithic application describes a single-tiered software application in which different components combined into a single program from a single platform.
(взято изIntroduction to Monolithic Architecture and MicroServices Architecture)
Объединение различных компонентов программного приложения в одну программу называется монолитным приложением. Например, приложение разделено на классы, функции и пространства имен по основным функциям языка программирования, конвейер развертывания используется для проверки изменений перед их развертыванием в производственной среде, а несколько экземпляров запускаются под нагрузкой. балансировочный механизм для их горизонтального масштабирования. :
All your logic for handling a request runs in a single process, allowing you to use the basic features of your language to divide up the application into classes, functions, and namespaces. With some care, you can run and test the application on a developer's laptop, and use a deployment pipeline to ensure that changes are properly tested and deployed into production. You can horizontally scale the monolith by running many instances behind a load-balancer.
В этом архитектурном паттерне приложение тоже работает хорошо, но есть 2 проблемы:
-
Изменения ограничены: небольшое изменение требует пересборки и развертывания всего приложения, и трудно контролировать объем изменений.
-
Плохо для масштабирования: вы не можете масштабировать только те части вашего приложения, которым требуется больше ресурсов, вы можете масштабировать только все приложение целиком.
Эти ограничения особенно заметны в облачных средах. Итак, микросервисная архитектура вышла на сцену
1. Что такое микросервисная архитектура?
Микросервисы — это метод разработки программного обеспечения — вариант архитектурного стиля сервис-ориентированной архитектуры (SOA), который структурирует приложение как набор слабо связанных сервисов.В микросервисной архитектуре сервисы детализированы, а протоколы — легковесны.
(взято изMicroservices)
Вариант сервис-ориентированной архитектуры (SOA), в котором приложение проектируется как серия слабо связанных мелкомодульных сервисов, организованных с помощью облегченных коммуникационных протоколов.
Building applications as suites of services. As well as the fact that services are independently deployable and scalable, each service also provides a firm module boundary, even allowing for different services to be written in different programming languages. They can also be managed by different teams.
В частности, приложение построено как набор небольших сервисов.Эти сервисы можно развертывать и масштабировать независимо друг от друга, каждый с четкой границей модуля, даже позволяя писать разные сервисы на разных языках программирования и управлять ими разными командами.
Микросервисы и SOA
Service-oriented architecture (SOA) is a style of software design where services are provided to the other components by application components, through a communication protocol over a network.
(взято изService-oriented architecture)
В SOA услуги предоставляются компонентами приложений другим компонентам через сетевые коммуникационные протоколы. следовательно,Микросервисная архитектура — это вариант SOA или особый случай, относящийся к структуре SOA, которая удовлетворяет определенным характеристикам.
2. 9 характеристик микросервисной архитектуры
Компонентизация через сервисы
Компоненты можно понимать как программные единицы, которые можно независимо заменять и обновлять. Ряд компонентов соединен вместе, чтобы сформировать программную систему, точно так же, как то, что мы видим в физическом мире:
Our definition is that a component is a unit of software that is independently replaceable and upgradeable. There's been a desire to build systems by plugging together components, much in the way we see things are made in the physical world.
В микросервисной архитектуре компонент — это сервис., обмениваться данными с помощью таких механизмов, как запросы веб-службы или RPC. Этот компонентный подход к гранулярности обслуживания имеет два преимущества:
-
Сервисы могут быть развернуты независимо
-
Сервис имеет явный внешний интерфейс (PublishedInterface)
Независимое развертывание означает, что для внутренних изменений в службе требуется только повторное развертывание службы, а несколько служб необходимо изменять совместно, когда затрагиваются изменения интерфейса службы. С другой стороны, также можно свести к минимуму такие связи за счет эволюции границ обслуживания и протоколов обслуживания.
Явный внешний интерфейс является сильным ограничением, которое может обеспечить инкапсуляцию компонентов и избежать чрезмерной тесной связи между компонентами.
Но RPC имеет более высокую производительность, чем внутрипроцессные вызовы, поэтому интерфейсы RPC в основном являются неструктурированными и часто более сложными в использовании. С другой стороны, если вы хотите настроить обязанности компонентов, стоимость рефакторинга также выше.
Организация команд вокруг бизнес-возможностей
Микросервисы позволяют разбить систему на ряд сервисов, основанных на бизнес-функциях, поэтому межфункциональные группы могут быть организованы вокруг бизнес-функций. И этоОрганизационная структура также помогает укрепить границы обслуживания:
[Не удалось передать изображение по внешней ссылке, исходный сайт может иметь механизм защиты от пиявки, рекомендуется сохранить изображение и загрузить его напрямую (img-8rxLM9xU-1577238129023) (Мартин Фаулер.com/articles/m…)]
Согласно закону P.S. Конвея, структура дизайна в конечном итоге будет соответствовать структуре коммуникации организации:
Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure. -- Melvyn Conway, 1967
Интересным примером того, как коммуникационная структура меняет структуру дизайна, является ситуация, когда некоторые команды втискивают логику в приложения, которыми они могут управлять., чтобы избежать затрат на связь при совместной работе между командами:
A smart team will optimise around this and plump for the lesser of two evils - just force the logic into whichever application they have access to.
По сравнению с разделением команд по бизнес-направлениям в монолитном приложении границы услуг более четкие и обязательные. Потому что легко иметь бизнес-функции, которые пересекают границы модулей, в то время как границы служб относительно стабильны.
Продукты, а не проекты
Микросервисная архитектура имеет тенденцию поддерживать/развивать продукт в течение длительного времени собственной командой разработчиков, а не передавать его другой группе поддержки после завершения проекта:
Microservice proponents tend to avoid this model, preferring instead the notion that a team should own a product over its full lifetime.
Эта философия продукта создает непрерывные отношения между командой разработчиков и пользователем, позволяя команде разработчиков сосредоточиться на том, как программное обеспечение может помочь пользователям улучшить бизнес-функциональность:
There is an on-going relationship where the question is how can software assist its users to enhance the business capability.
Умные конечные точки и тупые каналы
С точки зрения механизма связи типичным примером является корпоративная служебная шина.Сообщения проходят через ESB.ESB отвечает за маршрутизацию сообщений, оркестровку, преобразование и применение бизнес-правил, а затем достигает конечных точек для обработки. В этом режиме конечные точки могут оставаться надежными, поскольку большая часть логики обрабатывается в конвейере сообщений ESB. Так что назовите это умными каналами и тупыми конечными точками.
Микросервисы, как правило, делают противоположное, умные конечные точки и тупые каналы:
That the lanes of communication should be stripped of business processing and logic and should literally only distribute messages between components. It's then the components themselves that do processing / logic / validation etc... on those messages.
который,Конвейер отвечает только за распространение сообщений между компонентами, а сама служба соответствующим образом обрабатывает сообщения.
Децентрализованное управление
Самая большая проблема с централизованным управлением технологиями — это его ограничения.Единый стек технологий может подходить не для всех сценариев:
Experience shows that this approach is constricting - not every problem is a nail and not every solution a hammer, we prefer using the right tool for the job.
В контексте микросервисовКаждая услуга строится индивидуально, что дает возможность выбрать другой стек технологий, позволяя более подходящим инструментам делать разные вещи. Эта свобода в стеке технологий помогает сервисам развиваться независимо и естественным образом выбирать лучшие модели.
Конечно, «раньше у меня не было выбора, а теперь я могу» не означает, что сто цветов — это хорошо, ведь затраты на поддержание различных технологических экосистем могут быть выше, чем выгоды:
Мы не получаем 20 разных языков в одной системе, потому что каждый из них самоуверен и привносит свое видение внутри системы, поддержание разных экосистем очень дорого и потенциально запутанно, не обеспечивая слишком много преимуществ.
В качестве компромисса мы можем ограничить наш выбор определенными технологическими стеками вместо того, чтобы быть строго привязанными к одному технологическому стеку:
But a trade-off could help out, having a limited list of languages or frameworks we can pick from can really help. Suddenly, we are not tightly coupled with one stack only.
Децентрализованное управление данными
На самом абстрактном уровне децентрализация управления данными означает, что каждая система имеет разные концептуальные модели объективного мира. Например, клиенты в глазах продавцов и разработчиков понимают по-разному, одна и та же концепция может также иметь тонкие различия в двух точках зрения.
Эффективной мерой для решения этой ситуации является ограниченный контекст в предметно-ориентированном проектировании:
Контекст, к которому применяется модель, должен быть явно определен. Границы также должны быть четко установлены с точки зрения организации команды, использования определенных частей приложения и физических представлений, таких как кодовые базы и схемы баз данных. Необходимо поддерживать строгую согласованность модели в границах, не подвергаясь влиянию и возмущению внешних проблем.
(взято изПервый взгляд на ограниченный контекст)
То есть концепты модели определяются контекстом, в котором гарантируется их строгое соответствие. Разделите сложное поле на несколько ограниченных контекстов, а затем наметьте связи между ними, т. е.Децентрализация на уровне концептуальной модели:
DDD divides a complex domain up into multiple bounded contexts and maps out the relationships between them.
В отношении хранения данных микросервисы также реализуют аналогичную стратегию децентрализации.Пусть каждый сервис управляет своей собственной базой данных. Эти базы данных могут быть разными экземплярами одной и той же базы данных или совершенно разными системами баз данных, называемымиГибридная настойчивость:
Microservices prefer letting each service manage its own database, either different instances of the same database technology, or entirely different database systems - an approach called Polyglot Persistence.
P.S. Для проблемы непротиворечивости данных, вызванной децентрализованным хранением данных, можно рассмотреть некоторые компенсационные операции, чтобы сделать данные окончательно непротиворечивыми.Starbucks Does Not Use Two-Phase Commit
Автоматизация инфраструктуры
Развертывание микросервисов немного сложнее, чем монолитное приложение. Потому что в сложной сетевой среде развертывание нескольких служб сложнее, чем развертывание отдельного приложения:
Однако развитие облачных вычислений сделало возможной автоматизацию инфраструктуры, значительно уменьшив сложность создания, развертывания, эксплуатации и обслуживания сервисов, что позволило нам использовать автоматизацию инфраструктуры для обеспечения управления микросервисами в производственных средах.
Дизайн для отказа
В контексте микросервисов важнее отказоустойчивый дизайн клиента:
A consequence of using services as components, is that applications need to be designed so that they can tolerate the failure of services. Any service call could fail due to unavailability of the supplier, the client has to respond to this as gracefully as possible.
Дополнительная сложность этой отказоустойчивой конструкции является недостатком по сравнению с монолитным приложением.
С другой стороны, чтобы быстро обнаруживать точки сбоя и даже максимально автоматически восстанавливать сервисы, мониторинг в реальном времени особенно важен в микросервисных архитектурах.
P.S. Дополнительную информацию об отказоустойчивом дизайне см.Fault Tolerance in a High Volume, Distributed System
Эволюционный дизайн
Разделение компонентов имеет решающее значение в микросервисной архитектуре и связано с тем, можно ли уменьшить количество изменений. Общий принцип заключается в том, можно ли самостоятельно заменить и модернизировать компонент:
The key property of a component is the notion of independent replacement and upgradeability.
Однако, с другой точки зрения,Управление изменениями не обязательно означает сокращение изменений, также является отличным средством контроля, позволяющим гарантировать, что эти изменения вносятся так быстро, как ожидалось.
Change control doesn't necessarily mean change reduction - with the right attitudes and tools you can make frequent, fast, and well-controlled changes to software.
Используйте возможности декомпозиции сервисов, предоставляемые микросервисной архитектурой, в качестве инструмента для достижения контроля над изменениями детализации сервисов:
-
Ожидается, что некоторые услуги устареют в будущем и не должны развиваться в долгосрочной перспективе.
-
Поместите вещи, которые меняются одновременно, в одну и ту же службу, а части, которые редко меняются, в отдельные службы, отдельно от частей, которые меняются часто.
3. Ключевые проблемы микросервисной архитектуры
первый,Точно определить границы компонентов непросто:
It's hard to figure out exactly where the component boundaries should lie.
Таким образом, эволюционный дизайн — это следующая лучшая вещь, упрощающая рефакторинг границ (снижает затраты на пробы и ошибки):
Evolutionary design recognizes the difficulties of getting boundaries right and thus the importance of it being easy to refactor them. But when your components are services with remote communications, then refactoring is much harder than with in-process libraries.
С другой стороны, если дизайн плохой, делать это простоПереносит сложность внутри компонентов на связи между компонентами, что затрудняет контроль:
Another issue is If the components do not compose cleanly, then all you are doing is shifting complexity from inside a component to the connections between components. Not just does this just move complexity around, it moves it to a place that's less explicit and harder to control.
Вполне возможна ситуация, когда один простой сервис выглядит хорошо внутри, но игнорируются беспорядочные связи между сервисами:
It's easy to think things are better when you are looking at the inside of a small, simple component, while missing messy connections between services.