EIP / Message Expiration


メッセージの期限切れ(Message Expiration)

一言要約

Message Expiraionは、どれくらいの間、メッセージが生きているのか、 もしくは、メッセージが有効期限切れになる、のかを特定するタイムスタンプ である。

要約


  • アプリケーションは、Messaging を使っている。もしMessagesのデータや要求があるときに受け付けられなかった場合、使われずに無視されるべきだ。



送り手は、メッセージが無効であることをみなすべきか、そして処理すべきかをどう示せばいいだろうか。



  • Messagingは、Messageが最終的に受け手に配信されることを、実際に保証する。
  • 保証することができないものは、どれくらいの長さで配信さされるのか。
  • 例えば、もし送り手と受け手のネットワーク接続が1週間の間、途切れてしまったなら、メッセージを配信するために1週間かかることになる。
  • メッセージングは高い信頼性がある。なおさら参加者(送り手、ネットワーク、受け手)ではないとき、しかし、メッセージは信頼性のない状況で送信するために、非常に長い時間かけることができる。 (より詳細のためには、Guaranteed Delivery参照のこと)


  • たいていメッセージの内容は、有効なのがどれくらいの長さのために実用的な制限を持たせる。
  • 呼び出し側は、興味をなくすかもしれない要求にもとづいてストックが生まれる。1分以内に応答を受けれない、など。
  • これは要求が送信に1分以上かけるべきではないが、応答は非常に早く戻す送信をするようにするのがいい。
  • ストックの引用は1分以上もしくは、2つの古すぎるものを返信する。そして関係がなくなっていく。


  • 1度送り手がメッセージを送信し返信がなくキャンセルする時点で、メッセージを再度、呼び出す方法がない。
  • 同じようにメッセージが送信されたときやメッセージが古すぎて破棄するとき、受け手がチェックすることができる。
  • しかし、異なる状況下で異なる送り手は、どのくらいの長さが長すぎるのかについて、異なるアイデアを持っているかもしれない。
  • 受け手側は、どうやって破棄するためのメッセージを知るだろうか。
  • メッセージのライフタイムを特定するための送り手側の方法には、なにが必要だろうか。



どのくらいの間メッセージを生かすかを時間制限で特定するため、Message Expirationを設定する。



  • 1度メッセージが生きて通過する時間、そしてメッセージがまだ使用されていない、それでメッセージの有効期限が切れる。
  • メッセージングシステムの消費者は、有効期限切れのメッセージを無視するあろう
  • それらは、最初の場所で送っていない場所かのようにメッセージを扱う。
  • たいていのメッセージングシステムは、有効期限切れのメッセージングをDead Letter Channelに再度、経路を割り当てする機能を実装している。
  • 他では有効期限切れのメッセージを単純に破棄する。これは設定可能かもしれない。


  • Message Expirationは、牛乳パックの賞味期限日のようなものである。
  • 期限日の後に、あなたは牛乳を飲むべきではない。
  • 同じように、メッセージの有効期限切れの時、メッセージングシステムは配信すべきでない。
  • もし受け手がメッセージを受けているが、期限が切れる前に処理することができないのなら受け手はメッセージを捨てるべきである。


  • Message Expiraionは、どれくらいの間メッセージが生きているのか、もしくは、メッセージが有効期限切れになる、のかを特定するタイムスタンプ(日付と時間) である。
  • 設定は、関連して特定することができるか、強制終了することができる。
  • 強制終了の設定は、メッセージが有効期限切れになったときに、日付と時間で特定する。
  • 関連する設定は、有効期限切れ前にどのくらいの間、メッセージを生かすべきかを特定する。;
  • メッセージが強制的に関連する設定に変換されて送信されたときに、メッセージングシステムは時間を使う。
  • メッセージングシステムは、送り手と異なるタイムゾーンの受け手のためにタイムスタンプを調整する責任をもっている。
  • 夜明けに調整されて時間が保存される、そして、その他に2つの異なる時計が、何時なのかが一致しないことが起きる。


  • メッセージの有効期限切れのプロパティは、メッセージが送られた時に特定される送信時間のプロパティに関連性がある。
  • メッセージの強制的な有効期限切れのタイムスタンプは、送信したタイムスタンプより遅くなくてはならない。(もしくは、他のメッセージが、すぐに有効期限切れになるだろう)
  • この問題を避けるためにメッセージングシステムが送信したタイムスタンプに相対したタイムアウトを追加することで、有効期限切れのタイムスタンプを計算する場合に、送り手は、比較して有効期限切れ時間を決めている。
    (有効期限切れ時間=送信時間+ 生存時間)


  • メッセージが有効期限切れのとき、メッセージングシステムは単に破棄するかもしれない。もしくはDead Letter Channelに移動させるかもしれない。
  • 有効期限切れのメッセージングの場所を探す受け手がInvalid Message Channelに移動すべきである。
  • Publish-Subscribe Channelと一緒で各購読者が自身のメッセージのコピーを取得する。
  • それらの購読者がそのメッセージを使用する前に同じメッセージの他のコピーは有効期限切れになるが、メッセージのいくつかのコピーは、無事にそれらの購読者のもとへ届くかもしれない。
  • 'Request-Reply''を使用するとき、有効期限切れ設定と一緒の返信メッセージは、うまく動作しないかもしれない。
  • もし返信が有効期限切れなら、要求の送り手は最初の場所でその要求が受け取られたかさえわかならいだろう。
  • もし返信の有効期限切れが使用されていたなら要求の送り手が返信が受け取られないことを予測した場所でのケースを扱う設計をしなければならない。




例:JMS Time-to-Live パラメータ

  • メッセージの有効期限切れは、JMS の仕様では "message time-to-live" と呼ばれる。
  • JMSのメッセージは、メッセージの有効期限切れのために事前にJMSExpirationのプロパティを定義している。
  • しかし、送り手は、Message.setJMSExpiration(long)経由でセットすべきでない。なぜかというと、JMSプロバイダーはメッセージのを送信したと時に設定を上書きするためである。
  • むしろ、送り手は送信する全てのメッセージのタイムアウトを設定するために、MessageProducer?(QueueSender? もしくは TopicPulisher?)を使用すべきである。
  • この設定をするそのメソッドは、MessageProducer?.setTimeToLive?(long)である。
  • 送り手もまた個別のメッセージに対して、次のメソッドを使用してtime-to-liveを設定することができる。
    MessageProducer.send(Message message, int deliveryMode, int priority, long timeToLive)
  • 4つ目のパラメータで、ミリ秒のtime-to-live が指定できる。
  • Time-to-liveは、メッセージが送信された後にどのくらいの長さで有効期限切れにすべきであるかを特定するのに関連する設定である。



例: .NET Time-to-Be-Recieved と Time-to-Reach-Queue プロパティ

  • .NET のメッセージでは、2つのプロパティが有効期限切れを特定するためにある。
    • TimeToBeReceived?
    • TimeToReachQueue?
  • reach-queue 設定は、どのくらいの間にメッセージがその目的地のキューに届かなくてはいけないのを特定する。
  • be-recieved 設定は、どのくらいの間にメッセージが受け手に使用されなければならないのかを特定する。
  • そして、目的地のキューにメッセージを送信するための合計時間と目的地のキューに収まり続けることができるメッセージの合計時間を足して、制限をかける。
  • TimeToBeReceived?は、JMSのJMSExpirationプロパティと同じである。
  • 両方の時間の設定は、時間の長さである System.TimeSpan?型の値で持っている。

担当者のコメント

  • 有効期限切れってブラウザのCookieにある概念だったり身近にすぐイメージしやすいものがあった。
  • Apple のプッシュ通知をするサーバ(Apple Push Notification service)もこういう設計思想があるのかなーと思ったり。

みんなの突っ込み