복붙노트

[SPRING] JMS 수신기에서의 JMS 메시지 재전송 예외

SPRING

JMS 수신기에서의 JMS 메시지 재전송 예외

org.springframework.jms.listener.AbstractMessageListenerContainer에 대한 Javadoc은 if

나는 "예외가 발생했을 경우 재 전달이 없다"는 것은 jms 수신기에 예외가 발생하더라도 해당 메시지가 재전송되지 않음을 의미합니다 (따라서 추측 할 수 있겠지만). 그러나 청취자에게서 던진 예외는 성공을 거두지 못했음을 의미하며 승인이 없으므로 재 배달해야합니다.

질문은 ~이야: jms 리스너에서 예외가 발생했을 때 실제로 메시지 수신 확인을 어떻게 처리해야합니까?

실제로 일어나는 일은이 스택 추적에서 볼 수 있습니다.

at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:98)
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:66)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:660)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:620)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:591)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:308)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:246)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1142)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1134)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1031)

stacktrace의 5 행은 특히 중요합니다. 코드는 기본적으로 청취자로부터 던져진 예외가 org.springframework.jms.listener.AbstractMessageListenerContainer # commitIfNecessary에서 수행되는 ackowledgement를 우회한다는 것을 의미합니다. 괜찮아요.하지만 "던져진 예외가 발생하면 재 전달이 안돼"란 뜻은 무엇입니까?

추가 정보: 스프링 잼 : 4.1.2

<bean id="someListenerContainerFactory" class="org.springframework.jms.config.DefaultJmsListenerContainerFactory">
    <property name="connectionFactory" ref="connectionFactory"/>
    <property name="concurrency" value="1-10"/>
    <property name="sessionAcknowledgeMode">
        <util:constant static-field="javax.jms.Session.CLIENT_ACKNOWLEDGE"/>
    </property>
</bean>

해결법

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

    1.사용하는 리스너 컨테이너에 따라 다릅니다. AUTO ack 모드를 사용하면 SimpleMessageListenerContainer는 리스너가 반환 한 후 응답합니다 (예 : 기존 JMS MessageListener). DefaultMessageListenerContainer는 청취자가 호출되기 전에 응답하므로 메시지 손실을 방지하려면 acknowledgeMode = "transacted"가 필요합니다.

    사용하는 리스너 컨테이너에 따라 다릅니다. AUTO ack 모드를 사용하면 SimpleMessageListenerContainer는 리스너가 반환 한 후 응답합니다 (예 : 기존 JMS MessageListener). DefaultMessageListenerContainer는 청취자가 호출되기 전에 응답하므로 메시지 손실을 방지하려면 acknowledgeMode = "transacted"가 필요합니다.

    이 영역의 javadocs는 약간 오도 된 것으로 최근에 개선되었습니다.

    CLIENT_ACKNOWLEDGE를 사용하면 자신 만의 멍청한 행동을 할 수 있습니다. 그 문서는 당신이 중개인의 변덕에 처해 있다는 것을 의미합니다. JMS 메시지 javadoc에 따르면 다음과 같습니다.

    내 경험상 SMLC로 자동 응답을 사용하고 DMLC와 트랜잭션을 사용하는 것이 가장 좋습니다.

  2. from https://stackoverflow.com/questions/29413784/jms-message-redelivery-on-exception-in-jms-listener by cc-by-sa and MIT license