복붙노트

[SPRING] 간단한 Spring JMS 클라이언트 확인 작동

SPRING

간단한 Spring JMS 클라이언트 확인 작동

Spring에서 JMS ActiveMQ Acknowledgments가 작동하도록하기 시작했습니다. 지금까지 소비자가 메시지를 확인하지 않으면 여전히 대기열에서 가져 오는 것을 제외하고는 완벽하게 작동하는 소비자가 있습니다.

<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)...
}

해결법

  1. ==============================

    1.이 문서를 읽으십시오 : Spring JMS 컨테이너는 message.acknowledge ()를 사용하지 않습니다

    이 문서를 읽으십시오 : Spring JMS 컨테이너는 message.acknowledge ()를 사용하지 않습니다

    리스너 컨테이너는 다음과 같은 메시지 확인 옵션을 제공합니다.

  2. ==============================

    2.http://ourcraft.wordpress.com/2008/07/21/simple-jms-transaction-rollbacks-work/에서 답을 찾았습니다.

    http://ourcraft.wordpress.com/2008/07/21/simple-jms-transaction-rollbacks-work/에서 답을 찾았습니다.

    notify = "transacted"를 변경하고 new RuntimeException ( "메시지를 사용할 수 없습니다. 트랜잭션 롤백")을 발생시키는 것이 제대로 작동하는 것 같습니다. OnMessage () 루틴의 끝에서.

    그래도 notify = "client"가 무엇을 달성하는지 전혀 모른다

  3. ==============================

    3.요즘 Spring은 일반 JMS 메시지 리스너보다 우수한 래퍼를 제공합니다.

    요즘 Spring은 일반 JMS 메시지 리스너보다 우수한 래퍼를 제공합니다.

    AbstractMessageListenerContainer의 JavaDocs를 참조하십시오.

    따라서 @JmsListener 메서드를 정의하면 성공적으로 완료되면 확인 메시지가 자동으로 전송되지만 메시지를 다시 받기 위해 예외를 throw 할 수 있습니다.

  4. ==============================

    4.내 연습에서 클라이언트 확인은 거의 사용되지 않습니다. 일반적인 설정은 자동 확인이므로 코드가 onMessage ()에서 정상적으로 (예외없이) 반환되면 메시지가 자동으로 확인됩니다. 코드에서 onMessage ()에서 예외가 발생하면 승인이없고 메시지는 일반적으로 미리 구성된 횟수만큼 다시 배달 된 후 일반적으로 삭제되거나 사용 불능 메시지 대기열에 보관됩니다.

    내 연습에서 클라이언트 확인은 거의 사용되지 않습니다. 일반적인 설정은 자동 확인이므로 코드가 onMessage ()에서 정상적으로 (예외없이) 반환되면 메시지가 자동으로 확인됩니다. 코드에서 onMessage ()에서 예외가 발생하면 승인이없고 메시지는 일반적으로 미리 구성된 횟수만큼 다시 배달 된 후 일반적으로 삭제되거나 사용 불능 메시지 대기열에 보관됩니다.

    귀하의 경우 JMS 서버 관점에서 클라이언트가 메시지를 요청했지만 승인되지 않은 것처럼 보이므로 클라이언트가 여전히 '처리 중'입니다. 이 경우 동일한 대기열에있는 다른 소비자에게는 메시지가 보이지 않으므로 메시지가 여전히 대기열에있는 것처럼 보일 수 있습니다. 분명히 메시지가 사용 불능 메시지 대기열에 표시되지 않습니다.

    다양한 승인 모드를 명확하게 이해하려면 JMS 사양을 읽으십시오.

  5. ==============================

    5.소비자의 메시지에 대해 notify () 메소드를 호출하십시오.

    소비자의 메시지에 대해 notify () 메소드를 호출하십시오.

    자세한 내용은이 기사를 참조하십시오

    이 기사를 참조하십시오. Java 클라이언트 용 Sun Java System Message Queue 4.3 개발자 안내서

  6. ==============================

    6.다음 코드를 사용하십시오.

    다음 코드를 사용하십시오.

    <bean id="{containerName}"  class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref={connectionFactoryBean} />
        <property name="destinationName" ref="{queue}" />
        <property name="messageListener" ref="{listner}" />
        <property name="sessionAcknowledgeModeName" value="CLIENT_ACKNOWLEDGE"/>
    </bean>
    
  7. from https://stackoverflow.com/questions/9095471/getting-a-simple-spring-jms-client-acknowledge-to-work by cc-by-sa and MIT license