【问题标题】:Integration with external systems over JMS. Clustered environment通过 JMS 与外部系统集成。集群环境
【发布时间】:2019-06-01 12:32:43
【问题描述】:

我有一个应用程序,其中我为外部系统 A 创建了 2 个消息侦听器容器,它们分别侦听两个队列。

我还有 1 个消息侦听器容器,它运行并侦听外部系统 B 的另一个队列。我正在使用 spring DefaultMessageListenerContainer。

我的应用程序在集群环境中运行,同时定义了我的消息侦听器容器,我向它注入了我的侦听器,该侦听器实现了 javax MessageListener 接口并充当一种 MDB。

所以我的问题是:

  1. 每个队列都有一个消息侦听器容器实例是否正常?
  2. 我的消息驱动 pojo (MDP) 会在每个应用程序节点上执行 onMessage() 吗?
  3. 如果是,我该如何避免?我希望每条消息在某些应用程序节点上使用一次。
  4. DefaultMessageListenerContainer 的默认行为是什么,在我到达 onMessage 或完成 onMessage 执行后立即确认消息?还是我需要手动确认?

【问题讨论】:

    标签: spring jms integration spring-jms


    【解决方案1】:

    请参阅the spring framework JMS documentation 和 JMS 规范。

    1. 是的,这很正常——一个容器只能监听一个目的地。

    2. 取决于目的地类型;对于一个主题,每个实例都会得到一个消息的副本;对于一个队列,多个侦听器(消费者)将竞争消息。这与 Spring 无关,它是 JMS 的工作方式。

    3. 参见 #2。

    4. 使用 DMLC,它在调用容器之前立即得到确认;设置sessionTransacted = true,这样在侦听器退出之前不会提交ack。使用SimpleMessageListenerContainer,消息在侦听器退出时得到确认。有关差异,请参阅 DMLC 和 SMLC(以及它们的子类抽象类)的 Javadocs。

    【讨论】:

    • 我对我的第二个问题有点困惑,因为我在 doc Asynchronous Reception-Message-Driven POJOs 中看到了这一点,其方式类似于 EJB 世界中的消息驱动 Bean (MDB),消息驱动 POJO (MDP) 充当 JMS 消息的接收者。 MDP 的一个限制(但也请参见下面对 MessageListenerAdapter 类的讨论)是它必须实现 javax.jms.MessageListener 接口。另请注意,如果您的 POJO 将在多个线程上接收消息,请务必确保您的实现是线程安全的。
    • 说的只是同一个应用实例中的并发;如果您将容器货币设置为 > 1,则会创建多个消费者,每个消费者都有自己的线程。因此,您的侦听器必须是线程安全的 - 字段中没有维护状态 - 或者围绕它们进行一些同步(如果长时间持有锁/监视器,这可能会限制实际并发性)。当并发> 1时,每个消费者竞争消息(与有多个应用程序实例时相同)。经纪人对此一无所知,他只是看到多个消费者并分发消息。
    • 你能不能也看看这个 - stackoverflow.com/questions/54169727/…
    猜你喜欢
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 2012-12-21
    相关资源
    最近更新 更多