web-dev-qa-db-ja.com

単純なSpring JMSクライアントが動作することを確認する

ちょうど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&amp;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)...
}
16
Scotty OB

私は http://ourcraft.wordpress.com/2008/07/21/simple-jms-transaction-rollbacks-work/ で答えを見つけました

Acknowledge = "transacted"を変更し、新しいRuntimeException( "Message could n't消費されなかった。ロールバックトランザクション"); OnMessage()ルーチンの最後。

しかし、acknowledge = "client"が何を達成するかはまだわかりません

8
Scotty OB

このドキュメントをお読みください:Spring JMSコンテナーはmessage.acknowledge()を使用しません

リスナーコンテナは、次のメッセージ確認オプションを提供します。

「sessionAcknowledgeMode」を「AUTO_ACKNOWLEDGE」に設定(デフォルト):リスナー実行前の自動メッセージ確認。例外がスローされた場合の再配信はありません。
"sessionAcknowledgeMode"を "CLIENT_ACKNOWLEDGE"に設定:リスナーの実行が成功した後の自動メッセージ確認。例外がスローされた場合の再配信はありません。
"sessionAcknowledgeMode"を "DUPS_OK_ACKNOWLEDGE"に設定:リスナーの実行中または実行後の遅延メッセージ確認。例外がスローされた場合の再配信の可能性。
「true」に設定された「sessionTransacted」:リスナーの実行が成功した後のトランザクションの確認応答。例外がスローされた場合の再配信が保証されています。

20
Tarun

現在、Springは単純なJMSメッセージリスナーの優れたラッパーを提供しています。

AbstractMessageListenerContainer のJavaDocsを参照してください。

"sessionAcknowledgeMode" に設定 "CLIENT_ACKNOWLEDGE":リスナーが正常に実行された後の自動メッセージ確認。ユーザー例外がスローされた場合や、他のリスナー実行が中断された場合(JVMが死ぬなど)の場合のベストエフォートの再配信。

したがって、 @ JmsListener メソッドを定義すると、正常に完了すると通知が自動的に送信されますが、例外をスローしてメッセージを再度受信することができます。

5
gelin