第35章 重複メッセージ検出

HornetQ には、強力な自動重複メッセージ検出が含まれ、アプリケーションレベルで重複検出ロジックをコーディングせずに重複メッセージをフィルタリングできます。この章では、重複検出と、HornetQ が重複検出をどのように使用するか、重複検出をどのようにいつ設定するかについて説明します。
クライアントからサーバー、またはサーバーから別のサーバーにメッセージを送信する場合、ターゲットサーバーまたは接続がメッセージの送信後に失敗すると (ただし、送信者が送信 (またはコミット) が正常に処理されたことを示す応答を受け取る前)、送信者はメッセージがアドレスに正常に送信されたかどうかを知ることができません。
送信が受け取られ、処理された後 (ただし、応答が送信される前) にターゲットサーバーまたは接続が失敗した場合、メッセージはアドレスに正常に送信されますが、送信が受け取られ、処理が終了する前にターゲットサーバーまたは接続が失敗した場合は、メッセージがアドレスに正常に送信されません。送信者の観点から、これらの 2 つのケースを区別することはできません。
サーバーが回復すると、クライアントは困難な状況に置かれます。クライアントはターゲットサーバーで障害が発生したことを知っていますが、最後のメッセージがその宛先に正常に到達したかどうかを知りません。最後のメッセージを最送信する場合は、重複メッセージがアドレスに送信されることがあります。各メッセージが注文または取引の場合は、この結果注文が 2 回行われたり、取引が重複して記録されたりして、望まない状況が発生することがあります。
トランザクションでメッセージを送信することは正しい解決法ではありません。トランザクションコミットが処理されている間にサーバーまたは接続が失敗すると、トランザクションが正常にコミットされたかどうかがわかりません。
これらの問題を解決するために、HornetQ はアドレスに送信されたメッセージに対して自動重複メッセージ検出を提供します。

35.1. メッセージの送信に重複検出を使用

送信されたメッセージに対して重複メッセージ検出を有効にします。メッセージの特別なプロパティーに作成された一意の値を設定します。ターゲットサーバーはメッセージを受信すると、そのプロパティーが設定されているかどうかを確認します。設定されている場合、ターゲットサーバーはメモリキャッシュで、このヘッダーの値を持つメッセージがすでに受信されているかどうかを確認します。以前に同じ値を持つメッセージを受信した場合は、メッセージが無視されます。

注記

ノード間でメッセージを移動するために重複検出を使用する場合は、ソースからメッセージを消費し、ターゲットに送信するために XA トランザクションが使用されたときと同じ1 度だけの配信保証が提供されます (ただし、XA を使用する場合よりもオーバーヘッドが少なくなり、設定が大幅に簡単になります)。
トランザクションでメッセージを送信する場合は、そのトランザクションで送信されたメッセージに対してプロパティーを設定する必要はありません。それはトランザクションで 1 度だけ設定します。サーバーがトランザクションの任意のメッセージに対して重複メッセージを検出した場合は、トランザクション全体が無視されます。
設定されたプロパティーの名前は org.hornetq.api.core.HDR_DUPLICATE_DETECTION_ID の値 (_HQ_DUPL_ID) です。
プロパティの値のタイプは byte[] または SimpleString (コア API を使用する場合) のいずれかです。JMS を使用している場合は、String である必要があり、その値は一意である必要があります。一意の ID を生成する簡単な方法は UUID を生成することです。
コア API を使用してプロパティーを設定する例は次のとおりです。
...     

ClientMessage message = session.createMessage(true);

SimpleString myUniqueID = "This is my unique id";   // Could use a UUID for this

message.setStringProperty(HDR_DUPLICATE_DETECTION_ID, myUniqueID);

...
JMS API を使用する例は次のとおりです。
...     

Message jmsMessage = session.createMessage();

String myUniqueID = "This is my unique id";   // Could use a UUID for this

message.setStringProperty(HDR_DUPLICATE_DETECTION_ID.toString(), myUniqueID);

...