获得一个简单的Spring JMS客户端确认可以工作

Sco*_* OB 14 spring activemq-classic jms

刚刚开始JMS ActiveMQ Acknowledgements着手在Spring工作.到目前为止,我有一个完美的消费者工作,除了当我不确认消息时,它仍然从队列中取出(我希望它留在那里或以死信队列结束).

<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>
Run Code Online (Sandbox Code Playgroud)

在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)...
}
Run Code Online (Sandbox Code Playgroud)

小智 18

阅读本文档:Spring JMS容器不使用 message.acknowledge()

侦听器容器提供以下消息确认选项:

"sessionAcknowledgeMode"设置为"AUTO_ACKNOWLEDGE"(默认值):在侦听器执行之前自动确认消息; 如果抛出异常,则无法重新发送.
"sessionAcknowledgeMode"设置为"CLIENT_ACKNOWLEDGE":成功侦听器执行后自动确认消息; 如果抛出异常,则无法重新发送.
"sessionAcknowledgeMode"设置为"DUPS_OK_ACKNOWLEDGE":在侦听器执行期间或之后的延迟消息确认; 在例外抛出的情况下潜在的重新发送.
"sessionTransacted"设置为"true":成功监听器执行后的事务确认; 如果抛出异常,保证重新发送.


Sco*_* OB 7

我在http://ourcraft.wordpress.com/2008/07/21/simple-jms-transaction-rollbacks-work/找到答案

如果您更改acknowledge ="transacted"并确保抛出新的RuntimeException("消息无法消耗.回滚事务"),它似乎运行良好; 在OnMessage()例程的末尾.

仍然不知道承认="客户"实现了什么


gel*_*lin 5

如今,Spring提供了对普通JMS消息监听器的良好包装.

请参阅AbstractMessageListenerContainer的 JavaDocs .

"sessionAcknowledgeMode"设置为"CLIENT_ACKNOWLEDGE":成功执行侦听器后自动确认消息; 在抛出用户异常的情况下以及在其他侦听器执行中断(例如JVM死亡)的情况下,尽力而为的重新传递.

因此,当您定义@JmsListener方法时,确认会在成功完成后自动发送,但您可以抛出异常以再次接收消息.