EIP / Loan Broker System Management


Loan Broker System Management

サマリ

9章の融資ブローカーサンプルに、システム管理のEIPパターンを適用していく。ここでは、「管理コンソール」と「融資ブローカーのQoS」まで。

詳細

融資ブローカーのシステム管理(Loan Broker System Management)

  • この章では、9章の "Asynchronous Implementation with MSMQ" で説明したC# + MSMQベースの融資ブローカー実装を土台に、前章のシステム管理のパターンを適用していく。

融資ブローカーの計測(Instrumenting the Loan Broker)

Chap12_LoanBroker.png
  • 4つの主要コンポーネント:
    1. Customer は融資見積もりのリクエストを出す
    2. Loan Broker は中央のプロセスマネージャとして、信用調査機関(Credit Bureau)と銀行(Bank)との通信を調整する
    3. Credit Bureau は顧客の信用スコアを計算するサービスを提供する
    4. Bank X は見積もりリクエストを受けて、利率の見積もりを提供する
  • 現実には、アプリケーション内部へのアクセスはできず、監視・管理のコンポーネントしか弄れないことがほとんどなので、ここでもアプリケーションはブラックボックスなものとする。
  • その制約下で、ここでは以下の管理上の要求を実現する。
    • 管理コンソール -- 全コンポーネントの監視・管理を1ヶ所のフロントエンドに集約したい。
    • 融資ブローカーのQoS -- 融資ブローカーの応答時間を監視したい(前回のサンプルでは、テストクライアントが応答時間をチェックしていたが、本番の運用ではそれはできないため)。
    • 信用調査機関の動作検証 -- サードパーティのサービスプロバイダである信用調査機関の動作を定期的にチェックしたい。
    • 信用調査機関のフェイルオーバー -- もし信用調査機関の動作がおかしかったら、一時的に別のサービスプロバイダにメッセージを転送したい。

管理コンソール(Management Console)

  • 統合システム全体の健康状態を検査するには、コンポーネントのメトリクスを1ヶ所に集める管理コンソールが必要。また、障害に対応するために、メッセージフローやコンポーネントのパラメータを制御できる必要もある。
  • 管理コンソールはメッセージングを使って、各コンポーネントと通信する。独立した Control Bus を使って、システム管理専用のメッセージをやり取りする。
  • この本はUIの本ではないので、管理コンソールは超々シンプルにする。ベンダの製品はリアルタイムのデータ表示をサポートしてるものもあるし、VBやMS Office(Excelとか)を使えばイカしたビジュアルにもできる。プラットフォームによっても、JavaのJMX(Java Management Extensions)や Microsoft WMI(Windows Management Instrumentation)などが利用できる。

融資ブローカーのQoS(Loan Broker Quality of Service)

  • 第一の要求、融資ブローカーのQoSでは、ビジネスデータの中身には興味がなく、単にリクエストとリプライの間隔を測定できればよい。
  • 難しいポイントは、クライアントがReturn Addressを使って自由に返信先を指定できること。そこで、Smart Proxyパターンを使う。
  • Smart ProxyReturn Addressを一時的に格納し、それを固定のリプライチャネルに置き換える。リプライが戻って来たら、それをリクエストと相関付けて元々のReturn Addressへ投げ返す。
Chap12_SmartProxy.png


  • Smart Proxyはクライアントと融資ブローカーとの間に挿入する。クライアントから見たリクエストチャネル(loanRequestQueue?)は変わっていないので、Smart Proxyはクライアントから透過的に挿入できる。
  • Smart Proxyでは、融資リクエストへの応答時間の他に、現在処理中のリクエスト数も測定したい。
    • 応答時間:リクエストの受信時刻を記録し、リプライを受け取ったらその現在時刻からリクエストの受信時刻を引けばよい。
    • 処理中のリクエスト数:未処理(=まだリプライを受け取っていない)リクエスト数をカウントすればよい。brokerRequestQueue?に積み上がっているメッセージと融資ブローカーが既に処理中のメッセージは区別できないので、両方の合計をカウントする。
  • Smart Proxyは、メトリクス情報をcontrolBusQueue?チャネルを通して管理コンソールへ送る。1メッセージ受信毎にメトリクスを送っているとネットワーク負荷が高いので、タイマーを使って定義済みの間隔(例:5秒)でメトリクスメッセージを送ることにする。一度に全メッセージの詳細情報を送ってもよいが、簡単・軽量化のためにここではサマリ情報のみ送ることにする。
  • Smart Proxyパターンで紹介した実装をここでは再利用して、SmartProxyBase?SmartProxyRequestConsumer?SmartProxyReplyConsumerクラスのサブクラスを作成する(以下クラス図参照)。
Chap12_SmartProxy_ClassDiagram.png


  • LoanBrokerProxy? はオリジナルの SmartProxy? と同様、2つのメッセージコンシューマ(LoanBrokerProxyRequestConsumer?=クライアントからのリクエスト用、LoanBrokerProxyReplyConsumer?=融資ブローカーからのリプライ用)を持っている。どちらのコンシューマもベースクラス(SmartProxyRequestConsumer?SmartProxyReplyConsumer)を継承し、AnalyzeMessage?メソッドを実装している。

LoanBrokerProxy?クラス

  • Control Busのキューをコンストラクタで受け取り、performanceStats と queueStats の2つのメトリクスを ArrayList? として持つ。
    • performanceStats = リクエストーリプライの時間間隔(秒)を収集。
    • queueStats = 処理中リクエストメッセージ数を収集。
  • 事前に設定されたタイマーで OnTimerEvent? メソッドが呼び出され、収集データのスナップショットを取る。そのスナップショットに対して、SummaryStats? データ構造を使ってデータを最大・最小・平均値に圧縮し、そのサマリをControl Busに送る。

LoanBrokerProxyRequestConsumer?クラス

  • 入ってくるリクエストメッセージを処理する。ベースクラス(SmartProxyRequestConsumer? or SmartProxyReplyConsumer)が messageData ハッシュテーブルへのメッセージの出し入れをやってくれるので、処理中メッセージ数は単に messageData ハッシュテーブルのサイズを取得すればよい。収集結果は queueStats に保持する。

LoanBrokerProxyReplyConsumer?クラス

  • リプライメッセージが届いたら、2つのメトリクスを収集する。
    1. performanceStats -- リクエストからリプライまでに掛かった時間を記録。
    2. queueStats -- 残りの処理中リクエスト数を記録。
  • SummaryStats? データ構造がデータの最大・最小・平均値を算出する。処理されたリクエストメッセージ数は、リプライメッセージの performanceStats 数を リクエスト&リプライメッセージの queueStats 数から引くことで算出できる(?)。

メトリクスの計測

  • 2つのテストクライアントを使って、それぞれ融資見積もりを50リクエスト投げた。結果は以下の通り(XML形式のデータをXSLTを使ってHTMLに変換した)。
Chap12_Stats.png


  • Excelチャートにすると、キューサイズはこんな感じ。
Chap12_Chart.png


  • 最初に2つのテストクライアントがメッセージをぶち込んで、ピークは90くらいに。続いて、融資ブローカーは安定して2リクエスト/秒くらいで処理する。リクエストが大量なので応答時間はかなり遅い(最大で1分ちかく)。
  • 融資ブローカーはリクエスト爆撃を graceful に処理できていると言える一方で、応答時間はやはり遅い。応答時間を改善するには、融資ブローカーインスタンスや信用調査機関インスタンスを多重化すればよい。

担当者のつぶやき

  • ここがよく理解できていない。 > "処理されたリクエストメッセージ数は、リプライメッセージの performanceStats 数を リクエスト&リプライメッセージの queueStats 数から引くことで算出できる(?)。"

みんなの突っ込み