【Event-Driven Architectureへの道】レガシーシステムからマイクロサービスへ段階的に移行するには?(ストラングラーパターン)
この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。
はじめに
マイクロサービスアーキテクチャへの移行には様々な設計パターンが存在します。その中でも、一般的でよく語られるストラングラーパターンについて見ていきます。
このパターンは、モノリシックな、古いシステムとマイクロサービスやイベントドリブンなどの新しいシステムを共存させ、新しいシステムを作り上げながら、古いシステムを徐々に置き換えていくものです。
このパターンのメリットは、新しいシステムへの段階的な移行ができることです。既存のエンタープライズシステムなどは24時間365日稼働しており、一度で全てをマイクロサービス化することは不可能なため、徐々にサービスとして切り出していけるストラングラーパターンは魅力的なパターンとなります。
既存システムを分割しマイクロサービスアーキテクチャに移行する部分はかなり難易度が高く、最終的に分割仕切れずに断念してしまう可能性もあります。このため、既存の分割よりも新規サービスを既存と分割するスタイルの方が現実的であるともされてます。
ここでは、ストラングラーパターンを深掘りしていきながら、イベントドリブンアーキテクチャーと合わせてマイクロサービスの移行について触れていきます。
ストラングラーパターン
ストラングラーパターンは、特定の機能を新しいアプリケーションやサービスに徐々に置き換えることで、既存システムを段階的に移行する方法です。
既存システムとユーザーのフロントエンドの間に、データを振り分けるストラングラーファサードを設置し、ステップごとに一部の機能を切り出してマイクロサービス化し、新しいシステムとして稼働させていきます。
下記に簡単な例を示します。単一のモノリスである既存サービスが4つ存在する場合、そこから、一つずつ機能を切り出して、サービスとして稼働させ、その後、順次3つの機能を分割していく流れとなります。
ストラングラーファサード
ストラングラーファサードは、新しいコンポーネントやサービスを導入し、既存のコードと連携するための仲介層を提供し、プロキシと同様に複雑な基本コードまたは構造コードをマスキングするためにインターフェイスとして機能するオブジェクトです。既存のコードとの相互作用を制御し、段階的な移行を支援するために使用され、HTTPリバースプロキシ、API Gateway と組み合わせて使用することがあります。同じものではありませんが、一旦ここでは総称します。
ストラングラーファサードは新しいサービスと既存のサービスとのアクセスの振り分けを担当し、HTTPリバースプロキシやAPI Gateway は、トラフィック制御やセキュリティの向上のために使用されます。HTTPリバースプロキシやAPI Gateway がストラングラーファサードの一部として機能することがあります。
API Gatewayは、クライアントとAPI群(今回では在庫管理のサービス)の間に設置される、APIリクエストを各アプリケーション(モノリスおよびマイクロサービスアプリケーション)へルーティングするアプリケーションのことです。API Gateway として利用される技術としては、 Kong、Amazon API Gateway、Spring Cloud Gateway 等があげられます。
次に具体的な流れの例として、在庫管理システムに存在する複数のサービスの中から、一つのサービスをマイクロサービス化する流れを説明します。サービスの中から機能グループを抽出し、その中でも抽出の単位を小さくして、他の機能との連携が少ないものを選定することが奨励されます。今回の在庫状況サービスがそれにあたるものと想定します。
ステップ(0):切り出すサービスを決定します。システムの中でも他のサービスからのデータ参照が密になっている場合には、最初のステップには向かない場合があります。このため、ステップ0で切り出すサービスは他のサービスとの関係性を把握した上で決定する必要があります。先に述べたように今回は在庫管理を対象としているので中でも比較的、他のサービスからデータ参照が少ない在庫状況サービスを対象とします。
ステップ(1):在庫状況サービスを呼び出す元のサービスがHTTPが中心となるため、モノリスから切り出してストラングラーファサードの配下に起きます。こうすることで切り出した後のHTTPリダイレクトが可能となり、HTTPプロキシが受信したリクエストも把握でき、適切に割り振ることも可能になります。
前述の通りストラングラーファサードとして、現行システムに再利用できるHTTPリバースプロキシやAPI Gatewayが存在すれば最初にステップとして流用することもできます。
ステップ(2):在庫状況サービスを、モノリスの状態の在庫管理から機能およびデータを切り出して、ストラングラーファサードによりクライアントからのアクセスをリダイレクトします。サービスの機能も段階的に分けて実装し、並行稼働するような段階的リリースとデプロイも可能になります。
上記では、サービスの機能を段階的に分けて実装して完了した1つのマイクロサービスとなっているが、実際にはそう簡単にはいかないケースも多々あります。例えば、他のサービスが在庫状況サービスのデータを参照しないと整合性が取れない場合、その整合性の解決が直ぐにできない場合に、一部はマイクロサービスに実装し、モノリスにある機能とマイクロサービスにある機能から同じデータを参照する必要があります。この際に共有データベースを利用するパターンは、モジュラモノリスと呼ばれます。
ストラングラーパターンでマイクロサービスへの移行の際に、新しいサービスに切り替えた後に問題が発生して、元に戻したい場合があります。この移行中に一部を戻したい場合は、ストラングラーファサードで呼び出し先を元のサービスに戻すことで対応することができます。
データーベースの分割におけるデータ同期
モノリス側の既存サービスがマイクロサービスによりデータベースが分割されたマイクロサービス側のデータを参照する必要があることもあります。このような場合にはデータベース間のデータ同期を利用することも一つの方法です。
データ同期には何パターンか存在しますが、モノリスかマイクロサービスどちらかが両方のデータベースに対して書き込みを行うか、2つのデータベースビュー間で一貫性を保ってしまうパターン(共有データベース)などがあります。
上記のような事例が1つのサービスでできれば、あとは段階的にマイクロサービスへ順次移行していく計画を立て、実行していく流れとなります。全てのモノリスがマイクロサービスへ移行することができればステップは完了となります。
ストラングラーパターンとEvent-Driven Architecture
Event-Driven Architecture(EDA)の導入においてもストラングラーパターンの考えを利用して進めることができます。Event-Driven Architecture(EDA)は、これまでも他のブログ記事で紹介してきましたが、サービス間はAPI呼び出しで連携するのではなく、あるサービスが発行した状態の変化(イベント)を、その変化に対応する必要があるサービスが反応することで業務プロセスが実施されるアーキテクチャです。メリットとしては、スケーラビリティが高く障害に強く、新しい機能やサービスを追加する際に、既存ドメインの実装部分にインパクトを与えることがありません。
ここでは、Event-Driven Architecture(EDA)におけるストラングラーパターンでのマイクロサービス化のステップについて記載していきます。イベンド・ドリブンアーキテクチャを用い、既存ドメインの実装にインパクトを極小化するためのアーキテクチャの検討と実装を行う上で全体の概要図を記載します。
まず、ステップ0では、既存システムの一部ドメインを対象に抽出して、新サービスの機能追加を行います。
ステップ1では、既存のDBからのイベント抽出と、イベントを仲介する基盤(イベントブローカー)の導入を行います。この例では既存DBにはほぼ手を加えることなくイベントを抽出するためにCDC(Change Data Capture)を利用します。イベントブローカーとしてKafkaやSolace等が有名です。こちらについては別記事で紹介予定です。
次のステップ2では、マイクロサービスにDBを内包するために、マイクロサービス内のDBの設計と、既存DBからのデータ同期方法の設計と実装を行います。
次のステップ3では、送られてくるイベントとドメイン内DBを利用したマイクロサービス(新しい業務ロジック)を実装します。既存サービスの呼び出しが必要な場合には既存サービスを直接呼び出すのを避けて、腐敗防止層(ACL:Anti Corruption Layer)を用い抽象化してアクセスします。既存サービスも段階的にマイクロサービス化を行う前提の場合、ACLを用いることで既存サービスの変更が発生しても影響受けにくくすることができます。
ACLは一般的には以下のコンポーネントから構成されます。
- 外部サービスから情報を取得するためのClient
- 取得した値を変換するtranslator
- 変換されたものをラップするadaptor
次のステップ4では、マイクロサービスを実際の業務で利用します。この際に既存DBからのデータの同期をやめマイクロサービス側がDBが主となります。(シングルソースの移行)
更にステップ5では、送信元のサービス、受信元のサービスも直接イベントを伝えて接続します。こうすることで既存サービスを段階的にイベント・ドリブンアーキテクチャ化し、またイベント・ドリブンアーキテクチャを全体に広げることができるようになります。
まとめ
今回の記事では、マイクロサービスアーキテクチャへの移行と、その中でもストラングラーパターンについて説明しました。ストラングラーパターンは、古いシステム(モノリス)と新しいシステム(マイクロサービス)を一時的に共存させ、段階的に古いシステムを新しいものに置き換える設計パターンで、メリットとして段階的な移行が可能であることが挙げられます。古いシステムを分割する難しさはマイクロサービス化ではつきまといますが、ストラングラーパターンを用いることでリスクを低減してマイクロサービス化の知見を溜めて導入を進めることができます。
イベントドリブンアーキテクチャでは同様の考え方で同じ用に段階的に移行することがポインとなります。ストラングラーパターンの理解により、今回の記事が皆さんの「Event-Driven Architecture」の興味や導入のきっかけにつながれば大変嬉しいです。