【问题标题】:Spring message listener / MANUAL acknowledgeSpring消息监听器/手动确认
【发布时间】:2015-12-20 22:38:42
【问题描述】:

我知道这听起来像听过 1000 次,但我不这么认为 我真的找不到解决方案:

使用普通 ejb 我可以使用确认模式来确认() 手动留言。如果我不这样做,它会重新交付。我做了这个 在过去,它运作良好。

使用 Spring JMS 我遇到的问题似乎是我要么 可以将重新传递设置为仅在出现异常时处理 扔或根本不扔。

如何实现和ejb一样?

我的问题是:如果消息被确认,我不想要 即使发生异常,也要重新交付。

【问题讨论】:

    标签: spring jms message mdp


    【解决方案1】:

    “sessionAcknowledgeMode”设置为“AUTO_ACKNOWLEDGE”(默认):该模式依赖于容器:对于DefaultMessageListenerContainer,表示在监听器执行前自动确认消息,出现异常不重发,其他监听不重发执行中断。对于 SimpleMessageListenerContainer,这意味着在监听器执行后自动确认消息,在抛出用户异常的情况下不会重新传递,但在监听器执行期间 JVM 死机的情况下可能会重新传递。为了始终如一地安排任何容器变体的重新交付,请考虑“CLIENT_ACKNOWLEDGE”模式或 - 最好 - 将“sessionTransacted”设置为“true”。 “sessionAcknowledgeMode”设置为“DUPS_OK_ACKNOWLEDGE”:在 (DefaultMessageListenerContainer) 期间或 (SimpleMessageListenerContainer) 侦听器执行后不久进行延迟消息确认;如果抛出用户异常,则不会重新交付,但如果 JVM 在侦听器执行期间死亡,则可能会重新交付。为了始终如一地安排任何容器变体的重新交付,请考虑“CLIENT_ACKNOWLEDGE”模式或 - 最好 - 将“sessionTransacted”设置为“true”。 “sessionAcknowledgeMode”设置为“CLIENT_ACKNOWLEDGE”:监听器执行成功后自动消息确认;在引发用户异常以及其他侦听器执行中断(例如 JVM 死亡)的情况下,尽最大努力重新交付。 “sessionTransacted”设置为“true”:成功监听执行后的事务确认;在引发用户异常以及其他侦听器执行中断(例如 JVM 死机)的情况下保证重新交付。

    Spring JMS 框架为消息确认公开了上层抽象。用户只需要关心发生用户异常时是否重新投递消息的场景。

    所以,要注意消息监听容器工厂的bean,并相应配置jms选项。

    【讨论】:

    • 引用来自链接吗?可以发一下吗?
    【解决方案2】:

    感谢您的回复。但是,我完全是这样做的, 除了我使用 Spring 3 和注释配置。问题 不是接收而是确认。如果我使用交易 与否,似乎消息是自动确认的,而 接收。

    我尝试了直接扩展 MessageListener 并遵循 .. 注意到作品。

    public class JMSListener implements SessionAwareMessageListener<TextMessage> {
    ...
    
        @Override
        public void onMessage(TextMessage message, Session session) {
            ...
        }
    }
    

    这样我就可以看到会话设置。例如。 session.getAcknowledgeMode() 传递客户端确认和 session.getTransacted() 传递 true 或 false 取决于我设置的内容。但似乎没有任何效果。 无论如何,该消息似乎已被确认。

    spring的CLIENT_ACKNOWLEDGE的java doc也有区别 和杰。对于春天,写着:

    “CLIENT_ACKNOWLEDGE”:监听执行成功后自动消息确认;抛出异常时不重新投递。

    对于jee有写:

    CLIENT_ACKNOWLEDGE 使用这种确认模式,客户端通过调用消息的确认方法来确认已消费的消息。

    对我来说,这可能是原因吗?但如果真的是这样(我 简直不敢相信)它会使 spring 无法处理消息?

    【讨论】:

    • 您找到解决方法了吗?
    • 我也有同样的问题。如果发生任何异常,我不希望重新发送消息。你找到解决办法了吗?
    【解决方案3】:

    我们可以根据您的要求使用 spring 框架的 DefaultMessageListenerContainer

    请从 Spring 中找到以下文档:

    以类似于 EJB 世界中的消息驱动 Bean (MDB) 的方式, 消息驱动的 POJO (MDP) 充当 JMS 消息的接收者。这 一个限制(但另见下文讨论 MDP 上的 MessageListenerAdapter 类)是它必须实现 javax.jms.MessageListener 接口。另请注意,在 您的 POJO 将在多个线程上接收消息的情况, 确保您的实现是线程安全的很重要。

    http://docs.spring.io/spring/docs/2.5.x/reference/jms.html#jms-asynchronousMessageReception

    以下是我在方法上添加了确认()方法的代码sn-p。

    JMS 监听器类:

    public class MyProjectJMSListener implements MessageListener {
        public void onMessage(Message message) {
            try {
                message.acknowledge();
                //Business logic to be added 
            }
            catch (JMSException ex) {
                    throw new RuntimeException(ex);
            }       
        }
    }
    

    spring-jms-config.xml

    <bean id="messageListener" class="com.myproj.MyProjectJMSListener" />
    
    <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory"/>  <!-- connectionFactory bean class to be added -->
        <property name="destination" ref="my.jms.destination"/> 
        <property name="messageListener" ref="messageListener" />
    </bean>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2023-01-30
      • 1970-01-01
      • 2019-08-15
      • 1970-01-01
      • 2018-10-27
      • 2018-06-20
      相关资源
      最近更新 更多