2021 年の State of DevOps アンケートに回答して、ソフトウェア デリバリーの未来を形作り、ご自分の意見を伝えましょう。

DevOps 技術: アーキテクチャ

DevOps Research and Assessment(DORA)チームの調査によると、アーキテクチャは継続的デリバリーを達成するための重要な予測要素です。Kubernetes とメインフレームのどちらを使用する場合でも、アーキテクチャによってより高度なソフトウェア配信パフォーマンスを促進するプラクティスを採用できます。

チームが継続的デリバリーのプラクティスを採用する場合、次のアーキテクチャのプラクティスを採用することで成果が向上します。

  • チーム外の誰かの許可を得たり他のチームに依存したりせずに、システムの設計に大規模な変更を加えることができる。
  • チーム外のユーザーとの細かなコミュニケーションや調整を必要とせずに作業を完了できる。
  • プロダクトやサービスを、依存するサービスやそれに依存する他のサービスには関係なく、オンデマンドでデプロイおよびリリースできる。
  • 統合テスト環境を必要とせずに、ほとんどのテストをオンデマンドで実行できる。
  • 通常の営業時間内にデプロイでき、ダウンタイムがごくわずかである。

このような成果はメインフレーム技術を使用して実現できますが、最新の最先端技術を使用しても達成できない場合もあります。多くの組織は、テクノロジーの導入に多くの時間と労力を費やしていますが、アーキテクチャによって制限されるため、重要なソフトウェア配信の成果を達成できていません。

チームが他のチームに依存せずにシステムをテスト、デプロイ、変更できるようにシステムのアーキテクチャが設計されていれば、チームは作業の完了にコミュニケーションをほとんど必要としません。つまり、アーキテクチャとチームの両方がゆるやかに結合されています。

このコミュニケーションの帯域幅とシステム アーキテクチャの関係は、最初に Melvin Conway 氏によって「システムを設計する組織は、その組織のコミュニケーション構造を反映した設計を生み出す」と説明されています。緊密に結合されたアーキテクチャに対処し、より良いコミュニケーション パターンをサポートするために、チームと組織は逆コンウェイ戦略を使用できます。これは、チームの構造とパターンが、期待されるアーキテクチャ上の状態を促進するよう設計されています。このように、チームのコミュニケーション パターンによって、構築されたアーキテクチャ パターンがサポートおよび適用されます。

密結合されたアーキテクチャでは、小さな変更によって大規模な障害が発生する可能性があります。そのため、システムの一部で作業するユーザーは、複雑で管理作業の多いチェンジ マネジメント プロセスを含め、システムの他の部分で作業する他のユーザーと常に協力する必要があります。

マイクロサービス アーキテクチャは、真のサービス指向アーキテクチャと同様に、これらの成果を可能にするはずです。実際には、多くのサービス指向と呼ばれるアーキテクチャでは、サービスを個別にテストしてデプロイすることはできないため、チームはより高いソフトウェア配信パフォーマンスを実現できません。サービス指向アーキテクチャとマイクロサービス アーキテクチャを実装する場合は、これらの成果を厳しく評価することが重要です。

継続的デリバリーのアーキテクチャを実装する方法

主要なアーキテクチャのアーキタイプについて考えてみましょう。App Engine の元エンジニアリング ディレクターであり、現在は WeWork のエンジニアリング担当バイス プレジデントである Randy Shoup 氏は、次の点を観察しました。

「あらゆるプロダクトと規模に対応する、完璧な 1 つのアーキテクチャは存在しません。アーキテクチャは、製品化までの時間、開発機能の容易さ、スケーリングなど、特定の目標や要件と制約の範囲を満たします。プロダクトやサービスの機能はほぼ確実に時間とともに変化します。アーキテクチャのニーズも変化することに驚きはありません。1 倍の規模で機能するものが、10 倍や 100 倍の規模で機能することはほとんどありません。」

アーキテクチャのアーキタイプの長所と短所を考えると、それぞれが組織の変化するニーズに適合します。

アーキタイプ 長所 短所
モノリシック v1
(1 つのアプリケーションですべての機能)
  • 最初はシンプル
  • プロセス間レイテンシが低い
  • 単一のコードベース、1 つのデプロイ ユニット
  • 小規模でリソース効率が高い
  • チームの成長に伴う調整のオーバーヘッドの増加
  • モジュール性が不十分
  • スケーリングが低い
  • オール オア ナッシングのデプロイ(ダウンタイム障害)
  • 長いビルド時間
モノリシック v2
(モノリシック層のセット: フロントエンド プレゼンテーション、アプリケーション サーバー、データベース レイヤ)
  • 最初はシンプル
  • 結合クエリが簡単
  • 単一スキーマのデプロイ
  • 小規模でリソース効率が高い
  • 時間の経過に伴う結合の増加傾向
  • スケーリングと冗長性が低い(オール オア ナッシング、垂直方向のみ)
  • 適切な調整が難しい
  • オール オア ナッシングのスキーマ管理
マイクロサービス
(モジュール、独立、グラフの関係または階層、分離された永続性)
  • 各ユニットがシンプル
  • 独立したスケーリングとパフォーマンス
  • 独立したテストとデプロイ
  • パフォーマンスの最適な調整(キャッシュ、レプリケーションなど)が可能
  • 多数の連携するユニット
  • 多数の小さなリポジトリ
  • より高度なツールと依存関係の管理が必要
  • ネットワーク遅延

表に示すように、無駄のないプロダクト開発作業(新機能の迅速なプロトタイピング、ピボットの可能性や戦略の大幅な変更など)をサポートするモノリシック アーキテクチャは、全員が顧客に独自の価値を提供できる必要がある、数百のチームの開発者が必要なアーキテクチャとは異なります。アーキテクチャを進化させることで、アーキテクチャが常に組織の現在のニーズを満たすようにできます。アーキタイプに関係なく、継続的デリバリーを容易にするためにアーキテクチャを実装する場合は、チームはこのドキュメントの導入部分で説明した機能を達成できるようにする必要があります。

組織(本番、開発、テスト、運用)の代表者による、機能横断的なチームを構築することで、チームは個別に取り組みながらチームの枠を超えた構築が可能になります。チームが機能分断的となると、自律的に機能可能となり、アイデアを試し独自のツールを選択できます。チーム間でのコミュニケーションとテストを支援するには、明確に定義されたサービス間の契約を用意するとよいでしょう。

チームの独立性は重要であり、プロダクトやサービスの独立性も重要です。サービスはオンデマンドでテストできる必要があります。外部サービスのモックとスタブに関する手法を採用することで、外部の依存関係の影響を軽減し、テスト環境をすばやく作成できます。また、外部サービスの契約テストを実装すると、サービスや他のサービスへの依存関係を確実に満たすことができます。真の継続的デリバリーを実現するには、個別のチームのプロダクトやサービスを、依存するサービスから独立してテストおよびデプロイできるようにする必要があります。

いつでもデプロイできるようにするには、高度な自動化を使用して、Blue/Green またはローリング デプロイ モデルを実装することを検討してください。これらのモデルでは、少なくとも 2 つ以上のバージョンのプロダクトやサービスが同時に実行されます。これらのデプロイモデルを使用すると、チームはダウンタイムをほとんどまたはまったく発生させることなく、変更を検証して本番環境にデプロイできます。重要な考慮事項は、データのアップグレード方法です。つまり、データとスキーマは下位互換性のある方法で処理する必要があります。

コンポーネントの独立したデプロイを支援するために、下位互換性のあるバージョン管理された API を作成することをおすすめします。API の下位互換性を確保すると、システムは複雑になりますが、デプロイの容易さという点では柔軟性が高くなり、複雑性の増加に見合うものとなります。

サービス指向およびマイクロサービス アーキテクチャでは、制限付きコンテキストと API を使用して、大規模なドメインをより小規模かつ緩やかな単位で結合し、サービスやコンポーネントを分離してテストする方法として、テストの二重化と仮想化を使用するため、これらの機能が実現します。

アーキテクチャのよくある落とし穴

  • 多数のサービスを同時にリリースする。テスト性とデプロイ性が優先されないチームでは、ほとんどのテストで複雑で高額な統合環境を使用する必要があります。多くの場合、デプロイでは複雑な相互依存が原因で多数のサービスを同時にリリースする必要があります。これらの「ビッグバン」型デプロイでは、チームは何百、何千ものタスク間で多数の引き渡しと依存関係を伴う作業をオーケストレーションする必要があります。ビッグバン型デプロイには通常数時間から数日かかり、かなりのダウンタイムをスケジュールする必要があります。

  • 何百、何千という他の開発者の変更を統合する。このような開発者は、相互接続された数十、数百、数千のシステムに依存している可能性があります。テストは不十分な統合テスト環境で行われ、多くの場合、取得と構成に数週間かかります。こうした環境は通常、本番環境を表すものではないため、テストの価値と精度が低下します。その結果、変更のリードタイムが長くなるだけでなく(通常は数週間または数か月)、開発者の生産性が低下し、デプロイの成果も低下します。

  • ソフトウェア配信プロセスのボトルネックを作成する。ボトルネックの例としては、手動プロセス(テスト、デプロイなど)またはサービス オペレーションの観点から、1 つのチームに他の多くのチームが依存している場合があります。どちらの例でも、こうしたボトルネックによって単一障害点が生じ、多くの依存するチームの需要を満たすために、チームやサービスをスケーリングする必要があります。

アーキテクチャを改善する方法

小規模な開発者チームが、独立してコードを安全かつ迅速に本番環境に実装、テスト、デプロイできるアーキテクチャにより、開発者の生産性が高まり、デプロイの成果が向上します。サービス指向のアーキテクチャとマイクロサービス アーキテクチャの主な特長は、コンテキストが制限されたゆるく結合されたサービスで構成されていることです。このような原則に基づく最新のウェブ アーキテクチャの人気のパターンセットに、Twelve-Factor App があります。

Randy Shoup による観察:

「Google や Amazon などのサービス指向アーキテクチャを採用した組織は、柔軟性とスケーラビリティに優れています。このような組織には数万人の開発者がいて、小規模なチームでも非常に生産性が高くなっています。」

多くの組織では、サービスのテストとデプロイが明らかに困難となっています。すべてを再構築するのではなく、企業システムの設計を改善するための反復的なアプローチをおすすめします。このアプローチは進化的アーキテクチャと呼ばれます。この方法では、プロダクトやサービスに対する要件が変化するため、これらの成功のためにはライフサイクル中に再構築する必要があります。

このコンテキストでの有益なパターンの 1 つに、ストラングラー フィグ アプリケーションがあります。このパターンでは、サービス指向アーキテクチャの原則に従って新しい作業が行われるようにすることで、モノリシック アーキテクチャをよりコンポーネント化されたアーキテクチャに反復的に置き換えます。新しいアーキテクチャは、置き換え対象のシステムに委任される場合があるので注意してください。時間が経つにつれて、新しいアーキテクチャでより多くの機能が実行されるようになると、古いシステムが置き換えられます。

モノリシック アーキテクチャをよりコンポーネント化されたアーキテクチャに置き換える。

プロダクトとサービスのアーキテクチャは常に進化しています。置き換えるべきモジュールやサービスを決定する方法は多数あり、プロセスは反復的です。特定の機能をサービスに追加するかどうかを決定するときは、次の特性があるかどうかを検討してください。

  • 単一のビジネス機能を実装する。
  • 他のサービスとの最小限のやり取りで機能を実行する。
  • 他のサービスから独立して構築、スケーリング、デプロイされる。
  • メッセージバスや HTTP エンドポイントなど、軽量の通信方法を使用して他のサービスとやり取りする。
  • さまざまなツール、プログラミング言語、データストアなどで実装可能。

マイクロサービスやサービス指向のアーキテクチャに移行することで、組織全体の多くの要素も変化します。Steve Yegge 氏は、プラットフォームの不満で、SOA への移行から学んだ重要な教訓をいくつか紹介しています。

  • 1 つのサービスで発生した問題が多数のサービス呼び出しから発生している可能性があるため、指標とモニタリングがより重要となり、エスカレーションがより困難になります。
  • 内部サービスはサービス拒否攻撃(DoS)の種類の問題を引き起こす可能性があるため、すべてのサービスで割り当てとメッセージのスロットリングが重要です。
  • モニタリングは包括的で、サービスのビジネス ロジックとデータを実行する必要があるため、QA とモニタリングは統合され始めます。
  • 多数のサービスがある場合、システムを効率的に運用するためにサービス検出メカニズムを用意することが重要になります。
  • デバッグ可能な環境でサービスを実行するための共通の標準がなければ、他のユーザーのサービスで発生した問題のデバッグはより困難になります。

事例紹介: Datastore

密結合のアーキテクチャによって、全亭が安全に変更を行うための生産性と可用性が妨げられる可能性があります。対象的に、ゆるく結合されたアーキテクチャでは、モジュールが互いにつながる方法を決定する明確に定義されたインターフェースにより、生産性と安全性が向上します。ゆるく結合されたアーキテクチャによって、小規模の生産的なチームが、安全かつ独立してデプロイ可能な変更を行うことができます。各サービスには明確に定義された API があるため、サービスのテストと、チーム間でのコントラクトとサービスレベル契約(SLA)の作成が容易になります。

ゆるく結合されたアーキテクチャ。

Randy Shoup 氏は、このアーキテクチャを次のように説明しています。

「この種類のアーキテクチャは、基盤にサービスのレイヤが 5 層や 6 層あり、各サービスが特定の機能を果たす Gmail のようなサービスの場合、Google に大きなメリットがあります。各サービスは、サービスを構築して機能を実行する小規模なチームによってサポートされており、各グループが異なるテクノロジーを選択する可能性があります。もう 1 つの例は、世界最大級の NoSQL サービスの 1 つである Datastore サービスです。その規模ながら、8 人程度のチームでサポートされています。これには、何層にも重なって互いの上に構築された依存するサービスのレイヤをベースとしていることが大きく寄与しています。」

このようなサービス指向のアーキテクチャにより、小規模なチームは、各チームが独立して迅速かつ安全にデプロイできる、より小規模でシンプルな開発単位で作業できます。

アーキテクチャの改善を測定する方法

ソフトウェア配信のパフォーマンスを向上させるには、メインフレームでもマイクロサービスでも、アーキテクチャの改善に必要な実践の促進が不可欠です(変更のリードタイムの短縮、サービスの復旧時間の短縮、変更障害率の低減による、デプロイ頻度の増大)。サービスとプロダクトの結合がゆるくなると、デプロイの頻度が上がります。改善を測定する場合は、デプロイ数ではなくデプロイ率を使用することを検討してください。デプロイ数は、サービスを追加するだけで増加するためです。最後に、問題を検出して復旧するまでの時間が短縮され、変更が本番環境に反映されるまでの時間が短縮されるはずです。

このデプロイとサービスの測定に加えて、より独立して業務を行うチームは、ジョブ満足度チームテストの向上が実証されており、ニーズに応じて異なるテクノロジーとツールを選択する傾向を示しています。

次のステップ