Контейнерные микрослужбыContainerized Microservices

Разработка приложений Client-Server привела к созданию многоуровневых приложений, использующих определенные технологии на каждом уровне.Developing client-server applications has resulted in a focus on building tiered applications that use specific technologies in each tier. Такие приложения часто называют монолитными приложениями и упаковываются на оборудование для пиковых нагрузок.Such applications are often referred to as monolithic applications, and are packaged onto hardware pre-scaled for peak loads. Основным недостатком этого подхода разработки является тесная связь между компонентами внутри каждого уровня, что отдельные компоненты невозможно легко масштабировать и затраты на тестирование.The main drawbacks of this development approach are the tight coupling between components within each tier, that individual components can't be easily scaled, and the cost of testing. Простое обновление может иметь непредвиденные последствия на остальной части уровня, поэтому изменение компонента приложения требует повторного тестирования и повторного развертывания всего уровня.A simple update can have unforeseen effects on the rest of the tier, and so a change to an application component requires its entire tier to be retested and redeployed.

В частности, в случае с возрастом облака, можно легко масштабировать отдельные компоненты.Particularly concerning in the age of the cloud, is that individual components can't be easily scaled. Монолитное приложение содержит функциональные возможности, зависящие от домена, и обычно разделяется функциональными уровнями, такими как интерфейсная часть, Бизнес-логика и хранилище данных.A monolithic application contains domain-specific functionality, and is typically divided by functional layers such as front end, business logic, and data storage. Монолитное приложение масштабируется путем клонирования всего приложения на несколько компьютеров, как показано на рисунке 8-1.A monolithic application is scaled by cloning the entire application onto multiple machines, as illustrated in Figure 8-1.

Рис. 8-1. Подход монолитного масштабирования приложенийFigure 8-1: Monolithic application scaling approach

МикрослужбыMicroservices

Микрослужбы предлагают другой подход к разработке и развертыванию приложений, подход, который подходит для обеспечения гибкости, масштабирования и надежности современных облачных приложений.Microservices offer a different approach to application development and deployment, an approach that's suited to the agility, scale, and reliability requirements of modern cloud applications. Приложение микрослужб разбивается на независимые компоненты, которые совместно работают для предоставления общей функциональности приложения.A microservices application is decomposed into independent components that work together to deliver the application's overall functionality. Термин «микрослужба» подчеркивает, что приложения должны быть состоять из служб, достаточных для отражения независимых проблем, чтобы каждая микрослужба реализовала одну функцию.The term microservice emphasizes that applications should be composed of services small enough to reflect independent concerns, so that each microservice implements a single function. Кроме того, каждая микрослужба имеет четко определенные контракты, чтобы другие микрослужбы могли обмениваться данными и обмениваться ими.In addition, each microservice has well-defined contracts so that other microservices can communicate and share data with it. Типичные примеры микрослужб включают в себя корзины покупок, обработку запасов, подсистемы покупок и обработку платежей.Typical examples of microservices include shopping carts, inventory processing, purchase subsystems, and payment processing.

Микрослужбы могут масштабироваться независимо друг от друга, по сравнению с гигантским монолитным приложением, которое масштабируется вместе.Microservices can scale-out independently, as compared to giant monolithic applications that scale together. Это означает, что конкретная функциональная область, требующая большего объема вычислительной мощности или пропускной способности сети для поддержки спроса, может масштабироваться, а не иметь необходимости в масштабировании других областей приложения.This means that a specific functional area, that requires more processing power or network bandwidth to support demand, can be scaled rather than unnecessarily scaling-out other areas of the application. На рис. 8-2 показан этот подход, когда микрослужбы развертываются и масштабируются независимо друг от друга, создавая экземпляры служб на разных компьютерах.Figure 8-2 illustrates this approach, where microservices are deployed and scaled independently, creating instances of services across machines.

Рис. 8-2. Подход к масштабированию приложений микрослужбFigure 8-2: Microservices application scaling approach

Горизонтальное масштабирование микрослужб может выполняться практически мгновенно, позволяя приложению адаптироваться к изменяющимся нагрузкам.Microservice scale-out can be nearly instantaneous, allowing an application to adapt to changing loads. Например, одна микрослужба в веб-функции приложения может быть единственной микрослужбой в приложении, которую необходимо масштабировать для обработки дополнительного входящего трафика.For example, a single microservice in the web-facing functionality of an application might be the only microservice in the application that needs to scale out to handle additional incoming traffic.

Классическая модель масштабируемости приложений заключается в том, что для хранения постоянных данных используется балансировка нагрузки, уровень без сохранения состояния с общим внешним хранилищем.The classic model for application scalability is to have a load-balanced, stateless tier with a shared external datastore to store persistent data. Микрослужбы с отслеживанием состояния управляют собственными постоянными данными, обычно сохраняя их локально на серверах, на которых они размещены, чтобы избежать издержек при доступе к сети и сложности операций между службами.Stateful microservices manage their own persistent data, usually storing it locally on the servers on which they are placed, to avoid the overhead of network access and complexity of cross-service operations. Это позволяет максимально быстро обрабатывать данные и устранять потребность в системах кэширования.This enables the fastest possible processing of data and can eliminate the need for caching systems. Кроме того, масштабируемые микрослужбы с отслеживанием состояния обычно разделяют данные между своими экземплярами, чтобы управлять размером данных и пропускной способностью передачи, за пределами которых может поддерживаться один сервер.In addition, scalable stateful microservices usually partition data among their instances, to manage data size and transfer throughput beyond which a single server can support.

Микрослужбы также поддерживают независимые обновления.Microservices also support independent updates. Такая слабая связь между микрослужбами обеспечивает быстрое и надежное развитие приложений.This loose coupling between microservices provides a rapid and reliable application evolution. Независимая, распределенная природа поддерживает последовательное обновление, когда только подмножество экземпляров одной микрослужбы будет обновляться в любой конкретный момент времени.Their independent, distributed nature supports rolling updates, where only a subset of instances of a single microservice will update at any given time. Поэтому при обнаружении проблемы можно выполнить откат обновления ошибками, прежде чем все экземпляры будут обновлены с помощью неисправного кода или конфигурации.Therefore, if a problem is detected, a buggy update can be rolled back, before all instances update with the faulty code or configuration. Аналогичным образом микрослужбы обычно используют управление версиями схемы, так что клиенты видят последовательную версию при применении обновлений независимо от того, с каким экземпляром микрослужб осуществляется обмен данными.Similarly, microservices typically use schema versioning, so that clients see a consistent version when updates are being applied, regardless of which microservice instance is being communicated with.

Поэтому приложения микрослужб имеют множество преимуществ по сравнению с монолитными приложениями:Therefore, microservice applications have many benefits over monolithic applications:

  • Каждая микрослужба относительно невелика, легко управляется и развивается.Each microservice is relatively small, easy to manage and evolve.
  • Каждую микрослужбу можно разрабатывать и развертывать независимо от других служб.Each microservice can be developed and deployed independently of other services.
  • Каждую микрослужбу можно масштабировать независимо.Each microservice can be scaled-out independently. Например, может потребоваться горизонтальное масштабирование службы каталогов или покупательской корзины, чем служба заказа.For example, a catalog service or shopping basket service might need to be scaled-out more than an ordering service. Таким образом, полученная инфраструктура будет более эффективно потреблять ресурсы при масштабировании.Therefore, the resulting infrastructure will more efficiently consume resources when scaling out.
  • Каждая микрослужба изолирует любые проблемы.Each microservice isolates any issues. Например, если в службе возникает ошибка, она влияет только на эту службу.For example, if there is an issue in a service it only impacts that service. Другие службы могут продолжать обработку запросов.The other services can continue to handle requests.
  • Каждая микрослужба может использовать новейшие технологии.Each microservice can use the latest technologies. Поскольку микрослужбы автономны и работают параллельно, можно использовать новейшие технологии и платформы, а не использовать более старую платформу, которая может использоваться монолитным приложением.Because microservices are autonomous and run side-by-side, the latest technologies and frameworks can be used, rather than being forced to use an older framework that might be used by a monolithic application.

Однако решение на основе микрослужб также имеет потенциальные недостатки:However, a microservice based solution also has potential drawbacks:

  • Выбор способа разбиения приложения на микрослужбы может оказаться сложной задачей, так как каждая микрослужба должна быть полностью автономной, включая ответственность за источники данных.Choosing how to partition an application into microservices can be challenging, as each microservice has to be completely autonomous, end-to-end, including responsibility for its data sources.
  • Разработчики должны реализовать взаимодействие между службами, что повышает сложность и задержку в приложении.Developers must implement inter-service communication, which adds complexity and latency to the application.
  • Атомарные транзакции между несколькими микрослужбами обычно невозможны.Atomic transactions between multiple microservices usually aren't possible. Поэтому бизнес-требования должны учитывать окончательную согласованность между микрослужбами.Therefore, business requirements must embrace eventual consistency between microservices.
  • В рабочей среде существует сложность при развертывании и управлении системой, скомпрометированной многими независимыми службами.In production, there is an operational complexity in deploying and managing a system compromised of many independent services.
  • Прямой обмен данными между клиентом и микрослужбой может усложнить рефакторинг контрактов микрослужб.Direct client-to-microservice communication can make it difficult to refactor the contracts of microservices. Например, со временем секционирования системы по службам может потребоваться изменить.For example, over time how the system is partitioned into services might need to change. Одна служба может быть разбита на две или более служб, и две службы могут объединять их.A single service might split into two or more services, and two services might merge. Если клиенты обмениваются данными напрямую с микрослужбами, эта работа по рефакторингу может привести к нарушению совместимости с клиентскими приложениями.When clients communicate directly with microservices, this refactoring work can break compatibility with client apps.

КонтейнеризацияContainerization

Контейнеры — это подход к разработке программного обеспечения, при котором приложение и его набор зависимостей, а также его конфигурация окружения, абстрактные как файлы манифеста развертывания, упаковываются в виде образа контейнера, тестируются как единое целое и развертывается в операционной системе узла.Containerization is an approach to software development in which an application and its versioned set of dependencies, plus its environment configuration abstracted as deployment manifest files, are packaged together as a container image, tested as a unit, and deployed to a host operating system.

Контейнер — это изолированная, контролируемая и переносимая операционная среда, в которой приложение может работать, не затрагивая ресурсы других контейнеров или узла.A container is an isolated, resource controlled, and portable operating environment, where an application can run without touching the resources of other containers, or the host. Таким образом, контейнер выглядит и действует как недавно установленный физический компьютер или виртуальная машина.Therefore, a container looks and acts like a newly installed physical computer or a virtual machine.

Между контейнерами и виртуальными машинами существует много сходства, как показано на рисунке 8-3.There are many similarities between containers and virtual machines, as illustrated in Figure 8-3.

Рис. 8-3. Сравнение виртуальных машин и контейнеровFigure 8-3: Comparison of virtual machines and containers

Контейнер работает под управлением операционной системы, имеет файловую систему и может быть доступен по сети, как если бы это был физический компьютер или виртуальная машина.A container runs an operating system, has a file system, and can be accessed over a network as if it were a physical or virtual machine. Однако технология и понятия, используемые контейнерами, сильно отличаются от виртуальных машин.However, the technology and concepts used by containers are very different from virtual machines. Виртуальные машины включают приложения, необходимые зависимости и полную операционную систему на виртуальной машине.Virtual machines include the applications, the required dependencies, and a full guest operating system. Контейнеры включают приложение и его зависимости, но совместно используют операционную систему с другими контейнерами, выполняющимися как изолированные процессы в операционной системе узла (помимо контейнеров Hyper-V, которые выполняются внутри специальной виртуальной машины на контейнер).Containers include the application and its dependencies, but share the operating system with other containers, running as isolated processes on the host operating system (aside from Hyper-V containers which run inside of a special virtual machine per container). Таким образом, контейнеры совместно используют ресурсы и обычно требует меньше ресурсов, чем виртуальные машины.Therefore, containers share resources and typically require fewer resources than virtual machines.

Преимуществом подхода, ориентированного на разработку и развертывание в контейнере, является устранение большинства проблем, возникающих из-за несоответствия настроек среды и проблем, с которыми они поступают.The advantage of a container-oriented development and deployment approach is that it eliminates most of the issues that arise from inconsistent environment setups and the problems that come with them. Кроме того, контейнеры предоставляют возможность быстрого масштабирования приложений путем создания экземпляров новых контейнеров по мере необходимости.In addition, containers permit fast application scale-up functionality by instancing new containers as required.

Основные понятия при создании контейнеров и работе с ними:The key concepts when creating and working with containers are:

  • Узел контейнера: Физическая или виртуальная машина, настроенная для размещения контейнеров.Container Host: The physical or virtual machine configured to host containers. Узел контейнера будет запускать один или несколько контейнеров.The container host will run one or more containers.
  • Образ контейнера: Изображение состоит из объединения многоуровневых файловых систем, расположенных поверх других, и является основанием контейнера.Container Image: An image consists of a union of layered filesystems stacked on top of each other, and is the basis of a container. Изображение не имеет состояния и не изменяется при развертывании в разных средах.An image does not have state and it never changes as it's deployed to different environments.
  • Контейнера Контейнер — это экземпляр среды выполнения образа.Container: A container is a runtime instance of an image.
  • Образ ОС контейнера: Контейнеры развертываются из образов.Container OS Image: Containers are deployed from images. Образ операционной системы контейнера является первым слоем на потенциально многих слоях изображений, образующих контейнер.The container operating system image is the first layer in potentially many image layers that make up a container. Операционная система контейнера является неизменяемой и не может быть изменена.A container operating system is immutable, and can't be modified.
  • Репозиторий контейнеров: Каждый раз при создании образа контейнера образ и его зависимости хранятся в локальном репозитории.Container Repository: Each time a container image is created, the image and its dependencies are stored in a local repository. Эти образы могут многократно использоваться на узле контейнера.These images can be reused many times on the container host. Образы контейнеров также могут храниться в общедоступном или частном реестре, таком как DOCKER Hub, чтобы их можно было использовать на разных узлах контейнеров.The container images can also be stored in a public or private registry, such as Docker Hub, so that they can be used across different container hosts.

Предприятия все чаще внедряют контейнеры при реализации приложений на основе микрослужб, а DOCKER становится стандартной реализацией контейнера, которая реализована большинством платформ программного обеспечения и поставщиками облачных решений.Enterprises are increasingly adopting containers when implementing microservice based applications, and Docker has become the standard container implementation that has been adopted by most software platforms and cloud vendors.

Приложение-образец eShopOnContainers использует DOCKER для размещения четырех контейнерных внутренних служб, как показано на рисунке 8-4.The eShopOnContainers reference application uses Docker to host four containerized back-end microservices, as illustrated in Figure 8-4.

Рис. 8-4. eShopOnContainers эталонные микрослужбы приложенияFigure 8-4: eShopOnContainers reference application back-end microservices

Архитектура серверных служб в эталонном приложении разбивается на несколько автономных подсистем в форме совместной работы микрослужб и контейнеров.The architecture of the back-end services in the reference application is decomposed into multiple autonomous sub-systems in the form of collaborating microservices and containers. Каждая микрослужба предоставляет единую область функциональных возможностей: службу идентификации, службу каталогов, службу заказов и службу корзины.Each microservice provides a single area of functionality: an identity service, a catalog service, an ordering service, and a basket service.

Каждая микрослужба имеет собственную базу данных, что позволяет полностью отменять ее связь с другими микрослужбами.Each microservice has its own database, allowing it to be fully decoupled from the other microservices. При необходимости согласованность между базами данных из разных микрослужб достигается с помощью событий уровня приложения.Where necessary, consistency between databases from different microservices is achieved using application-level events. Дополнительные сведения см. в разделе Обмен данными между микрослужбами.For more information, see Communication Between Microservices.

Дополнительные сведения о эталонном приложении см. в разделе микрослужбы .NET: архитектура контейнерных приложений .NET.For more information about the reference application, see .NET Microservices: Architecture for Containerized .NET Applications.

Обмен данными между клиентом и микрослужбамиCommunication Between Client and Microservices

Мобильное приложение eShopOnContainers взаимодействует с контейнерными внутренними микрослужбами с помощью прямого обмена данными между клиентом и микрослужбами, как показано на рис. 8-5.The eShopOnContainers mobile app communicates with the containerized back-end microservices using direct client-to-microservice communication, which is shown in Figure 8-5.

Рис. 8-5. Прямое взаимодействие между клиентом и микрослужбойFigure 8-5: Direct client-to-microservice communication

С прямым обменом данными между клиентом и микрослужбами мобильное приложение выполняет запросы к каждой микрослужбе напрямую через общедоступную конечную точку с другим портом TCP на микрослужбу.With direct client-to-microservice communication, the mobile app makes requests to each microservice directly through its public endpoint, with a different TCP port per microservice. В рабочей среде конечная точка обычно сопоставляется с подсистемой балансировки нагрузки микрослужбы, которая распределяет запросы по доступным экземплярам.In production, the endpoint would typically map to the microservice's load balancer, which distributes requests across the available instances.

Совет

Рассмотрите возможность использования взаимодействия с шлюзом API.Consider using API gateway communication. Прямой обмен данными между клиентом и микрослужбой может иметь недостатки при создании большого и сложного приложения на основе микрослужб, но это более недостаточно для небольших приложений.Direct client-to-microservice communication can have drawbacks when building a large and complex microservice based application, but it's more than adequate for a small application. При проектировании крупного приложения на основе микрослужб с десятками микрослужб рекомендуется использовать взаимодействие с шлюзом API.When designing a large microservice based application with tens of microservices, consider using API gateway communication. Дополнительные сведения см. в разделе микрослужбы .NET: архитектура контейнерных приложений .NET.For more information, see .NET Microservices: Architecture for Containerized .NET Applications.

Обмен данными между микрослужбамиCommunication Between Microservices

Приложение на основе микрослужб — это распределенная система, которая может выполняться на нескольких компьютерах.A microservices based application is a distributed system, potentially running on multiple machines. Обычно каждый экземпляр службы — это процесс.Each service instance is typically a process. Таким образом, службы должны взаимодействовать по протоколу межпроцессного взаимодействия, такому как HTTP, TCP, Расширенный протокол управления очередью сообщений (AMQP) или двоичные протоколы, в зависимости от природы каждой службы.Therefore, services must interact using an inter-process communication protocol, such as HTTP, TCP, Advanced Message Queuing Protocol (AMQP), or binary protocols, depending on the nature of each service.

Два распространенных подхода к обмену данными между микрослужбами — это обмен данными на основе HTTP при запросе данных и упрощенный асинхронный обмен сообщениями при обмене обновлениями между несколькими микрослужбами.The two common approaches for microservice-to-microservice communication are HTTP based REST communication when querying for data, and lightweight asynchronous messaging when communicating updates across multiple microservices.

Асинхронный обмен сообщениями на основе событий очень важен при распространении изменений в нескольких микрослужбах.Asynchronous messaging based event-driven communication is critical when propagating changes across multiple microservices. При таком подходе микрослужба публикует событие, когда что-то получится, например при обновлении бизнес-сущности.With this approach, a microservice publishes an event when something notable happens, for example, when it updates a business entity. Другие микрослужбы подписываются на эти события.Other microservices subscribe to these events. Затем, когда микрослужба получает событие, оно обновляет собственные бизнес-сущности, которые, в свою очередь, могут привести к публикации дополнительных событий.Then, when a microservice receives an event, it updates its own business entities, which might in turn lead to more events being published. Эта функция публикации и подписки обычно достигается с помощью шины событий.This publish-subscribe functionality is usually achieved with an event bus.

Шина событий обеспечивает взаимодействие публикации и подписки между микрослужбами, не требуя от них явного уведомления друг от друга, как показано на рис. 8-6.An event bus allows publish-subscribe communication between microservices, without requiring the components to be explicitly aware of each other, as shown in Figure 8-6.

Рис. 8-6. Публикация и подписка с помощью шины событийFigure 8-6: Publish-subscribe with an event bus

С точки зрения приложения, шина событий — это просто канал публикации и подписки, предоставляемый через интерфейс.From an application perspective, the event bus is simply a publish-subscribe channel exposed via an interface. Однако способ реализации шины событий может различаться.However, the way the event bus is implemented can vary. Например, реализация шины событий может использовать RabbitMQ, служебную шину Azure или другие служебные шины, такие как NServiceBus и MassTransit.For example, an event bus implementation could use RabbitMQ, Azure Service Bus, or other service buses such as NServiceBus and MassTransit. На рис. 8-7 показано, как шина событий используется в эталонном приложении eShopOnContainers.Figure 8-7 shows how an event bus is used in the eShopOnContainers reference application.

Рис. 8-7. Асинхронное взаимодействие на основе событий в приложении-образцеFigure 8-7: Asynchronous event-driven communication in the reference application

Шина событий eShopOnContainers, реализованная с помощью RabbitMQ, предоставляет функции асинхронной публикации и подписки "один ко многим".The eShopOnContainers event bus, implemented using RabbitMQ, provides one-to-many asynchronous publish-subscribe functionality. Это означает, что после публикации события может быть несколько подписчиков, прослушивающих одно и то же событие.This means that after publishing an event, there can be multiple subscribers listening for the same event. Эта связь показана на рис. 8-9.Figure 8-9 illustrates this relationship.

Рис. 8-9. Связь «один ко многим»Figure 8-9: One-to-many communication

Этот подход к обмену данными «один ко многим» использует события для реализации бизнес-транзакций, охватывающих несколько служб, обеспечивая окончательную согласованность между службами.This one-to-many communication approach uses events to implement business transactions that span multiple services, ensuring eventual consistency between the services. Сквозная транзакция состоит из ряда распределенных шагов.An eventual-consistent transaction consists of a series of distributed steps. Таким образом, когда микрослужба профиля пользователя получает команду Упдатеусер, она обновляет сведения о пользователе в своей базе данных и публикует событие Усерупдатед в шине событий.Therefore, when the user-profile microservice receives the UpdateUser command, it updates the user's details in its database and publishes the UserUpdated event to the event bus. Микрослужба корзины и микрослужба заказа подписано на получение этого события, и в ответ на обновление сведений о покупателях в соответствующих базах данных.Both the basket microservice and the ordering microservice have subscribed to receive this event, and in response update their buyer information in their respective databases.

Примечание

Шина событий eShopOnContainers, реализованная с помощью RabbitMQ, предназначена для использования только в качестве подтверждения концепции.The eShopOnContainers event bus, implemented using RabbitMQ, is intended to be used only as a proof of concept. Для рабочих систем следует учитывать альтернативные реализации шины событий.For production systems, alternative event bus implementations should be considered.

Дополнительные сведения о реализации шины событий см. в разделе микрослужбы .NET. архитектура контейнерных приложений .NET.For information about the event bus implementation, see .NET Microservices: Architecture for Containerized .NET Applications.

СводкаSummary

Микрослужбы предлагают подход к разработке и развертыванию приложений, который подходит для обеспечения гибкости, масштабирования и надежности современных облачных приложений.Microservices offer an approach to application development and deployment that's suited to the agility, scale, and reliability requirements of modern cloud applications. Одним из основных преимуществ микрослужб является то, что их можно масштабировать независимо друг от друга. Это означает, что можно масштабировать конкретную функциональную область, которая требует большего объема вычислительной мощности или пропускной способности сети для поддержки спроса без необходимости масштабирования областей приложение, не требующее увеличения спроса.One of the main advantages of microservices is that they can be scaled-out independently, which means that a specific functional area can be scaled that requires more processing power or network bandwidth to support demand, without unnecessarily scaling areas of the application that are not experiencing increased demand.

Контейнер — это изолированная, контролируемая и переносимая операционная среда, в которой приложение может работать, не затрагивая ресурсы других контейнеров или узла.A container is an isolated, resource controlled, and portable operating environment, where an application can run without touching the resources of other containers, or the host. Предприятия все чаще внедряют контейнеры при реализации приложений на основе микрослужб, а DOCKER становится стандартной реализацией контейнера, которая реализована большинством платформ программного обеспечения и поставщиками облачных решений.Enterprises are increasingly adopting containers when implementing microservice based applications, and Docker has become the standard container implementation that has been adopted by most software platforms and cloud vendors.