目次


マイクロサービス・アプリケーションにストラングラー・アプリケーション・パターンを適用する

実際のアプリにマイクロサービスを役立てる方法

Comments

読者の皆さんが私の同類であれば、新しい開発ツールや新しい開発手法や運用手法、あるいは新しいアーキテクチャーの原則に関する記事やブログを常に読み漁っていることでしょう。新しい手法や新しいアーキテクチャーの原則は紙上では素晴らしいアイデアのように思えます。あるいはまったく新しい (グリーンフィールド) アプリケーションに実装すれば見事な結果を生むかもしれませんが、既存のアプリケーションに実装する場合に必ずと言ってよいほど問題になるのは、その方法が明らかではないことです。

開発者の世界では、ブラウンフィールド・アプリケーション、つまり最新の手法に従って作成されたわけでも、最新のツールを使用して作成されたわけでもない既存のアプリケーションのほうが多数を占めています。この状況は、特にマイクロサービス・アーキテクチャーで顕著です。私が話をした開発チームのほとんどが、マイクロサービスは素晴らしいアイデアだと思うものの、現在巨大なモノリシック・アプリケーションを使用しているため、どのように導入すればよいのかわからないと言っています。

そのような状況に真に役立つソリューションを見つけたときの喜びは格別です。Martin Fowler 氏によるストラングラー・アプリケーション・パターンもそのようなソリューションです。彼がストラングラー・アプリケーション・パターンを作成したのはマイクロサービス・アーキテクチャーが開発される前ではあるものの、このパターンはマイクロサービス手法に移行しようとしている開発チームに素晴らしいガイダンスを与えます。

ストラングラー・アプリケーション・パターンとは何か

Martin Fowler 氏は 2004 年に彼が書いた記事の中で、大規模な Web アプリケーション内のコードをリファクタリングしてリリースする際の処理方法としてストラングラー・アプリケーション・パターンを定義しました。

ストラングラー・アプリケーションのベースとなっているのは、他の木の幹にぐるぐる巻き付いて締め殺して置き換わる「つる植物」との共通性です。概念としては、まず、Web アプリの構造 (Web アプリは、ビジネス・ドメインの別々の側面に機能上マッピングされている複数の個別 URI からなるという事実) を利用して、アプリケーションを異なる複数の機能ドメインに分割し、それらのドメインを 1 つずつ新しいマイクロサービス・ベースの実装で置き換えていけるよう準備します。これにより、2 つの別個のアプリケーションが同じ URI 空間内で共存することになります。そこからは、最終的にモノリシックなアプリケーションをシャットダウンできるようになるまで、徐々に新しくリファクタリングしたアプリケーションが元のアプリケーションを「締め殺す」、つまり置き換えていきます。したがって、ストラングラー・アプリケーションには、変換共存排除というステップがあります。

  • 変換: 既存のサイトと同等の新しいサイトを作成します (例えば、Bluemix 内、あるいは既存の環境内でも構いませんが、より新しい手法をベースにサイトを作成します)。
  • 共存: 既存のサイトをしばらく残しておきます。既存のサイトから新しいサイトにリダイレクトするために、機能を増分的に実装します。
  • 排除: サイトの古い機能からトラフィックがリダイレクトされるようになったら、既存のサイトからその機能を削除します (または単純に保守するのを止めます)。

このパターンを適用する場合の素晴らしい点は、新しい機能をリリースする前に「ビッグ・バン」的な移行によってアプリケーションのすべてのコードを更新しようとする場合よりも遥かに短い時間枠で徐々に価値を生み出せることです。さらに、ストラングラー・アプリケーション・パターンはマイクロサービスを導入する際の漸進的アプローチにもなります。つまり、使用している環境内でこのアプローチが有効でないことがわかったら、必要に応じて簡単に方向転換できます。

ストラングラー・アプリケーション・パターンが有効な場合と有効ではない場合

当然、あるパターンがあらゆる状況に適用されると前提することはできません。ストラングラー・アプリケーション・パターンを成功させるには、次の要件を満たしていなければなりません。

  • Web または API ベースのモノリスであること: これが第一の要件です。ストラングラー・アプリケーション全体の目的は、新しい機能と古い機能との間を簡単に行き来する手段が確保されるようにすることです。Web アプリケーションに取り組んでいるとしたら、そのアプリの URL 構造が、システムのどの部分をどのように実装するかを選択するためのフレームワークになります。一方、シック・クライアント・アプリケーションやそれと同様のネイティブ・モバイル・アプリケーションは、この手法にはそれほど適していません。これらのアプリケーションには、アプリケーションを同じ方法で分解するために使用できる構造があるとは限らないためです。
  • 標準化された URL 構造 (URL の正当な使用法) であること: すべての Web アプリケーションは、Web の構造 (例えば、HTTP や HTML の使用) によって課せられた何らかの標準に従って機能するとは言え、Web アプリケーションを実装するために使用できるアプリケーション・アーキテクチャーは何種類もあります。そうは言っても、この手法の枠内でも、裁量の余地がかなり残っています。例えば、(ポータル手法の場合と同じく) サーバー・リクエストの下に中間層があると、URL を使用してアプリケーションを分割する場合に問題になります。切り替えと経路指定の判断がブラウザー・レベルで行われるのではなく、アプリケーションの奥深くで行われるため、事態がより複雑になるからです。
  • メタ UI: UI が「メタ」UI (ビジネス・プロセス・ベースの UI や、臨機応変に組み立てられる UI) であるとしてもストラングラー・アプリケーション手法は有効ですが、この場合、分割後のチャンクのサイズが大きくなり、しかもすべてを同時に実装しなければならなくなります。そのため、生成フレームワーク全体の修正、あるいは少なくともマイクロサービスをベースとしていない現在のビジネス・モデルとのやりとりが行われるすべての部分の修正が必要になります。

悪いパターン適用方法

パターンが適用されるケースがあるように、パターンが適用されないケースや、少なくとも簡単には適用されないケースがあります。そのようなケースは以下のとおりです。

  • 1 ページずつ適用しないこと: 最も小さいスライバー (破片) は、単一のマイクロサービスです。一貫性の問題を回避するためには、データに 2 つの異なるデータ・アクセス・メソッドを使用しないようにする必要があります。
  • 一度に適用しないこと: アプリケーション全体を一度に変換するとしたら、それはストラングラー・パターンを適用していることにはなりません。

パターンをどのようにして適用するか

アプリケーション・リファクタリングの 2 つの異なる側面を交互に織り込む必要があります。つまり、マイクロサービス設計に合わせてバックエンドをリファクタリングするという側面 (内側の部分) と、マイクロサービスに対応するようにフロントエンドをリファクタリングして、そのリファクタリングの推進力となっている新しい機能的変更を行うという側面 (外側の部分) です。

内側の部分

  1. アプリケーション設計内でコンテキスト境界を識別する: Eric Evans 氏は自身の著書『エリック・エヴァンスのドメイン駆動設計』の中で、コンテキスト境界が「モデルを適用するコンテキストを定義する」と述べています。コンテキスト境界は、一連のビジネス・モデル内で数々のエンティティーの意味を制約する、共有概念フレームワークです。航空会社のアプリケーションを例に用いると、航空券の予約が 1 つのコンテキスト境界であり、航空会社のロイヤルティー・プログラムはまた別のコンテキスト境界になります。これらのコンテキスト境界で共有される用語 (「フライト」など) はあるとしても、その使い方と定義は、コンテキスト境界によって大幅に異なる場合があります。
  2. リファクタリングするのに最も小さく、最もコストがかからないコンテキスト境界を選ぶ: 他のコンテキスト境界に、最も単純なものから最も複雑なものの順でランクを付けます。リファクタリングの価値を証明するには (そして、このプロセスを導入する上での問題を振り落とすためには)、最も複雑でないコンテキスト境界からリファクタリングを開始し、その後で、より複雑な (そしておそらくコストがかかる) リファクタリング・タスクに取り掛かる必要があります。
  3. コンテキスト内でのマイクロサービスの概念的計画を練る: エンティティー・パターン、集約パターン、およびサービス・パターンを適用して、大まかな URL 構造とマイクロサービス全体の責任を計画します (Evans 氏)。この時点では、マイクロサービスのすべてを詳細に設計しようとしているわけではないことに注意してください!どのようなマイクロサービスが存在することになりそうなのかを把握して、その「推測」を以降のステップで適用できるようにすることが目的です。

外側の部分

ブラウンフィールド・プロジェクトの途中でストラングラー・アプリケーション・パターンを適用する計画を立てるプロセスは、複雑化する傾向があります。それは、バックエンドの実装を変更してマイクロサービスを具現化するだけでなく、プロジェクトの一環として、通常は多くのフロントエンド UI も変更することになるからです。実際、そもそもマイクロサービスを実装する動機となるのは、大抵はフロントエンドの変更です (例えば、サイトをシングルページ・アプリケーションとして、またはモバイル・アプリケーションとして実装するなど)。マイクロサービス・アーキテクチャーを使用する場合は、UI が最終的にどのような設計になるのか、あるいは UI チームがどのような先駆的な変更を実装するのかをあらかじめ正確に把握することはできません。ただし、設計の出発点として役立つ単純な仮定を立てることは可能です。

  1. 既存の UI 内で使用されている画面間の関係を分析する: これが実際に何を意味するのかと言うと、画面を一連の論理フローにグループ化する必要があるということです。フローは単純な概念であり、旅行 Web サイト内で飛行機を予約する、リテール Web サイト内でショッピング・カートの清算をするなど、単一のユーザー・タスクを実行する、ある画面から別の画面へとつながっている画面のグループを意味します。ここでの考え方は、UI 内には限られた数のフローがあり、各フローは、フローで操作対象としている概念を表す、一連の少数のマイクロサービスに対応することになるというものです。
  2. モデル操作の関連のある複数の側面に、「驚き最小の原則」を適用する: 驚き最小の原則は、ソフトウェア・エンジニアリングとユーザー・インターフェース設計に古くから適用されている古いルールであり、システムは大多数の人が最も自然と思える動作をしなければならないという考え方です。この原則に即した単純な仮定を立ててみてください。例えば、特定のドメインの側面を検索するフローがあるとしたら、当然このドメインのその側面を更新するフローを (現在ないとしても) 仮定できます。
  3. チャンクのサイズを決定する: チャンクの概念についてはこの後詳しく説明しますが、とりあえず、チャンクは関連するエピック (壮大な出来事) のグループであると考えてください。チャンクのサイズを決定する際に検討すべき課題は、ユーザーが単一のフロー内で操作することが理にかなっているのか、あるいはフロー相互のつながりが密接であるために、フローをグループ化して初めて、ユーザーが許容できる最小の要素になるのかという点です。例えば、プロファイル管理はリテール・サイトの他の部分とは密接なつながりがないため、プロファイル管理はサイトの他の部分から切り離して独立したフローにすることが理にかなっています。その一方、支払方法の選択を清算プロセスの他の部分から切り離して、支払にまったく別の UI を使用するのは妥当なことではありません。それは、驚き最小の原則に違反することになるためです。この原則に従うとしたら、支払方法の選択と清算を単一の論理ユニットにまとめるという結果に至るでしょう。
  4. チャンク全体を一度にリリースするのか、あるいは各チャンクを一連のスライバーとしてリリースするのかを選択する: この側面については、次のセクションで取り上げます。

ストラングラー・マイクロサービスのリリース・プロセス

Bluemix Garage メソッドのなかで、私たちは作業を編成するためにアジャイル手法から一定の概念を採用しました。例えば、ヒル (希望の丘、MVP 定義) は開始プロセスを通じて、それぞれに個別に実装可能な MVP 要素を表す複数のユーザー・ストーリーに分割されます。相互に関連する複数のユーザー・ストーリーは、上位レベルのシステム機能を説明するエピックにグループ化されます。

この結果、ストラングラー・アプリケーション・パターンを適用してシステムを徐々に置き換えていくという課題に立ち戻ります。複数のエピックをチャンクにグループ化し、実装の制約によるか、初期の大規模なロールアウト単位になるユーザー・エクスペリエンスの関係によって、複数のチャンクを結合します。ほとんどの場合、1 つのチャンクはユーザー・タスクを定義する 1 つの UI フローによって境界づけられ、このフロー内のすべての要素は一貫した方法で実装します。

エピックは、スクワッド (少人数のチーム) によって実装されます。1 つのスクワッドがチャンクに含まれる 1 つ以上のエピックを実装することもありますが、スクワッドが実装を担当する最小の要素はエピックです。スクワッドはエピックを定義するユーザー・ストーリーを進行中のバックログに追加します。バックログでは、実装の優先順位に応じてユーザー・ストーリーにランクが付けられます。

一方、一連のスポンサー・ユーザーからすぐにフィードバックを受けるには、チャックはまだかなり大きいロールアウト単位です。そのため、私たちはフィードバックを受けるために内部で使用できる、サイズを小さくしたリリース要素を定義しています。スライバーは、マイクロサービスとそれらのマイクロサービスを中心とした変更を統合してエンド・ユーザーの使用に適した状態にする最小リリース単位です。チャンクがバスや飛行機のチケットを予約するためのフロー全体であり、このフローを実装するためにはすべてのマイクロサービスが必要であるとしても、1 つのスライバーは、そのフロー内の 1 つのステップ (例えば、チケット予約の確認メッセージを表示するステップ) と、その確認を取得するために必要な 1 つのマイクロサービスを表す単一のページにすることができます。つまり、複数のスライバーからチャンクを構成し、スライバーを次々と限定公開してフィードバックを得たうえで、チャンクの表しているタスク全体が実行可能になった時点になって初めてエンド・ユーザーにチャンクをリリースするという仕組みを採用できます。

まとめ

この記事では、ストラングラー・アプリケーション・パターンを適用する際に派生する問題として、このパターンが適用される場合と適用されない場合、そしてリリース管理に与える影響について説明しました。また、Bluemix Garage のコンサルティング業務内で使用している用語のうち、皆さんのお役に立ちそうな新しい用語をいくつか紹介しました。この記事で特に焦点を当てたのは、ストラングラー・アプリケーションを適用する際のマイクロサービス開発の計画プロセス、そしてアプリケーションの機能リリースを管理するプロセスです。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Cloud computing
ArticleID=1045861
ArticleTitle=マイクロサービス・アプリケーションにストラングラー・アプリケーション・パターンを適用する
publish-date=05182017