動的ルーティングインフラ、その先にある課題
前回は、Spring Cloud Gateway(以下、SCG)を活用し、従来の硬直した静的YAML設定構造から脱却して、データベースベースの無停止動的ルーティングアーキテクチャを構築する過程について説明しました。インフラの中核となる設定要素をアプリケーションのビジネスデータ領域へ移行することで、システムの再ビルドやデプロイを行わず、運用中にリアルタイムでルーティングルールを変更できる柔軟性を確保しました。これは、複雑なマルチベンダー環境において、各開発会社間のデプロイ時期のずれやエンドポイントの変更に柔軟に対応できる強力な緩衝地帯となりました。
しかし、実務の観点から見ると、無停止の動的ルーティング環境を完成させたことは、巨大な目的地へ向かう第一歩にすぎませんでした。インフラレベルでトラフィックの通路を柔軟に開いた瞬間、分散マイクロサービスアーキテクチャ(MSA)環境が直面する、より本質的で深刻な実務上の課題が表面化したためです。その中心には、数十の分断されたサービス上でどのように共通のセキュリティ標準を維持するのか、そして特定の時点で予測不能に押し寄せる大規模トラフィックから内部システムをどのように安全に保護するのかという、2つの重要な課題がありました。それが、「セキュリティ機能の中央集約」と「システム可用性確保のためのトラフィック制御およびキュー管理」です。
今回は、前回設計したGatewayRouteドメインモデルと動的インフラを基盤として、統合認証・認可フィルターの実装過程と、大規模トラフィックを安定的に受け入れて制御するキュー管理サービスの実装戦略について、詳しく解説します。
統合認証および認可(Authorization)フィルター
MSAをマルチベンダー環境で運用する際、最初に直面する技術的なアキレス腱は、まさに「セキュリティ標準の統一性」です。ドメインごとに専門化された複数の開発会社が、それぞれのマイクロサービスを独立して開発・デプロイする構造では、認証(Authentication)と認可(Authorization)の仕組みが各サービス内部に分断されやすくなります。特に本プロジェクトで構築したインフラは、外部との無秩序な接触を遮断した内部閉域網環境でした。そのため、内部マイクロサービスのネットワークトポロジー(Topology)を外部連携接点に直接公開することなく、すべての受信リクエストの身元を一貫して検証し、ビジネス権限に応じて完全に制御する強力な「セキュリティゲート(Secure Gate)」が不可欠でした。各サービスがビジネスロジックに純粋に集中できるようセキュリティ上のオーバーヘッドを完全に取り除き、システム全体のセキュリティレベルを引き上げて同期させるため、Spring Cloud Gatewayレイヤーにグローバルな非同期認証・認可フィルターを実装しました。
第一に、Spring Cloud Gatewayは内部的にSpring WebFluxとNettyエンジンを基盤とするリアクティブ(Reactive)アーキテクチャを採用しています。そのため、1スレッドで1リクエストを処理する従来のサーブレット(Servlet)ベースの同期フィルターではなく、少数のイベントループ(Event Loop)スレッドで大規模な同時接続をノンブロッキング(Non-blocking)に処理できるリアクティブWebフィルター(WebFilter)の設計が求められます。実装した統合認証・認可フィルターは、単純なJWT(JSON Web Token)の復号にとどまらず、複数ベンダー間の複雑な連携仕様を単一のフィルター内で有機的に仲介し、データベースベースでAPIパスごとに許可されたサービスとリアルタイムにマッピングして認可制御を行います。この複雑なフィルターアーキテクチャが、ノンブロッキングAPIゲートウェイ環境で一度の遅延もなく安定かつ迅速に動作できた秘訣は、リアクティブストリームの特性を完全に理解し、適切な場所に配置した3つの中核的な技術要素にあります。
第二に、複数の連携仕様を透過的に受け入れるための動的トークンスワップおよびプロトコルアダプターメカニズムです。このフィルターは、単なるゲートウェイの入口にとどまらず、複数の開発会社とレガシープラットフォームが絡み合う内部閉域網の通信仕様を柔軟に仲介する集中型アダプターとして機能します。マルチベンダー環境では、各システムが求める認証情報の仕組みがそれぞれ異なることが多くあります。これをクライアント側で個別に対応させるのではなく、ゲートウェイがリクエストの宛先を把握し、ダウンストリームサービスが求める形式へリクエストを動的かつリアルタイムに変換するよう設計しました。特にレガシープラットフォームとの連携時には、外部の元トークンを検証した後、内部のビジネスドメイン間通信に必須となる専用インフラトークンをバックグラウンドで動的に発行し、新しい認証情報でヘッダーを置き換えてリクエストを転送する動的トークンスワップアーキテクチャを実装しました。その結果、複数の開発会社およびレガシーインターフェースが強制する、相違があり複雑な認証・認可仕様をゲートウェイレイヤーの下に完全に隠蔽でき、内部システム間の結合度をかつてない水準まで低下させることができました。
第三に、ノンブロッキングログ処理プロセスです。セキュリティ上の機密性を維持するためのログ(GateLogCdo)蓄積プロセスは、メインルーティングストリームの応答速度に悪影響を与えないよう、極めて精密に分離されています。これは、監査ログをデータベースへ書き込み、ネットワークへ送信するI/Oオーバーヘッド全体を、メインのランタイムフローから完全に分離された独立したバックグラウンドスレッドプールへ委譲する構造です。これにより、ログ蓄積の遅延によって1件のリクエストも応答が遅れることを根本から防ぎ、ゲートウェイ本来の役割であるセキュリティ検証とルーティング仲介機能を完全に維持するアーキテクチャを構成できました。
キュー管理システム
MSA環境では、特定ドメインサービスの障害や性能低下が、単一コンポーネントの停止だけで終わることはありません。分散システム環境で、特定のマイクロサービスにマーケティングイベントや突発的なトラフィック急増が集中すると、そのサービスの応答遅延が、上位の呼び出しレイヤーであるAPIゲートウェイのコネクションプール枯渇へつながる障害伝播が頻繁に発生します。特に、複数の開発会社が各ドメインを独立して管理するマルチベンダー環境では、ハードウェア機器レベルで一律にIPを遮断したり、インフラ帯域幅を制限したりするだけでは、ビジネス要件に柔軟に対応することが困難です。インフラ設定に依存せず、各APIルートの重要度と利用可能容量に応じてトラフィックのしきい値を動的に変更し、しきい値を超えたユーザーにも無条件の拒否ではなく、順番にアクセスする機会を与えるキューおよび可用性制御アーキテクチャが必要となる理由です。そのため、データベースベースでゲートウェイの実行中にサービスごとの利用可能容量をリアルタイムに設定し、超過したトラフィックをリアクティブなノンブロッキングストリーム内で安全に待機させるカスタム動的キューシステムを構築しました。
キュー制御の入口となるQueueFilterは、SCGの標準拡張仕様であるAbstractGatewayFilterFactoryを継承して実装しました。このフィルターは、リクエストごとにルートIDを抽出して独立したトラフィック隔離壁を構築し、ユーザーの順番が来るまでNettyのイベントループスレッドを占有しないノンブロッキング方式で待機シグナルを仲介します。
このキューシステムが、ゲートウェイ自体のリソースを枯渇させることなくバックエンドを防御できる秘訣は、リアクティブストリームとJava標準の同時実行APIを滑らかに接続する、アーキテクチャ上の有機的な連携にあります。
第一に、CompletableFutureとリアクティブストリーム間の「ノンブロッキングブリッジ」です。従来のブロッキング構造でキューを実装するには、スレッドを休止させる方式を使う必要があるため、待機するユーザー数に応じてスレッドが枯渇し、ゲートウェイが先に停止してしまいます。これを克服するため、QueueContext内部で待機セッションごとに空のCompletableFutureを生成し、ConcurrentHashMapで管理するよう設計しました。ユーザーは自分の順番が来るまで、Nettyの貴重なイベントループスレッドを1msも拘束することなく、利用可能なスレッドを返却できます。そして内部処理が完了し、QueueContextから順番完了シグナルが発行された瞬間にだけリアクティブパイプラインが起動して後続のルーティングチェーンへ進むため、極めて高いリソース効率を実現しました。
第二に、システムの限界容量に対応する二段構えの遮断戦略と非同期バックエンド連携です。インメモリキューが許容する範囲内のトラフィックはQueueContextに蓄積され、リアクティブな保留状態で安全に順番を待ちます。一方、インメモリキューまで飽和状態に達した場合は、待機セッション情報をバックエンドへ渡して分散イベントを誘導した後、QueueFullExceptionをスローして例外処理を行います。これにより、ゲートウェイはインメモリオーバーフローのリスクから完全に保護され、クライアントは標準HTTPレスポンスを通じて待機IDを受け取り、バックエンドとアウトオブバンドで通信できる堅牢なアーキテクチャ上の緩衝地帯を確保できます。
第三に、リアクティブライフサイクルに基づくリソースリーク根絶メカニズムです。分散キュー環境で最も頻繁に発生する実務上の障害は、ユーザーが待機中にページを更新したりウィンドウを閉じたりして接続が切断されたにもかかわらず、インメモリリソースや同時実行スロットが解放されずに残るデッドロック現象です。このシステムは、リアクティブストリームのライフサイクルシグナルを精密に捕捉し、この問題を根本から防ぎます。具体的には、ストリームのキャンセル時に発動するdoOnCancelでゴーストセッションを即座に削除し、doFinallyブロックによって、リクエストの正常な処理完了だけでなく、ネットワークエラーやタイムアウトなど、いかなる理由でHTTPリクエスト・レスポンスサイクルが最終終了した場合でも、待機中の次のユーザーを連鎖的に呼び起こします。利用可能なスロットを占有する前にキャンセルされた幽霊待機者を検出した場合は、メモリから静かに削除する浄化ロジックまで実行します。このように歯車のようにかみ合ったライフサイクル制御によって、1件のリソースリークやデッドロックもなく安定性を維持する成果を上げることができました。
おわりに
ここまで、統合認証・認可フィルターの実装と、キュー管理サービスの実装方法を見てきました。単に外部リクエストをバックエンドへ転送していたAPIゲートウェイを活用し、セキュリティとトラフィック制御の中央集約によるマルチベンダー開発の生産性最大化と、キュー管理サービスによるインフラの安定性確保を実現しました。
結局のところ、アーキテクチャの進化とは、硬直したハードウェアやインフラの制約にビジネスを合わせることではなく、急速に変化するビジネス要件と複雑な協業構造を支えられるよう、ソフトウェアを柔軟に進化させていくプロセスそのものです。本プロジェクトでSCGを中心に構築した動的制御アーキテクチャが、マルチベンダー環境でMSAを導入し、分散したセキュリティの分断や大規模トラフィックの制御に悩む開発者の皆さまにとって、良い参考になれば幸いです。
Hustle Paul