前置き
モノリシックからマイクロサービスに変える際に、避けて通れないのが、
2PC(二相コミット)から結果整合にし、トランザクション制御をアプリケーションコードとして自前実装しなくてはならない点です。
以下の記事で軽く触れはしたものの、詳細には触れていなかったので、
ここで改めて詳細に振れていきたいと思います。
前提知識
ここで前提として、段階的に可逆性を担保させて移行する
「ストラングラー・ファサード(Strangler Facade)」 と呼ばれるものを軽く紹介しておきます。
結構マクロなアーキテクチャをリアーキしたりする時に、可逆性を担保させたまま、
安全にかつ段階的に移行させる際に、ほぼ頻出している設計パターンです。
ストラングラー・ファサードはプロキシ層です。
全ての外部リクエストの唯一の入り口となり、リクエストの内容に応じて、古いシステム(例:モノリス)に流すか、新しく構築したシステム(例:マイクロサービス)に流すかを判断します。
そして、図のように段階的に移行していき、最終的に古いシステムは削除する感じです。
段階的サーガへの移行
2PC(二相コミット)からサーガへの移行は、稼働中のシステムの心臓部を手術するような、非常に繊細でリスクの高い作業です。
そのため、ストラングラー・フィグ・パターンを用いた、安全な段階的移行が不可欠となります。
前提:移行前の状態
現在の状態
注文サービス、決済サービス、在庫サービスが、2PCコーディネーターによって同期的にロックされ、アトミックなトランザクションを実現している。
現在の課題
2PCによる同期ロックが、システムのパフォーマンスを低下させ、障害時の復旧を困難にしている。
ステップ1:分析とサーガの設計
まず、移行の準備をします。
①. 現行トランザクションの徹底的な分析
現在2PCで管理されているビジネスプロセスを完全に理解します。
どのサービスが、どの順序で、どのようなデータの読み書きを行っているかをドキュメント化します。(図解の方がオススメ)
②. 新しいサーガの設計
現行のプロセスを、サーガパターンで再設計します。
オーケストレーション型を採用し、新しいサーガ・オーケストレーターを定義します。
プロセスの各ステップ(例: 決済の実行)と、
それに対応する補償トランザクション(例: 決済の取消)を明確に定義します。
この時、対称性原理を意識したら【取消】というビジネスユースケースが
あぶり出しやすいです。
ステップ2:補償トランザクションと新APIの実装
次に、新しいサーガで必要となる「部品」を、既存のサービスに追加します。
補償APIの実装
決済サービスにcancelPaymentAPIを、在庫サービスにreleaseStockAPIを、それぞれ追加で実装します。
これらは、何か問題があった際にサーガが呼び出すためのものです。
新APIの準備
新しいサーガから呼び出されるためのAPIを、既存のAPIとは別に用意します。
(例: /v2/processPayment)
重要
この段階では、既存の2PCで使われているAPIやロジックには一切手を加えません。
新旧のロジックがサービス内に共存している状態になります。
絶対にここですぐに既存の2PCで使われているAPIやロジックを消すってことはしないでください。
ステップ3:プロキシの導入とサーガの実装
ここからが、ストラングラー・フィグ・パターンの核心です。
①. トランザクション・プロキシの導入
既存のシステムへのリクエストを全て受け付ける、新しいトランザクション・プロキシサービスを導入します。
最初は、このプロキシは何もせず、全てのリクエストをそのまま既存の2PCの仕組みに転送するだけです。
②. サーガ・オーケストレーターの実装
ステップ1で設計したロジックを持つサーガ・オーケストレーターを実装します。
このオーケストレーターは、ステップ2で追加した新しいAPIを呼び出すように作ります。
ステップ4:段階的なトラフィックの移行
プロキシを使って、トラフィックを徐々に新しいサーガへと流し始めます。
①. 一部のリクエストを新方式へ
プロキシのロジックを修正し、特定の条件(例: 社内ユーザーからのリクエスト、
特定の低リスクな商品カテゴリの注文など)に合致するリクエストだけを、新しく実装したサーガ・オーケストレーターに転送するようにします。
それ以外の通常のリクエストは、引き続き既存の2PCの仕組みへ転送します。
②. 監視と検証
新しいサーガで処理されたトランザクションが、正しく完了しているか、問題発生時に補償トランザクションが期待通りに動くかを、入念に監視・検証します。
③. トラフィック割合の増加
新しいサーガの安定性に自信が持てたら、プロキシの設定を変更し、サーガへ流すリクエストの割合を徐々に増やしていきます。(例: 1% → 10% → 50% → 100%)
ステップ5:古い仕組みの解体
全てのトラフィックが、新しいサーガの仕組みで処理されるようになったら、移行は完了です。
旧ロジックの削除
誰も使わなくなった既存の2PCコーディネーターと、関連する古いAPIを安全に削除(解体)します。
この手順を踏むことで、稼働中のシステムを止めることなく、リスクを最小限に抑えながら、システムの心臓部を新しいアーキテクチャへと安全に入れ替えることができるのです。