ちょうどJMS ActiveMQ Acknowledgements
春に働いています。これまでのところ、私が完全に機能しているコンシューマーはいますが、メッセージを確認しなかった場合でも、キューから取得されます(メッセージがそこに留まるか、デッドレターキューで終了することを期待しています)。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd">
<!-- A JMS connection factory for ActiveMQ -->
<bean id="connectionFactory" class="org.Apache.activemq.ActiveMQConnectionFactory"
p:brokerURL="failover://(tcp://jms1:61616,tcp://jms2:61616)?randomize=false&jms.redeliveryPolicy.maximumRedeliveries=5" />
<!-- A POJO that implements the JMS message listener -->
<bean id="simpleMessageListener" class="com.company.ConsumerClass" />
<!-- A JMS namespace aware Spring configuration for the message listener container -->
<jms:listener-container
container-type="default"
connection-factory="connectionFactory"
acknowledge="client"
concurrency="10-50"
cache="consumer">
<jms:listener destination="someQueue" ref="simpleMessageListener" method="onMessage" />
</jms:listener-container>
</beans>
ConsumerClassでは、私の単純なコンシューマーは次のようになります。
@Override public final void onMessage(Message message) {
Object postedMessage = null;
try {
postedMessage = ((ObjectMessage) message).getObject();
if (postedMessage.getClass() == SomeMessageType.class) {
try {
//Some logic here
message.acknowledge();
return; //Success Here
} catch (MyException e) {
logger.error("Could not process message, but as I didn't call acknowledge I expect it to end up in the dead message queue");
}
}
} catch (JMSException e) {
logger.error("Error occurred pulling Message from Queue", e);
}
//Also worth noting, if I throw new RuntimeException("Aww Noos"); here then it won't take it from the queue, but it won't get consumed (or end up as dead letter)...
}
私は http://ourcraft.wordpress.com/2008/07/21/simple-jms-transaction-rollbacks-work/ で答えを見つけました
Acknowledge = "transacted"を変更し、新しいRuntimeException( "Message could n't消費されなかった。ロールバックトランザクション"); OnMessage()ルーチンの最後。
しかし、acknowledge = "client"が何を達成するかはまだわかりません
このドキュメントをお読みください:Spring JMSコンテナーはmessage.acknowledge()
を使用しません
リスナーコンテナは、次のメッセージ確認オプションを提供します。
「sessionAcknowledgeMode」を「AUTO_ACKNOWLEDGE」に設定(デフォルト):リスナー実行前の自動メッセージ確認。例外がスローされた場合の再配信はありません。
"sessionAcknowledgeMode"を "CLIENT_ACKNOWLEDGE"に設定:リスナーの実行が成功した後の自動メッセージ確認。例外がスローされた場合の再配信はありません。
"sessionAcknowledgeMode"を "DUPS_OK_ACKNOWLEDGE"に設定:リスナーの実行中または実行後の遅延メッセージ確認。例外がスローされた場合の再配信の可能性。
「true」に設定された「sessionTransacted」:リスナーの実行が成功した後のトランザクションの確認応答。例外がスローされた場合の再配信が保証されています。
現在、Springは単純なJMS
メッセージリスナーの優れたラッパーを提供しています。
AbstractMessageListenerContainer のJavaDocsを参照してください。
"sessionAcknowledgeMode"
に設定"CLIENT_ACKNOWLEDGE"
:リスナーが正常に実行された後の自動メッセージ確認。ユーザー例外がスローされた場合や、他のリスナー実行が中断された場合(JVM
が死ぬなど)の場合のベストエフォートの再配信。
したがって、 @ JmsListener メソッドを定義すると、正常に完了すると通知が自動的に送信されますが、例外をスローしてメッセージを再度受信することができます。