🐚

精読「モノリスからマイクロサービスへ (3)」

2025/01/20に公開



モノリスからマイクロサービスへ ―モノリスを進化させる実践移行ガイド
従来のモノリシックアーキテクチャを現代のビジネスニーズに適応させるための実践的な移行手法を網羅した一冊です。本書では、マイクロサービスの基本的な概念や利点だけでなく、移行プロジェクトで直面する課題とその解決方法を具体例を交えながら解説しています。

また、技術的なアプローチだけでなく、組織的・文化的な側面にも焦点を当て、チーム全体でのスムーズな移行を支援します。実務で活用できる戦略やツール、ステップバイステップのガイドを提供しているため、モノリスに課題を感じている開発者やアーキテクト、プロジェクトリーダーに最適です。

これからのシステム開発に必要なスキルと知識を身につけ、進化するシステムの未来を切り拓きたい方にぜひおすすめしたい一冊です。

関連記事

成長の痛み

マイクロサービスアーキテクチャを採用する過程では、さまざまな困難に直面する。この章では、それらの問題を詳しく掘り下げ、事前に警戒しやすくすることを目指している。全ての問題を解決するわけではないが、問題が発生しやすいタイミングや対処の必要性を判断するための兆候も紹介する。

サービスが増えれば痛みも増える

マイクロサービスアーキテクチャの導入では、サービス数の増加や組織の規模、技術選択などの要因で問題が発生するタイミングが異なる。特にサービス数は、問題がいつ顕在化するかを示す有力な指標となる。マイクロサービス化は段階的に進むものであり、その過程で新たな課題に直面し、それを解決するためのスキルや技術が求められる。

この章では、問題が発生しやすいタイミングや要因、解決のポイントについて詳しく解説していく。これにより、マイクロサービス導入時に潜在的な落とし穴を事前に認識し、適切に対応する助けとなる。

所有権のスケール

問題の発生

  • 開発者やサービスが増えると、共同所有モデルでは方向性や基準の統一が難しくなる。
  • 急成長企業では「分散モノリス」が生じやすい。

解決策

  • 強いコードの所有: チームごとに特定のサービスを管理し、基準を独自に設定。
  • プロダクト指向: ドメインごとにチームが集中し、プロダクトオーナーが指針を提供。

破壊的変更

マイクロサービス間の契約を変更する際、後方互換性を損なうと、システム全体に影響を与える可能性がある。この問題に対応するためには以下のポイントが重要である。

  1. 偶発的な破壊的変更の防止
    スキーマやテストを活用して変更の影響を早期に検出する。開発者に契約変更を明示させる。

  2. 変更の慎重な検討
    可能な限り契約を拡張し、既存のコンシューマーに影響を与えない変更を選ぶ。

  3. 移行期間の提供
    並行して新旧の契約をサポートし、コンシューマーが移行する時間を確保する。

これらを徹底することで、マイクロサービスの独立性を保ちながら変更によるリスクを最小限に抑えられる。

レポーティング

モノリシックなシステムでは、単一のデータベースでレポーティングが容易に行われるが、マイクロサービスではデータが分散するため、レポーティングが困難になる。

この問題の発生

  • データの分散により、大規模な結合操作が必要となる。
  • 初期段階で考慮されないことが多く、ステークホルダーにとって意図しない影響を与える。

解決策

  1. 専用レポーティング用データベース
    マイクロサービスのデータストレージとは別に、レポーティング用のデータベースを設置する。

    • ユーザー要件に応じてスキーマを設計可能。
    • マイクロサービスからデータを「プッシュ」して同期を保つ。
  2. 技術的アプローチ

    • 変更データキャプチャ:変更されたデータをリアルタイムで取得し、レポーティング用に反映する。
    • データベースビュー:複数のデータベースから単一のビューを提供。
    • 中間コンポーネント:イベント駆動でレポーティング用データベースを更新。

これらの方法で、分散されたデータを効率的に統合し、レポーティングの課題を解消できる。

監視とトラブルシューティング

問題発生のタイミング

  • モノリスからマイクロサービスに移行することで、問題の発生を予測することが難しくなり、開発者やテスターは本番環境前に潜在的な問題を発見し対処する必要がある。

問題の現れ方

  • 監視ツールのアラートが発生するものの、問題が本当に重要なものなのか判断がつかないケースや、実際に何が起きているのかが理解できないことがある。

解決策の提案

  • ログ集約

    • マイクロサービスアーキテクチャでは、ログが分散しているため、ログ集約システムを使用して中央でログを管理し、検索可能にすることが推奨されている。これにより、問題を迅速に把握できる。
  • トレーシング

    • 各サービス間の呼び出しを追跡することで、どのサービスがボトルネックになっているのか、どこで問題が発生しているのかを明確にできる。相関IDを使用して、トレーシングを行うことでフロー全体を監視する。
  • 本番環境でのテスト

    • 本番環境でも動作確認を行い、問題が発生した場合に備えることが重要です。人工的なユーザー行動をシミュレートすることで、予期せぬ問題を事前に発見できる。

可観測性

  • システムが複雑になれば、どんな問題が発生するか予測するのが難しくなるため、問題が発生したときにシステムについて深く掘り下げて調査できる情報を収集することが求められる。

開発者体験

開発者体験は、マイクロサービスが増えることで低下する可能性がある。JVMなどリソース集約型のランタイムでは、手元で実行できるサービス数が限られ、開発が遅くなることがある。

問題の現れ方:サービスが増えると、ビルドや実行に時間がかかり、開発者は強力なマシンを要求するようになるが、根本的な解決にはならない。

発生タイミング:リソース消費の多いサービスほど、問題は早く発生する。

解決策:サービスをスタブ化する、リモートで実行する方法(例:Telepresence、Azure Functions)を活用し、ローカルとリモート環境をハイブリッドで使うことで、開発者体験を改善できる。

あまりにも多くのものを実行している

サービス数が増え、インスタンスも増えれば、デプロイや設定、管理が複雑になり、モノリシックアプリケーションではスケールできない可能性がある。特に、望ましい状態の管理が重要になり、マイクロサービスが増えると、手動の管理は限界を迎える。

問題の現れ方:デプロイやトラブルシュートに時間がかかり、運用チームの増員が必要になることも。

発生タイミング:スケールに伴い、手動や従来のツールでは対応しきれなくなる。

解決策:高度な自動化が必要。Kubernetesなどを使うことで、複数のマシンにまたがるサービスの管理が可能になり、運用の負担を軽減できる。また、FaaSなどのサーバーレス技術を先に試す「サーバーレスファースト」のアプローチも有効。

エンドツーエンドテスト

課題

  • エンドツーエンドテストの範囲が広くなることで、テストの実行時間が長くなり、失敗時に問題を特定するのが難しくなる。
  • 複数のサービス間でのテストは非常に複雑になり、失敗の原因が環境に依存する場合も多く、マイクロサービスではより多くの制御外の問題に直面しやすい。

解決策

  1. 自動化された機能テストの範囲を制限

    • テストケースは各サービスの管理チーム内で行うようにし、チーム間での大規模なテストを避ける。
    • これにより、テストの所有権が明確になり、テストのカバレッジも明確化される。
  2. コンシューマー駆動契約(CDC)

    • マイクロサービスのコンシューマーに期待する動作を定義してもらい、サービスが変更されても合格するようにする。
    • Pactなどのツールを使うことで、これらのテストを管理しやすくする。
  3. 自動化されたリリース修正とプログレッシブデリバリー

    • 本番環境に影響を及ぼす前に問題を発見し、プログレッシブデリバリー(段階的な公開)を使ってリスクを最小化する。
    • 例えば、カナリアリリースや、許容される基準を定義して、問題が発生した際に自動的にロールバックする仕組み。
  4. 品質フィードバックサイクルの改善

    • どこでどのようにテストすべきかを継続的に見直し、無駄なテストを削除することで、フィードバックサイクルを効率化する。

これらのアプローチは、テストの範囲を管理し、実行効率を高めると同時に、テストが失敗した際の問題追跡を簡単にするための方法。

全体最適と局所最適

マイクロサービスアーキテクチャにおける「全体最適」と「局所最適」のバランスが問題になる。各チームが独自に決定を下すことで一貫性が欠け、効率が悪化する可能性がある。特に、組織が成長するにつれて、チーム間で異なる方法で問題を解決し、非効率が生じる。解決策としては、意思決定を可逆的・不可逆的に分け、チーム間のコミュニケーションを促進することが挙げられる。

堅牢性と回復性

ネットワーク障害やシステムの不安定さが本番環境で頻繁に発生することがあり、従来の開発・テストサイクルではそれに十分に対応できないことがある。システムの規模が大きくなると、回復性の問題が増え、カスケード障害やバックプレッシャーといった問題に直面しやすくなる。

解決策としては、非同期通信やタイムアウトの適切な設定、サーキットブレーカーなどを使用してサービスを分離し、障害に迅速に対応することが重要。また、サービスの複数インスタンスを活用して、サービスの死滅を防ぐことが有効。回復性は単に対策を実施するだけでなく、問題発生時に学び、組織全体で対応能力を進化させることが求められる。

孤児サービス

マイクロサービスの中には、長期間放置されていても正常に動作しているものがあり、それらの所有権が不明確な場合がある。こうしたサービスは「孤児サービス」と呼ばれ、管理するべき責任者が不在なため、問題が発生した際にどのように対処すべきか分からないことが多い。

この問題は、長期間にわたってマイクロサービスを運用している組織でよく見られる。サービスの担当者が辞めてしまったり、サービスがどこで管理されているか忘れられたりするため。

解決策としては、サービスの共同所有を実践している組織は孤児サービスの問題が少ないとされている。共同所有では、サービスの変更や管理を複数のチームが行うため、サービスに関する情報が共有されやすくなる。また、社内でサービスのレジストリを作成し、サービスのメタデータを収集・照合することで、誰がそのサービスを管理しているのかを把握できるようになる。

この章のまとめ

この章の主旨は、問題が発生する前に予見することができるということ。そして、問題が起きる前に解決策を講じることと、絶対に発生しないであろう問題に過度に時間を費やすこととのバランスを取る重要性を伝えている。

終わりに

2つの重要なメッセージ。

  • 1つ目は、適切な情報を収集し、他者の真似を避けて、自分の問題に合った合理的な意思決定を行うこと。
  • 2つ目は、マイクロサービスは段階的に導入すべきで、時間をかけて自分のコンテキストに合った方法を見つけることが重要。

参考


Discussion