【问题标题】:How to connect to multiple VPNs using "solace-jms-spring-boot" API如何使用“solace-jms-spring-boot”API 连接到多个 VPN
【发布时间】:2019-02-13 02:51:40
【问题描述】:

我成功地实现了 Spring-boot 应用程序以连接到单个 VPN,并使用此处提供的说明从/向该 VPN 上的队列消费/产生消息(非常有帮助): https://github.com/SolaceProducts/solace-jms-spring-boot

但现在我正在努力解决以下问题: 根据我的阅读,使用此属性,我们只能指定一个 VPN:solace.jms.msgVpn

如何连接到 2 个不同的 VPN 并从每个 VPN 中的队列消费/生产/生产?我们可以在同一个 Spring Boot 应用程序中执行此操作吗?

任何帮助将不胜感激。

另一个问题 - 我们如何使用这些 API 确认返回的消息?

【问题讨论】:

    标签: spring-boot jms solace


    【解决方案1】:

    虽然您目前无法使用 solace-jms-spring-boot 一次连接多个 VPN,但您有两种选择:

    1. 在不同的主题上发布回同一个 VPN,并使用 VPN 桥将其桥接到另一个 VPN。这种方法的优点是,如果需要,您可以桥接到许多其他 VPN,这些 VPN 可以位于同一个或另一个代理上。由于这是在管理上完成的,因此除了发布到新主题外,不需要对应用程序进行任何更改。请注意,您需要配置网桥和订阅,这需要管理访问权限。如果您使用新的动态消息路由功能,您可以减少或消除与配置主题相关的管理负担。 DMR 跨多个站点工作,并在添加或删除订阅时动态处理消息路由。

    2. 在您的 Spring Boot 应用程序中使用 Solace Spring Cloud Stream (SCS) binder(可在 GitHub 和 Maven Central 上获得)。 binder 支持在同一个应用程序中使用相同或不同传输方式的多个 binder - 在这种情况下,您可以将两个 Solace binder 定义到同一个 broker 但具有不同的 VPN 名称。

    关于确认消息,使用 solace-jms-spring-boot 您不需要显式确认消息,因为 Spring JMS 使用本地事务。如果您的回调引发异常,则事务将回滚,否则将提交。如果它被回滚,默认情况下消息将返回队列并重新传递。这可能会导致您的应用程序进入无限循环尝试处理错误消息,因此建议在队列上设置属性max-redelivery > 0,并指定一个死消息队列,中毒消息将在超过重新发送限制。默认情况下,DMQ 是#DEAD_MSG_QUEUE,您可能需要创建它。请注意,消息还必须在 DMQ 合格标志设置为 true 的情况下发布。

    如果您决定改用 SCS 绑定器,则确认机制会有所不同,并且不使用本地事务,而是由 SCS 管理。有关重试、DMQ(也称为 DLQ)以及全局和应用程序级错误处理程序的详细信息,请参阅 SCS 参考文档。由于 SCS 提供了类似的功能,您不需要在代理上配置 max-redelivery 或 DMQ,并且消息不需要设置 DMQ 合格标志。相反,您需要在应用程序属性/YAML 中配置错误处理。一般来说,当你的应用抛出异常时,会尝试重新投递,超过投递限制(默认为 3 次)后,要么进入 DLQ,要么进入应用或全局级别定义的错误处理程序。如前所述,这将取决于您的配置。

    禁用本地事务的示例是here。然后您可以使用setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE) 启用客户端确认。但是,任何异常都不能回滚其他操作(例如,如果您在另一个会话上发布回复)。请注意,您的 @JmsListener 注释应指定引用您的容器工厂的 containerFactory 参数。

    根据DefaultMessageListenerContainer 的文档,如果您想避免消息丢失或非原子操作,最好使用事务。当您的回调成功返回时,事务和客户端确认均已完成。

    【讨论】:

    • 感谢您的回复。我使用解决方法在我的 getDefJmsListenerFactory() 方法中初始化 SolConnectionFactory 并手动设置 VPN 和其他连接属性。
    • SolConnectionFactory scf = SolJmsUtility.createConnectionFactory(); scf.setVPN(env.getProperty("vpn.name")); factory.setConnectionFactory(scf);
    • 关于消息确认,您提到 Spring 使用本地事务。所以如果我设置 factory.setSessionTransacted(false);它还会向路由器确认消息吗?
    • 请查看添加的新详细信息以解决您的问题:无交易。
    猜你喜欢
    • 2018-09-06
    • 2020-09-13
    • 2021-10-03
    • 2017-03-13
    • 2021-09-17
    • 2019-05-19
    • 2014-11-16
    • 1970-01-01
    • 2021-11-20
    相关资源
    最近更新 更多