Проектирование ориентированного на микрослужбы приложенияDesign a microservice-oriented application

В этом разделе рассматривается разработка гипотетического серверного корпоративного приложения.This section focuses on developing a hypothetical server-side enterprise application.

Спецификации приложенияApplication specifications

Это гипотетическое приложение обрабатывает запросы путем выполнения бизнес-логики, обращения к базам данных и последующего возврата ответов HTML, JSON или XML.The hypothetical application handles requests by executing business logic, accessing databases, and then returning HTML, JSON, or XML responses. Мы хотим сказать, что приложение должно поддерживать различные клиенты, включая браузеры рабочего стола, в которых работают одностраничные приложения (SPA), классические веб-приложения, мобильные веб-приложения и собственные мобильные приложения.We will say that the application must support various clients, including desktop browsers running Single Page Applications (SPAs), traditional web apps, mobile web apps, and native mobile apps. Приложение также может предоставлять интерфейс API для использования третьими лицами.The application might also expose an API for third parties to consume. Также должна быть предусмотрена возможность асинхронной интеграции его микрослужб или внешних приложений, поскольку такой подход помогает повысить устойчивость микрослужб в случае частичных сбоев.It should also be able to integrate its microservices or external applications asynchronously, so that approach will help resiliency of the microservices in the case of partial failures.

Приложение будет состоять из следующих типов компонентов.The application will consist of these types of components:

  • Компоненты уровня представления.Presentation components. Они отвечают за обработку пользовательского интерфейса и использование удаленных служб.These components are responsible for handling the UI and consuming remote services.

  • Логика предметной области или бизнес-логика.Domain or business logic. Это логика домена приложения.This component is the application's domain logic.

  • Логика доступа к базе данных.Database access logic. Сюда входят компоненты доступа к данным, обеспечивающие доступ к базам данных (SQL или NoSQL).This component consists of data access components responsible for accessing databases (SQL or NoSQL).

  • Логика интеграции приложений.Application integration logic. Сюда входит канал обмена сообщениями, построенный на брокерах сообщений.This component includes a messaging channel, based on message brokers.

Приложению потребуется высокая степень масштабируемости, при этом его вертикальные подсистемы должны иметь возможность автономной масштабируемости, так как одним подсистемам будет требоваться более высокая степень масштабируемости, чем другим.The application will require high scalability, while allowing its vertical subsystems to scale out autonomously, because certain subsystems will require more scalability than others.

Должна быть предусмотрена возможность развертывания приложения в нескольких инфраструктурных средах (в общедоступных облачных и локальных средах), и желательно, чтобы это приложение было кроссплатформенным, способным легко перемещаться с Linux на Windows (или наоборот).The application must be able to be deployed in multiple infrastructure environments (multiple public clouds and on-premises) and ideally should be cross-platform, able to move from Linux to Windows (or vice versa) easily.

Контекст команды разработчиковDevelopment team context

Также предполагаются следующие особенности процесса разработки для приложения.We also assume the following about the development process for the application:

  • Имеется несколько команд разработчиков, работающих над разными областями приложения.You have multiple dev teams focusing on different business areas of the application.

  • Новые члены команд должны быстро включаться в работу, и приложение должно быть простым для понимания и легко модифицируемым.New team members must become productive quickly, and the application must be easy to understand and modify.

  • Приложение будет иметь долгий срок развития и постоянно меняющиеся бизнес-правила.The application will have a long-term evolution and ever-changing business rules.

  • Вам потребуется хорошая долгосрочная поддержка, что означает гибкость при реализации будущих изменений и возможность обновления нескольких подсистем с минимальным воздействием на другие подсистемы.You need good long-term maintainability, which means having agility when implementing new changes in the future while being able to update multiple subsystems with minimum impact on the other subsystems.

  • Вы хотите реализовать непрерывную интеграцию и непрерывное развертывание приложения.You want to practice continuous integration and continuous deployment of the application.

  • Вы хотите использовать преимущества новых технологий (платформы, языки программирования и т. д.) при развитии приложения.You want to take advantage of emerging technologies (frameworks, programming languages, etc.) while evolving the application. Вы не хотите, чтобы при переходе на новые технологии приходилось выполнять полную миграцию приложения, так как это может вызвать высокие затраты и повлиять на предсказуемость и стабильность работы приложения.You do not want to make full migrations of the application when moving to new technologies, because that would result in high costs and impact the predictability and stability of the application.

Выбор архитектурыChoosing an architecture

Какой должна быть архитектура развертывания приложения?What should the application deployment architecture be? Спецификации для приложения наряду с контекстом разработки дают веские основания предположить, что следует конструировать приложение путем его разделения на автономные подсистемы в виде совместно работающих микрослужб и контейнеров, где микрослужба представляет собой контейнер.The specifications for the application, along with the development context, strongly suggest that you should architect the application by decomposing it into autonomous subsystems in the form of collaborating microservices and containers, where a microservice is a container.

При таком подходе каждая служба (контейнер) реализует набор целостных и тесно связанных функций.In this approach, each service (container) implements a set of cohesive and narrowly related functions. Например, приложение может состоять из таких служб, как служба каталога, служба заказов, служба корзины, служба профилей пользователей и т. п.For example, an application might consist of services such as the catalog service, ordering service, basket service, user profile service, etc.

Микрослужбы взаимодействуют с помощью протоколов, таких как HTTP (REST), но также и по возможности асинхронно (например, с помощью AMQP), особенно при распространении обновлений с помощью событий интеграции.Microservices communicate using protocols such as HTTP (REST), but also asynchronously (for example, using AMQP) whenever possible, especially when propagating updates with integration events.

Микрослужбы разрабатываются и разворачиваются как контейнеры, независимо друг от друга.Microservices are developed and deployed as containers independently of one another. Это означает, что команда разработчиков может разрабатывать и разворачивать определенную микрослужбу, не затрагивая другие подсистемы.This approach means that a development team can be developing and deploying a certain microservice without impacting other subsystems.

Каждая микрослужба имеет собственную базу данных, что позволяет ей быть полностью отделенной от других микрослужб.Each microservice has its own database, allowing it to be fully decoupled from other microservices. При необходимости согласованность между базами данных разных микрослужб достигается с помощью событий интеграции уровня приложения (через шину логических событий), которые обрабатываются в CQRS.When necessary, consistency between databases from different microservices is achieved using application-level integration events (through a logical event bus), as handled in Command and Query Responsibility Segregation (CQRS). Из-за этого бизнес-ограничения должны учитывать итоговую согласованность между несколькими микрослужбами и связанными базами данных.Because of that, the business constraints must embrace eventual consistency between the multiple microservices and related databases.

eShopOnContainers: эталонное приложение для .NET и микрослужб, развернутых с использованием контейнеровeShopOnContainers: A reference application for .NET and microservices deployed using containers

Чтобы вы могли сосредоточиться на архитектуре и технологиях и не думать о гипотетической области бизнеса, в которой вы можете не разбираться, мы выбрали хорошо известную область бизнеса, а именно упрощенное приложение электронной коммерции (интернет-магазин), которое представляет каталог продукции, принимает заказы от клиентов, проверяет запасы и выполняет другие бизнес-функции.So that you can focus on the architecture and technologies instead of thinking about a hypothetical business domain that you might not know, we have selected a well-known business domain—namely, a simplified e-commerce (e-shop) application that presents a catalog of products, takes orders from customers, verifies inventory, and performs other business functions. Исходный код этого приложения на основе контейнеров можно найти в репозитории GitHub eShopOnContainers.This container-based application source code is available in the eShopOnContainers GitHub repo.

Приложение состоит из нескольких подсистем, в том числе нескольких внешних пользовательских интерфейсов магазина (веб-приложения и собственного мобильного приложения), а также внутренних микрослужб и контейнеров для всех необходимых серверных операций с несколькими шлюзами API в качестве консолидированных точек входа во внутренние микрослужбы.The application consists of multiple subsystems, including several store UI front ends (a Web application and a native mobile app), along with the back-end microservices and containers for all the required server-side operations with several API Gateways as consolidated entry points to the internal microservices. На рис. 6-1 показана архитектура этого эталонного приложения.Figure 6-1 shows the architecture of the reference application.

Схема клиентских приложений, использующих eShopOnContainers в одном узле Docker.

Рис. 6-1.Figure 6-1. Архитектура эталонного приложения eShopOnContainers для среды разработкиThe eShopOnContainers reference application architecture for development environment

На схеме выше показано, что мобильные клиенты и клиенты SPA обмениваются данными с конечными точками одного шлюза API, который, в свою очередь, взаимодействует с микрослужбами.The above diagram shows that Mobile and SPA clients communicate to single API gateway endpoints, that then communicate to microservices. Традиционные веб-клиенты обмениваются данными с микрослужбой MVC, которая взаимодействует с микрослужбами через шлюз API.Traditional web clients communicate to MVC microservice, that communicates to microservices through the API gateway.

Среда размещения.Hosting environment. На рис. 6-1 вы видите несколько контейнеров, развернутых в одном узле Docker.In Figure 6-1, you see several containers deployed within a single Docker host. Этого можно добиться, выполнив развертывание на один узел Docker с помощью команды docker-compose up.That would be the case when deploying to a single Docker host with the docker-compose up command. Однако если вы используете оркестратор или контейнерный кластер, каждый контейнер может работать на другом узле, и на любом узле может выполняться любое количество контейнеров, как описывалось ранее в разделе, посвященном архитектуре.However, if you are using an orchestrator or container cluster, each container could be running in a different host (node), and any node could be running any number of containers, as we explained earlier in the architecture section.

Архитектура взаимодействия.Communication architecture. В приложении EShopOnContainers используются два типа взаимодействия, в зависимости от вида функционального действия (запросы или обновления и транзакции).The eShopOnContainers application uses two communication types, depending on the kind of the functional action (queries versus updates and transactions):

  • Связь по протоколу HTTP между клиентом и микрослужбой через шлюзы API.Http client-to-microservice communication through API Gateways. Такое взаимодействие используется для запросов и при получении обновлений или команд транзакций от клиентских приложений.This approach is used for queries and when accepting update or transactional commands from the client apps. Использование шлюзов API подробно описано в следующих разделах.The approach using API Gateways is explained in detail in later sections.

  • Асинхронное взаимодействие на основе событий.Asynchronous event-based communication. Такое взаимодействие осуществляется через шину событий для распространения обновлений на микрослужбы или для интеграции с внешними приложениями.This communication occurs through an event bus to propagate updates across microservices or to integrate with external applications. Шина событий может быть реализована с помощью какой-либо технологии инфраструктуры брокера обмена сообщениями, например RabbitMQ, или с помощью служебных шин более высокого уровня (уровня абстракции), таких как служебная шина Azure, NServiceBus, MassTransit или Brighter.The event bus can be implemented with any messaging-broker infrastructure technology like RabbitMQ, or using higher-level (abstraction-level) service buses like Azure Service Bus, NServiceBus, MassTransit, or Brighter.

Приложение разворачивается как набор микрослужб в форме контейнеров.The application is deployed as a set of microservices in the form of containers. Клиентские приложения могут взаимодействовать с этими микрослужбами в виде контейнеров через общедоступные URL-адреса, опубликованные шлюзами API.Client apps can communicate with those microservices running as containers through the public URLs published by the API Gateways.

Владение данными в каждой микрослужбеData sovereignty per microservice

В этом примере приложения каждая микрослужба имеет свою собственную базу данных или источник данных, хотя все базы данных SQL Server развертываются как отдельный контейнер.In the sample application, each microservice owns its own database or data source, although all SQL Server databases are deployed as a single container. Такое проектное решение было принято только для того, чтобы облегчить разработчику получение кода из GitHub, его клонирование и открытие в Visual Studio или Visual Studio Code.This design decision was made only to make it easy for a developer to get the code from GitHub, clone it, and open it in Visual Studio or Visual Studio Code. Или же оно облегчает компиляцию пользовательских образов Docker с помощью .NET CLI и Docker CLI с последующим развертыванием и запуском их в среде разработки Docker.Or alternatively, it makes it easy to compile the custom Docker images using the .NET CLI and the Docker CLI, and then deploy and run them in a Docker development environment. В любом случае использование контейнеров для источников данных позволяет разработчикам выполнять сборку и развертывание за считанные минуты без необходимости подготовки внешней базы данных или любого другого источника данных с жесткими зависимостями от инфраструктуры (облачной или локальной).Either way, using containers for data sources lets developers build and deploy in a matter of minutes without having to provision an external database or any other data source with hard dependencies on infrastructure (cloud or on-premises).

В реальной рабочей среде для обеспечения высокой доступности и масштабируемости базы данных должны размещаться на серверах баз данных в облаке или в локальной среде, но не в контейнерах.In a real production environment, for high availability and for scalability, the databases should be based on database servers in the cloud or on-premises, but not in containers.

Таким образом, единицы развертывания для микрослужб (и даже для баз данных в этом приложении) представляют собой контейнеры Docker, а эталонное приложение является многоконтейнерным приложением, использующим принципы микрослужб.Therefore, the units of deployment for microservices (and even for databases in this application) are Docker containers, and the reference application is a multi-container application that embraces microservices principles.

Дополнительные ресурсыAdditional resources

  • Репозиторий GitHub eShopOnContainers. Исходный код для эталонного приложения eShopOnContainers GitHub repo. Source code for the reference application
    https://aka.ms/eShopOnContainers/

Преимущества решения на основе микрослужбBenefits of a microservice-based solution

Решение на основе микрослужб, такое как представлено здесь, имеет много преимуществ:A microservice-based solution like this has many benefits:

Каждая микрослужба относительно невелика, соответственно ею легко управлять и развивать.Each microservice is relatively small—easy to manage and evolve. В частности:Specifically:

  • Разработчик может легко разобраться и быстро приступить к работе с хорошей производительностью.It is easy for a developer to understand and get started quickly with good productivity.

  • Контейнеры запускаются быстро, что повышает производительность разработчиков.Containers start fast, which makes developers more productive.

  • Интегрированная среда разработки, такая как Visual Studio, может загружать небольшие проекты быстрее, что тоже повышает производительность разработчиков.An IDE like Visual Studio can load smaller projects fast, making developers productive.

  • Каждую микрослужбу можно проектировать, разрабатывать и развертывать независимо от других микрослужб, что обеспечивает гибкость, так как становится проще часто развертывать новые версии микрослужб.Each microservice can be designed, developed, and deployed independently of other microservices, which provide agility because it is easier to deploy new versions of microservices frequently.

Можно масштабировать отдельные области приложения.It is possible to scale out individual areas of the application. Например, может потребоваться масштабирование службы каталога или службы корзины, но не процесса заказа.For instance, the catalog service or the basket service might need to be scaled out, but not the ordering process. Инфраструктура микрослужб будет намного более эффективной с точки зрения ресурсов, используемых при масштабировании, чем монолитная архитектура.A microservices infrastructure will be much more efficient with regard to the resources used when scaling out than a monolithic architecture would be.

Можно разделить работу между несколькими командами разработки.You can divide the development work between multiple teams. Каждая служба может принадлежать одной команде разработки.Each service can be owned by a single development team. Каждая команда может управлять своими службами, разрабатывать, развертывать и масштабировать их независимо от остальных команд.Each team can manage, develop, deploy, and scale their service independently of the rest of the teams.

Проблемы более изолированы.Issues are more isolated. Если в одной службе возникает проблема, она изначально влияет только на эту службу (за исключением случая использования неправильного проекта с прямыми зависимостями между микрослужбами), и другие службы могут продолжать обрабатывать запросы.If there is an issue in one service, only that service is initially impacted (except when the wrong design is used, with direct dependencies between microservices), and other services can continue to handle requests. Напротив, один вышедший из строя компонент в архитектуре монолитного развертывания может привести к остановке всей системы, особенно когда речь идет о ресурсах, например об утечке памяти.In contrast, one malfunctioning component in a monolithic deployment architecture can bring down the entire system, especially when it involves resources, such as a memory leak. Кроме того, после устранения проблемы в микрослужбе можно развернуть только затронутую микрослужбу без ущерба для остальной части приложения.Additionally, when an issue in a microservice is resolved, you can deploy just the affected microservice without impacting the rest of the application.

Можно использовать новейшие технологии.You can use the latest technologies. Так как возможно независимо разрабатывать службы и запускать их параллельно (благодаря контейнерам и .NET), вы можете приступать к использованию последних технологий и платформ в нужный момент и не застревать на устаревшем стеке или платформе для всего приложения.Because you can start developing services independently and run them side by side (thanks to containers and .NET), you can start using the latest technologies and frameworks expediently instead of being stuck on an older stack or framework for the whole application.

Недостатки решения на основе микрослужбDownsides of a microservice-based solution

Решение на основе микрослужб, такое как представлено здесь, имеет некоторые недостатки:A microservice-based solution like this also has some drawbacks:

Распределенное приложение.Distributed application. Распределенное приложение усложняет разработчикам проектирование и создание служб.Distributing the application adds complexity for developers when they are designing and building the services. Например, разработчики должны реализовать взаимодействие между службами с помощью протоколов, таких как HTTP и AMPQ, что повышает сложность тестирования и обработки исключений.For example, developers must implement inter-service communication using protocols like HTTP or AMPQ, which adds complexity for testing and exception handling. Это также приводит к увеличению задержек в системе.It also adds latency to the system.

Сложность развертывания.Deployment complexity. Приложение, имеющее множество типов микрослужб, которому требуется высокий уровень масштабируемости (должна быть предусмотрена возможность создания большого количества экземпляров каждой и балансировки этих служб на большом числе узлов), подразумевает высокую степень сложности развертывания для ИТ-операций и управления.An application that has dozens of microservices types and needs high scalability (it needs to be able to create many instances per service and balance those services across many hosts) means a high degree of deployment complexity for IT operations and management. Если вы не используете инфраструктуру на основе микрослужб (например, оркестратор и планировщик), то на реализацию этой дополнительной сложности может потребоваться гораздо больше усилий разработчиков, чем на само бизнес-приложение.If you are not using a microservice-oriented infrastructure (like an orchestrator and scheduler), that additional complexity can require far more development efforts than the business application itself.

Атомарные транзакции.Atomic transactions. Атомарные транзакции между несколькими микрослужбами обычно невозможны.Atomic transactions between multiple microservices usually are not possible. Бизнес-требования должны включать итоговую согласованность между несколькими микрослужбами.The business requirements have to embrace eventual consistency between multiple microservices.

Увеличенная потребность в глобальных ресурсах (таких как общий объем памяти, диски и сетевые ресурсы для всех серверов или узлов).Increased global resource needs (total memory, drives, and network resources for all the servers or hosts). Во многих случаях при замене монолитного приложения на приложение с микрослужбами объем изначальных глобальных ресурсов, необходимых новому приложению на основе микрослужб, будет больше инфраструктурных требований исходного монолитного приложения.In many cases, when you replace a monolithic application with a microservices approach, the amount of initial global resources needed by the new microservice-based application will be larger than the infrastructure needs of the original monolithic application. Это объясняется тем, что более высокий уровень детализации и распределенные службы требуют больше глобальных ресурсов.This approach is because the higher degree of granularity and distributed services requires more global resources. Однако учитывая низкую стоимость ресурсов в целом и преимущества возможности масштабирования определенных частей приложения, повышенная стоимость ресурсов в сравнении с долгосрочными затратами при разработке монолитных приложений обычно является лучшим выбором для больших, долгосрочных приложений.However, given the low cost of resources in general and the benefit of being able to scale out certain areas of the application compared to long-term costs when evolving monolithic applications, the increased use of resources is usually a good tradeoff for large, long-term applications.

Проблемы с прямым взаимодействием клиента и микрослужбы.Issues with direct client-to-microservice communication. Когда приложение большое и имеет десятки микрослужб, возникают проблемы и ограничения, если приложению требуется прямое взаимодействие клиента с микрослужбой.When the application is large, with dozens of microservices, there are challenges and limitations if the application requires direct client-to-microservice communications. Одна из проблем заключается в возможном несоответствии между потребностями клиента и интерфейсами API, предоставляемыми каждой микрослужбой.One problem is a potential mismatch between the needs of the client and the APIs exposed by each of the microservices. В некоторых случаях клиентскому приложению может потребоваться выполнить много отдельных запросов для создания пользовательского интерфейса, что может оказаться неэффективным в Интернете и непрактичным в мобильной сети.In certain cases, the client application might need to make many separate requests to compose the UI, which can be inefficient over the Internet and would be impractical over a mobile network. Таким образом, запросы от клиентского приложения в серверную систему необходимо максимально сократить.Therefore, requests from the client application to the back-end system should be minimized.

Другая проблема, связанная с прямым взаимодействием клиента с микрослужбой, состоит в том, что некоторые микрослужбы могут использовать протоколы, не адаптированные для Интернета.Another problem with direct client-to-microservice communications is that some microservices might be using protocols that are not Web-friendly. Одна служба может использовать двоичный протокол, в то время как другая — обмен сообщениями AMQP.One service might use a binary protocol, while another service might use AMQP messaging. Эти протоколы не адаптированы для брандмауэра, и их лучше использовать внутренним образом.Those protocols are not firewall-friendly and are best used internally. Как правило, для взаимодействия за пределами брандмауэра в приложении следует использовать такие протоколы, как HTTP и WebSockets.Usually, an application should use protocols such as HTTP and WebSockets for communication outside of the firewall.

Еще одним недостатком прямого взаимодействия клиента со службами является то, что оно затрудняет выполнение рефакторинга контрактов для этих микрослужб.Yet another drawback with this direct client-to-service approach is that it makes it difficult to refactor the contracts for those microservices. Со временем разработчикам может потребоваться изменить способ разделения системы на службы.Over time developers might want to change how the system is partitioned into services. Например, они могут объединить две службы или разбить службу на несколько служб.For example, they might merge two services or split a service into two or more services. Однако если клиенты взаимодействуют со службами напрямую, выполнение такого рода рефакторинга может нарушить совместимость с клиентскими приложениями.However, if clients communicate directly with the services, performing this kind of refactoring can break compatibility with client apps.

Как упоминалось в разделе, посвященном архитектуре, при разработке и сборке сложного приложения на основе микрослужб следует обдумать целесообразность использования нескольких детальных шлюзов API вместо более простого прямого взаимодействия клиента с микрослужбами.As mentioned in the architecture section, when designing and building a complex application based on microservices, you might consider the use of multiple fine-grained API Gateways instead of the simpler direct client-to-microservice communication approach.

Разделение на микрослужбы.Partitioning the microservices. Наконец, независимо от подхода, выбранного для архитектуры микрослужб, еще одна задача состоит в том, чтобы решить, как разделить все приложение на несколько микрослужб.Finally, no matter, which approach you take for your microservice architecture, another challenge is deciding how to partition an end-to-end application into multiple microservices. Как упоминалось в разделе, посвященном архитектуре, существует несколько методов и подходов.As noted in the architecture section of the guide, there are several techniques and approaches you can take. В сущности, вам нужно определить области приложения, которые отделены от других областей и имеют небольшое количество жестких зависимостей.Basically, you need to identify areas of the application that are decoupled from the other areas and that have a low number of hard dependencies. Во многих случаях это согласуется с разделением на службы по варианту использования.In many cases, this approach is aligned to partitioning services by use case. Например, в нашем приложении интернет-магазина имеется служба заказов, отвечающая за всю бизнес-логику, относящуюся к процессу заказа.For example, in our e-shop application, we have an ordering service that is responsible for all the business logic related to the order process. У нас также есть служба каталога и служба корзины, которые реализуют другие возможности.We also have the catalog service and the basket service that implement other capabilities. Желательно, чтобы каждая служба имела только небольшой набор задач.Ideally, each service should have only a small set of responsibilities. Это аналогично принципу разделения обязанностей (SRP), используемому для классов, который утверждает, что класс должен иметь только одну причину для изменения.This approach is similar to the single responsibility principle (SRP) applied to classes, which states that a class should only have one reason to change. Однако в данном случае это относится к микрослужбам, поэтому область будет больше, чем один класс.But in this case, it is about microservices, so the scope will be larger than a single class. Прежде всего, микрослужба должна быть автономной, с начала до конца, включая ответственность за свои источники данных.Most of all, a microservice has to be autonomous, end to end, including responsibility for its own data sources.

Внешняя и внутренняя архитектура и конструктивные шаблоныExternal versus internal architecture and design patterns

Внешняя архитектура — это архитектура микрослужб, состоящая из нескольких служб и соответствующая принципам, описанным в разделе "Архитектура" данного руководства.The external architecture is the microservice architecture composed by multiple services, following the principles described in the architecture section of this guide. Однако в зависимости от характера каждой микрослужбы и независимо от выбранной высокоуровневой архитектуры микрослужб распространенный и иногда рекомендуемый подход заключается в наличии разных внутренних архитектур на основе разных шаблонов для различных микрослужб.However, depending on the nature of each microservice, and independently of high-level microservice architecture you choose, it is common and sometimes advisable to have different internal architectures, each based on different patterns, for different microservices. Микрослужбы даже могут использовать разные технологии и языки программирования.The microservices can even use different technologies and programming languages. На рис. 6-2 показано это разнообразие.Figure 6-2 illustrates this diversity.

Схема сравнения шаблонов внешней и внутренней архитектуры.

Рис. 6-2.Figure 6-2. Внешняя и внутренняя архитектура и конструктивные шаблоныExternal versus internal architecture and design

Например, в нашем эталонном приложении eShopOnContainers микрослужбы каталога, корзины и пользовательские профили являются простыми (в основном это подсистемы CRUD).For instance, in our eShopOnContainers sample, the catalog, basket, and user profile microservices are simple (basically, CRUD subsystems). Следовательно, их внутренняя архитектура и конструктивный шаблон достаточно просты.Therefore, their internal architecture and design is straightforward. Однако у вас могут быть другие микрослужбы, например микрослужба заказов, которая является более сложной и представляет постоянно меняющиеся бизнес-правила с высокой степенью сложности предметной области.However, you might have other microservices, such as the ordering microservice, which is more complex and represents ever-changing business rules with a high degree of domain complexity. В подобных случаях может потребоваться реализация в конкретной микрослужбе более сложных шаблонов, например таких, которые определяются с помощью предметно-ориентированного проектирования (DDD), как мы это делаем в микрослужбе заказов eShopOnContainers.In cases like these, you might want to implement more advanced patterns within a particular microservice, like the ones defined with domain-driven design (DDD) approaches, as we are doing in the eShopOnContainers ordering microservice. (Мы рассмотрим эти шаблоны DDD позднее, в разделе, посвященном реализации микрослужбы заказов eShopOnContainers.)(We will review these DDD patterns in the section later that explains the implementation of the eShopOnContainers ordering microservice.)

Другая причина использования разных технологий для микрослужб может заключаться в сути каждой микрослужбы.Another reason for a different technology per microservice might be the nature of each microservice. Например, при разработке для области AI или машинного обучения может оказаться предпочтительнее использовать такой функциональный язык программирования, как F# или даже R вместо объектно-ориентированного языка программирования, такого как C#.For example, it might be better to use a functional programming language like F#, or even a language like R if you are targeting AI and machine learning domains, instead of a more object-oriented programming language like C#.

Суть в том, что каждая микрослужба может иметь другую внутреннюю архитектуру на основе других конструктивных шаблонов.The bottom line is that each microservice can have a different internal architecture based on different design patterns. Не все микрослужбы следует реализовывать с помощью расширенных шаблонов DDD, так как это может оказаться чрезмерным техническим усложнением.Not all microservices should be implemented using advanced DDD patterns, because that would be over-engineering them. Аналогично, сложные микрослужбы с постоянно меняющейся бизнес-логикой не следует реализовывать как компоненты CRUD, иначе вы можете получить код низкого качества.Similarly, complex microservices with ever-changing business logic should not be implemented as CRUD components, or you can end up with low-quality code.

Новый мир: множество архитектурных шаблонов и многоязыковые микрослужбыThe new world: multiple architectural patterns and polyglot microservices

Существует множество архитектурных шаблонов, используемых архитекторами и разработчиками программного обеспечения.There are many architectural patterns used by software architects and developers. Ниже приведены некоторые из них (смешанные архитектурные стили и архитектурные шаблоны).The following are a few (mixing architecture styles and architecture patterns):

Вы также можете создавать микрослужбы с помощью множества технологий и языков, таких как веб-API ASP.NET Core, NancyFx, SignalR ASP.NET Core (доступный в .NET Core 2 и более поздних версий), F#, Node.js, Python, Java, C++, GoLang и многих других.You can also build microservices with many technologies and languages, such as ASP.NET Core Web APIs, NancyFx, ASP.NET Core SignalR (available with .NET Core 2 or later), F#, Node.js, Python, Java, C++, GoLang, and more.

Важно отметить, что ни один конкретный архитектурный шаблон или стиль и ни одна конкретная технология не подходят для всех ситуаций.The important point is that no particular architecture pattern or style, nor any particular technology, is right for all situations. На рис. 6-3 показаны некоторые подходы и технологии (хотя и не в каком-либо определенном порядке), которые могут использоваться в различных микрослужбах.Figure 6-3 shows some approaches and technologies (although not in any particular order) that could be used in different microservices.

Схема, демонстрирующая 12 сложных микрослужб в многоязыковой архитектуре.

Рис. 6-3.Figure 6-3. Множество архитектурных шаблонов и многоязыковые микрослужбыMulti-architectural patterns and the polyglot microservices world

Шаблоны с несколькими архитектурами и многоязыковые микрослужбы позволяют комбинировать языки и технологии в зависимости от потребностей микрослужбы, при этом службы по-прежнему смогут взаимодействовать друг с другом.Multi-architectural pattern and polyglot microservices means you can mix and match languages and technologies to the needs of each microservice and still have them talking to each other. Как показано на рис. 6-3, в приложениях, состоящих из многих микрослужб (с ограниченным контекстом в технологии с предметно-ориентированным проектированием, или просто "подсистем" как автономных микрослужб), можно реализовывать каждую микрослужбу по-разному.As shown in Figure 6-3, in applications composed of many microservices (Bounded Contexts in domain-driven design terminology, or simply "subsystems" as autonomous microservices), you might implement each microservice in a different way. Каждая микрослужба может иметь свой архитектурный шаблон и использовать разные языки и базы данных в зависимости от характера приложения, бизнес-требований и приоритетов.Each might have a different architecture pattern and use different languages and databases depending on the application's nature, business requirements, and priorities. В некоторых случаях микрослужбы могут быть аналогичными.In some cases, the microservices might be similar. Но обычно это не так, потому что границы контекста и требования каждой подсистемы, как правило, различны.But that is not usually the case, because each subsystem's context boundary and requirements are usually different.

Например, для простого служебного приложения CRUD разработка и реализация шаблонов DDD может не иметь смысла.For instance, for a simple CRUD maintenance application, it might not make sense to design and implement DDD patterns. Но для вашей основной предметной области или бизнеса может потребоваться применение расширенных шаблонов для решения сложных бизнес-задач с постоянно меняющимися бизнес-правилами.But for your core domain or core business, you might need to apply more advanced patterns to tackle business complexity with ever-changing business rules.

В частности, если вы используете крупные приложения, состоящие из нескольких подсистем, не применяйте единственную архитектуру верхнего уровня на основе единственного архитектурного шаблона.Especially when you deal with large applications composed by multiple subsystems, you should not apply a single top-level architecture based on a single architecture pattern. Например, CQRS не подходит в качестве архитектуры верхнего уровня для всего приложения, но может оказаться полезной для определенной группы служб.For instance, CQRS should not be applied as a top-level architecture for a whole application, but might be useful for a specific set of services.

Не существует простого решения или правильного архитектурного шаблона для каждого конкретного случая.There is no silver bullet or a right architecture pattern for every given case. Вы не можете получить "один архитектурный шаблон, подходящий для всего".You cannot have "one architecture pattern to rule them all." В зависимости от приоритетов микрослужб необходимо выбирать свой подход для каждой из них, как описано в следующих разделах.Depending on the priorities of each microservice, you must choose a different approach for each, as explained in the following sections.