Azure でのマイクロサービスの設計、構築、および操作Designing, building, and operating microservices on Azure

現在、マイクロサービスは、回復性優れ、単独でのデプロイが可能で、迅速に展開できるスケーラブルなクラウド アプリケーションを構築するための一般的なアーキテクチャ スタイルになっています。Microservices have become a popular architectural style for building cloud applications that are resilient, highly scalable, independently deployable, and able to evolve quickly. しかし、このマイクロサービスを、単なる業界用語に留めないためには、アプリケーションを設計および構築するのためのさまざまなアプローチが必要です。To be more than just a buzzword, however, microservices require a different approach to designing and building applications.

この一連の記事では、Azure でマイクロサービス アーキテクチャを構築して実行する方法について説明します。In this set of articles, we explore how to build and run a microservices architecture on Azure. 取り上げるトピックは次のとおりです。Topics include:

  • ドメインベースの設計 (DDD) を使用してマイクロサービス アーキテクチャを設計する。Using Domain Driven Design (DDD) to design a microservices architecture.
  • コンピューティング、ストレージ、メッセージング、およびその他の設計要素に適した Azure テクノロジを選択する。Choosing the right Azure technologies for compute, storage, messaging, and other elements of the design.
  • マイクロサービスの設計パターンについて理解する。Understanding microservices design patterns.
  • 回復性、スケーラビリティ、およびパフォーマンスを設計する。Designing for resiliency, scalability, and performance.
  • CI/CD パイプラインを構築する。Building a CI/CD pipeline.

全体として、ドローン配送サービスのエンド ツー エンド シナリオに焦点を当てて説明します。このサービスでは、顧客はパッケージがドローンで集荷および配送されるスケジュールを設定することができます。Throughout, we focus on an end-to-end scenario: A drone delivery service that lets customers schedule packages to be picked up and delivered via drone. リファレンス実装のコードは GitHub にありますYou can find the code for our reference implementation on GitHub

GitHub リファレンス実装GitHub Reference implementation

まずは、基礎から始めましょう。But first, let's start with fundamentals. マイクロサービスと何でしょうか。また、マイクロサービス アーキテクチャを採用することで、どのような利点を得られるのでしょうか。What are microservices, and what are the advantages of adopting a microservices architecture?

マイクロサービスを構築する理由Why build microservices?

マイクロサービス アーキテクチャでは、アプリケーションが小規模の独立したサービスで構成されます。In a microservices architecture, the application is composed of small, independent services. 以下に、マイクロサービスの特徴を定義します。Here are some of the defining characteristics of microservices:

  • 各マイクロサービスが 1 つのビジネス機能を実装します。Each microservice implements a single business capability.
  • マイクロサービスは小さいため、小規模な 1 つの開発者チームで作成および管理できます。A microservice is small enough that a single small team of developers can write and maintain it.
  • マイクロサービスは個別のプロセスで実行され、適切に定義された API またはメッセージング パターンを介して通信します。Microservices run in separate processes, communicating through well-defined APIs or messaging patterns.
  • マイクロサービスでは、データ ストアまたはデータ スキーマが共有されません。Microservices do not share data stores or data schemas. 各マイクロサービスがそれぞれ自身のデータを管理する必要があります。Each microservice is responsible for managing its own data.
  • マイクロサービスは個別のコード ベースを持ち、ソース コードを共有しません。Microservices have separate code bases, and do not share source code. ただし、共通のユーティリティ ライブラリを使用することはあります。They may use common utility libraries, however.
  • 他のサービスとは関係なく各マイクロサービスをデプロイして更新できます。Each microservice can be deployed and updated independently of other services.

適切に構築することで、マイクロサービスにより、以下のような有益なメリットが多数もたらされます。Done correctly, microservices can provide a number of useful benefits:

  • 機敏性。Agility. マイクロサービスは個別にデプロイされるため、バグ修正や機能リリースが管理しやすくなります。Because microservices are deployed independently, it's easier to manage bug fixes and feature releases. アプリケーション全体を再デプロイしなくてもサービスを更新できるほか、問題が発生したときに更新プログラムをロールバックできます。You can update a service without redeploying the entire application, and roll back an update if something goes wrong. 従来のアプリケーションでは、多くの場合、アプリケーションの一部にバグが見つかると、リリース プロセス全体がブロックされ、その結果、新機能はバグ修正が統合、テスト、および公開されるまで使用できなくなる可能性があります。In many traditional applications, if a bug is found in one part of the application, it can block the entire release process; as a result, new features may be held up waiting for a bug fix to be integrated, tested, and published.

  • 短いコード、小規模チーム。Small code, small teams. マイクロサービスの規模は小さく、1 つの機能チームによって構築、テスト、およびデプロイできます。A microservice should be small enough that a single feature team can build, test, and deploy it. コード ベースは小さいほど、わかりやすくなります。Small code bases are easier to understand. 大規模なモノリシック アプリケーションでは、時間の経過に伴ってコードの依存関係が複雑になる傾向にあり、新しい機能を追加しようとすると、多くの場所でコード変更が必要です。In a large monolithic application, there is a tendency over time for code dependencies to become tangled, so that adding a new feature requires touching code in a lot of places. マイクロサービス アーキテクチャでは、コードまたはデータ ストアが共有されないため、依存関係を最小限に抑え、新しい機能を簡単に追加できます。By not sharing code or data stores, a microservices architecture minimizes dependencies, and that makes it easier to add new features. 小規模なチーム編成も機敏性を向上させます。Small team sizes also promote greater agility. "2 枚のピザ ルール" も、チームは 2 枚のピザが行き渡る人数に抑える必要がある、となっています。The "two-pizza rule" says that a team should be small enough that two pizzas can feed the team. もちろん、これは正確な基準ではなく、チームの食欲によっても変わります。Obviously that's not an exact metric and depends on team appetites! しかし、重要なのは、大規模なグループでは、コミュニケーションに時間がかかり、管理オーバーヘッドが増大し、機敏性も低下するため、生産性が低くなる傾向があるという点です。But the point is that large groups tend be less productive, because communication is slower, management overhead goes up, and agility diminishes.

  • テクノロジの組み合わせMix of technologies. 必要に応じて、チームがテクノロジ スタックを組み合わせて、サービスに最適なテクノロジを選択できます。Teams can pick the technology that best fits their service, using a mix of technology stacks as appropriate.

  • 回復性Resiliency. 個々のマイクロサービスが使用できなくなっても、上流マイクロサービスが障害を正しく処理するように設計されている限り (サーキット ブレークの実装など)、アプリケーション全体が中断されることはありません。If an individual microservice becomes unavailable, it won't disrupt the entire application, as long as any upstream microservices are designed to handle faults correctly (for example, by implementing circuit breaking).

  • スケーラビリティ: Scalability. マイクロサービス アーキテクチャでは、各マイクロサービスを個別に拡張できます。A microservices architecture allows each microservice to be scaled independently of the others. つまり、サブシステムにさらに多くのリソースが必要な場合、アプリケーション全体をスケールアウトせずに、サブシステムをスケールアウトすることができます。That lets you scale out subsystems that require more resources, without scaling out the entire application. コンテナー内にサービスをデプロイすると、マイクロサービスを高密度で 1 つのホストに圧縮できるため、リソースをより効率的に使用できます。If you deploy services inside containers, you can also pack a higher density of microservices onto a single host, which allows for more efficient utilization of resources.

  • データの分離Data isolation. 影響を受けるのは 1 つのマイクロサービスだけであるため、スキーマ更新がはるかに実行しやすくなります。It is much easier to perform schema updates, because only a single microservice is impacted. モノリシック アプリケーションでは、アプリケーションのさまざまな部分すべてが同じデータに影響する可能性があり、スキーマの変更にはリスクが伴うため、スキーマ更新は非常に困難になる可能性があります。In a monolithic application, schema updates can become very challenging, because different parts of the application may all touch the same data, making any alterations to the schema risky.

課題No free lunch

こうしたメリットを実現するには、それなりに手間がかかります。These benefits don't come for free. この一連の記事は、回復性、拡張性、管理性に優れたマイクロサービスを構築するためのいくつかの課題に対処できるようにすることを目的としています。This series of articles is designed to address some of the challenges of building microservices that are resilient, scalable, and manageable.

  • サービス境界Service boundaries. マイクロサービスを構築するときは、サービス間の境界をどこにするかを慎重に検討する必要があります。When you build microservices, you need to think carefully about where to draw the boundaries between services. 一度サービスを構築して運用環境にデプロイすると、その境界を越えてリファクターするには困難を伴うことがあります。Once services are built and deployed in production, it can be hard to refactor across those boundaries. 適切なサービス境界を選択することは、マイクロサービス アーキテクチャを設計するときの最大の課題の 1 つです。Choosing the right service boundaries is one of the biggest challenges when designing a microservices architecture. 各サービスの規模はどの程度にするべきでしょうか。How big should each service be? どのような場合に複数のサービスに機能を分解し、また、どのような場合に同じサービス内に機能をまとめるべきでしょうか。When should functionality be factored across several services, and when should it be kept inside the same service? このガイドでは、ドメイン ベース設計を使用して、サービス境界を見つけ出すアプローチについて説明します。In this guide, we describe an approach that uses domain-driven design to find service boundaries. この場合、まずはドメイン分析で境界コンテキストを検出し、機能要件と機能以外の要件に基づいて、一連の戦術的 DDD パターンを適用します。It starts with Domain analysis to find the bounded contexts, then applies a set of tactical DDD patterns based on functional and non-functional requirements.

  • データの一貫性と整合性Data consistency and integrity. マイクロサービスの基本原則は、各サービスがそれぞれ自身のデータを管理することです。A basic principle of microservices is that each service manages its own data. これによりサービスが分離されますが、データ整合性または冗長性の課題が生じる可能性があります。This keeps services decoupled, but can lead to challenges with data integrity or redundancy. その問題のいくつかについては、データ統合に関するページで説明しています。We explore some of these issues in the Data considerations.

  • ネットワークの輻輳と待機時間Network congestion and latency. 小さく細分化された多くのサービスを使用すると、サービス間の通信が増え、エンド ツー エンドの待機時間が長くなります。The use of many small, granular services can result in more interservice communication and longer end-to-end latency. サービス間の通信に関する章では、サービス間でのメッセージングに関する考慮事項について説明します。The chapter Interservice communication describes considerations for messaging between services. マイクロサービス アーキテクチャでは、同期通信と非同期通信の両方が使用されます。Both synchronous and asynchronous communication have a place in microservices architectures. サービスの疎結合を維持し、サービスを個別にデプロイおよび更新できるように、適切な API 設計を行うことが重要です。Good API design is important so that services remain loosely coupled, and can be independently deployed and updated.

  • 複雑さComplexity. マイクロサービス アプリケーションには可動部分がかなりあります。A microservices application has more moving parts. 各サービスはシンプルですが、サービスは全体として連携する必要があります。Each service may be simple, but the services have to work together as a whole. 1 つのユーザー操作に、複数のサービスが関連する場合があります。A single user operation may involve multiple services. インジェストとワークフローに関する章では、高スループットでの要求の取り込み、ワークフローの調整、およびエラー処理に関するいくつかの問題について説明します。In the chapter Ingestion and workflow, we examine some of the issues around ingesting requests at high throughput, coordinating a workflow, and handling failures.

  • クライアントとアプリケーションの間の通信。Communication between clients and the application. アプリケーションを多数の小規模サービスに分解した場合、クライアントは、こうしたサービスとどのように通信するのでしょうか。When you decompose an application into many small services, how should clients communicate with those services? 各サービスを個別に直接呼び出すべきか、あるいは、API ゲートウェイを介して要求をルーティングするべきでしょうか。Should a client call each individual service directly, or route requests through an API Gateway?

  • 監視Monitoring. 分散アプリケーションを監視するには複数のサービスのテレメトリを関連付ける必要があるため、モノリシック アプリケーションを監視するよりも手間がかかります。Monitoring a distributed application can be a lot harder than a monolithic application, because you must correlate telemetry from multiple services. ログ記録と監視に関する章では、こうした懸念事項を取り上げます。The chapter Logging and monitoring addresses these concerns.

  • 継続的インテグレーションと配信 (CI/CD)Continuous integration and delivery (CI/CD). マイクロサービスの主な目標の 1 つが機敏性です。One of the main goals of microservices is agility. これを実現するには、各サービスを迅速かつ確実にテスト環境および運用環境にデプロイできるように、自動化された堅牢な CI/CD が必要です。To achieve this, you must have automated and robust CI/CD, so that you can quickly and reliably deploy individual services into test and production environments.

ドローン配送アプリケーションThe Drone Delivery application

このような問題を調査し、マイクロサービス アーキテクチャのベスト プラクティスのいくつかを紹介するために、ドローン配送アプリケーションというリファレンス実装を作成しました。To explore these issues, and to illustrate some of the best practices for a microservices architecture, we created a reference implementation that we call the Drone Delivery application. リファレンス実装は GitHub にあります。You can find the reference implementation on GitHub.

Fabrikam, Inc. は、ドローン配送サービスを開始しようとしています。Fabrikam, Inc. is starting a drone delivery service. 同社は、ドローン機団を管理しています。The company manages a fleet of drone aircraft. 企業がサービスに登録すると、ユーザーは、ドローンで商品を集荷して配送するように依頼できます。Businesses register with the service, and users can request a drone to pick up goods for delivery. 顧客が集荷のスケジュールを設定すると、バックエンド システムによってドローンが割り当てられ、推定配送時刻がユーザーに通知されます。When a customer schedules a pickup, a backend system assigns a drone and notifies the user with an estimated delivery time. 配送中、ETA は常時更新され、顧客はドローンの場所を追跡できます。While the delivery is in progress, the customer can track the location of the drone, with a continuously updated ETA.

このシナリオには、かなり複雑なドメインが含まれます。This scenario involves a fairly complicated domain. ビジネスに関する懸念事項には、ドローンのスケジュール設定、荷物の追跡、ユーザー アカウントの管理、履歴データの保存と分析などもあります。Some of the business concerns include scheduling drones, tracking packages, managing user accounts, and storing and analyzing historical data. さらに、Fabrikam が求めているのは、迅速に市場に出し、迅速に反復して、新機能を追加することです。Moreover, Fabrikam wants to get to market quickly and then iterate quickly, adding new functionality and capabilities. アプリケーションは、高いサービス レベル目標 (SLO) に基づいてクラウド スケールで動作する必要があります。The application needs to operate at cloud scale, with a high service level objective (SLO). また、Fabrikam は、システムの部分ごとに、データ ストレージとクエリの要件がまったく異なることを予期しています。Fabrikam also expects that different parts of the system will have very different requirements for data storage and querying. Fabrikam はこれらをすべて考慮した結果、ドローン配送アプリケーションにマイクロサービス アーキテクチャを選択します。All of these considerations lead Fabrikam to choose a microservices architecture for the Drone Delivery application.

注意

マイクロサービス アーキテクチャと他のアーキテクチャ スタイルのどちらを選択するかについては、「Azure アプリケーション アーキテクチャ ガイド」を参照してください。For help in choosing between a microservices architecture and other architectural styles, see the Azure Application Architecture Guide.

このリファレンス実装では、Azure Container Service (ACS) で Kubernetes を使用しています。Our reference implementation uses Kubernetes with Azure Container Service (ACS). ただし、高いレベルでのアーキテクチャの決定と課題の多くは、Azure Service Fabric を含む、すべてのコンテナー オーケストレーターに当てはまります。However, many of the high-level architectural decisions and challenges will apply to any container orchestrator, including Azure Service Fabric.