EIP / Guaranteed Delivery


EIP

保証されたデリバリー

一言要約

メッセージをデータストアに格納することで、メッセージングシステムがクラッシュしても消えなくなる。ただし100%じゃないよ。

要約


メッセージシステムが落ちていてもメッセージが届くという保証は?


  • RPCよりも非同期メッセージングが有利な点は、送信側、受信側、ネットワークが同時に動いていなくてもよいところにある。ネットワークが落ちていれば、メッセージは溜めておかれるし、受信側がつながらなければリトライする。溜めておいて送る がメッセージングの基礎になる。じゃあ、どうやって溜めておくの?
  • デフォルトではメッセージをメモリに溜める。しかし、メッセージングシステムがクラッシュすると、メッセージも消えてしまう。
  • たいていのアプリケーションは同じような問題に対処しなければならない。そして、たいていのアプリケーションと同じく、メッセージングシステムもメッセージをデータベースに格納する。

メッセージングシステムがクラッシュしてもメッセージが消えないように、保証されたデリバリーを使おう


  • 保証されたデリバリーを使う際、メッセージングシステムはビルトインのデータストアを用いる。メッセージングシステムをインストールするコンピュータにそれぞれデータストアが置かれ、メッセージがローカルに格納される。
    • メッセージが送信側のデータストアに安全に格納されるまでは送信が完了しない。
    • 受信側に届くまで,順次メッセージはデータストアに格納される。
  • 永続化によって信頼性が上がる代わりにパフォーマンスが犠牲になる。メッセージングシステムがクラッシュしたり、シャットダウンしたりしたときにメッセージが消えてよければ、保証されたデリバリーを避ければ性能は上がる。
  • 同じく、トラフィックが高い状況ではディスク領域を大きく消費してしまう点も考慮しよう。メッセージングシステムによっては、メッセージングシステム内にメッセージを置いておける時間を定めるリトライ・タイムアウト・パラメータを設定できるものもある。アプリケーションの多くはメッセージをイベントメッセージ(151)としてつかうので、一定期間が経った後に安全に棄てることができる(メッセージの賞味期限[176])。
  • テストやデバッグをしている時は保証されたデリバリーモードをOFFにするとよい。メッセージングサーバーを落とし上げすれば溜まっているメッセージをすべて消せるからだ。メッセージが溜まっていると、デバッグが大変になる。
    • たとえば、ポイント・ツー・ポイント・チャネル(103)の場合、メッセージが溜まっていると受信側はそのメッセージを処理してしまう。非同期保証型メッセージングでは、デバッグ時のよくある落とし穴になる。
    • 商用メッセージングシステムでは、テスト用に個別にキューを消せるようになっている。

コラム:保証されたメッセージングはどの程度保証されているのか

  • コンピュータシステムの信頼性が「9の数」で測られることを念頭に置いておくことは重要だ。つまり、99.9%ということである。
  • 99.9%を99.99%に上げることは指数関数的なコストがかかるので、100%ということはほとんどない。
  • 同じことは保証されたデリバリーにも言えて、メッセージが消えてしまうことはある。

  • .NETのMSMQでは、チャネルを永続化するためにはトランザクション境界を宣言しなければならない。送信側が常に トランザクショナルクライアント(484)でなければならないということ。JMSで パブリッシュ-サブスクライブ・チャネル(106)を使うと、メッセージがアクティブなサブスクライバに送られることしか保証できない。

具体例

  • 株式取引
    • 株式取引では、取引の要求と確認は 保証されたデリバリー を使って送らなければならない。ただし、金額の変動は保証する必要がない
  • JMSの永続メッセージ
    • JMSではメッセージの永続化はメッセージ単位で設定される。つまり、あるメッセージは永続化されるが、別のメッセージはメモリ上ということがあるということ。
    • コード例
  • IBM WebSphere? MQ
    • IBM WebSphere? MQは、保証されたデリバリーはチャネルごと、もしくはメッセージごとに設定できる。チャネルが永続化されていなければ、メッセージは永続化できない。チャネルが永続化可能になっていれば、メッセージ単位で変わる
    • 具体的な使い方
  • .NET 永続化メッセージ
    • 永続化するには、MessaeQueue?をトランザクション境界内でつくればよい。