Microservices入門

Microservicesは、回復性に優れ、独立したデプロイが可能なシステムアーキテクチャである。 Microservicesアーキテクチャの特徴は以下のようなものだ。

  • 各サービスが1つのビジネス上の機能を実現する
  • 各サービスは小さいので、小規模なチームで開発/運用ができる
  • 各サービスは個別のプロセスで実行され、なんらかのAPIやメッセージングプロトコルで通信する
  • モノリスと異なり、各サービスがデータストアを持つ。RDBなどをサービス間で共有することはない
  • 各サービスは個別のコードベースを持つ。ただし、共通ライブラリなどは別途持つことがある
  • 各サービスは、他のサービスを意識せずにデプロイされることができる

Microservicesアーキテクチャによってもたらされるメリットは以下のようなものだ。

  • 俊敏性
    • 各サービスは個別にデプロイされるため、バグ修正やfeatureリリースの管理がしやすい。アプリケーションをアップデートするためにアプリケーション全体の再デプロイは不要で、かつロールバックも小さくできる。
  • テクノロジーの組み合わせ
    • 各サービスに責任を持つチームが、好きなミドルウェア・プログラミング言語・CI/CDなどを選択できる。
  • 耐障害性/回復性
    • 個々のサービスが使用できなくなったとしても、上流のサービスが障害を正しくハンドリングできるように設計/実装されている場合(Circuit Breakerパターンなど。今度書く。)、アプリケーション全体が停止することはない。
  • スケーラビリティ
    • 各サービスは独立しているため、個別にスケールアップ/スケールアウトが可能である。アプリケーション全体をスケールアウトせずに、本当にスケールアウトが必要なサブシステムだけをスケールアウトさせることができる。
  • データの分離
    • 各サービスはスキーマ/データストアを共有しないため、スキーマ更新を行う場合に、影響を受けるのをひとつのサービスに限定できる。モノリシックなアプリケーションでは、アプリケーションの様々な部分に影響が出るため、スキーマ更新は骨の折れる作業になってしまうことがしばしばだが、適切に設計されたMicroservicesアーキテクチャではそのようなことにはならない。

これらに加え、筆者が所属するMercariでは、組織のスケールアップに耐える、という目的もある。1000人規模のエンジニア組織でもスピードを落とさずにデプロイし続けるためにMicroservicesアーキテクチャを選択し、複数の小規模なチームが小規模なサービスを高速に開発/運用できるようにするという狙いがある。(ref: メルカリは開発組織を拡大するためにマイクロサービスアーキテクチャを採用した。Mercari Tech Conf 2018)

Microservicesは、多くの場合以下のような課題を抱えることになる。

  • サービス境界
    • Microservicesを設計する際は、サービスの境界について(つまり、責務の境界について)慎重に検討する必要がある。一度サービスを構築しデプロイすると、サービスを超えたリファクタリングは困難だ。
  • データの一貫性/整合性
    • Microservicesは原則として、各サービスがそれぞれでデータを管理する必要がある。しかし、データ整合性/冗長性の課題が発生しうる。
  • ネットワークの輻輳、レイテンシ
    • 多くのサービスを使用すると、サービス間通信のオーバーヘッドが無視できなくなり、E2Eレベルでのレスポンスタイムが増える。
  • Complexity
    • 各サービスはシンプルであっても、サービスは全体として協調して動作する必要がある。1つの操作に複数のサービスが関連したり、サービスがサービスを呼び出したりすることがある。
  • クライアントとの通信
    • クライアントは直接各サービスを呼び出すべきか。それとも、APIゲートウェイパターンを採用するべきか。
  • モニタリング
    • 分散システムの監視では、複数のサービスを関連付けないと状況が把握できないため、モノリシックなアプリケーションよりも監視が煩雑になる。
  • CI/CD
    • Microservicesを採用するメリットのひとつに俊敏性があるが、そのためには迅速かつ確実に動作するCI/CDが必要である。

この記事ではMicroservicesの特徴、メリット、課題について記した。各課題に対するアプローチについて、別の記事で書いていこうと思う。