【问题标题】:JMS fault tolerant asynchronous publisherJMS 容错异步发布者
【发布时间】:2023-04-03 03:48:01
【问题描述】:

在我们的架构中,即使与本地网络的连接丢失,JMS 发布者也可以继续工作(并生成新消息)。是否可以使用 JMS 使发布服务器能够容忍网络或代理中断:

  1. 发布调用可能不会阻止应用程序,即使代理不可用;
  2. 已发布的消息(中断期间)必须在网络连接恢复后传递;

据我了解,可以在每台发布机器上使用嵌入式(本地)代理来完成。如果这是唯一的方法,那么该拓扑是否存在任何不明显的问题 - 性能、维护等?本地代理是否能够自行容忍中断?

【问题讨论】:

    标签: java jms messaging


    【解决方案1】:

    我没有尝试过,但您似乎可以使用本地故障转移来降低阻抗: 使用 ActiveMQ,您可以配置故障转移传输:

    failover:(tcp://primary:61616,tcp://secondary:61616)?randomize=false
    

    尝试绘制这个:

    client +---> primary: network broker <-------+
           |                                     |
           +---> secondary: embedded broker -----+
    

    这里的主要代理是您的网络代理,而您的二级代理是本地嵌入的代理,具有与主要代理的桥接。当客户端发布分配时,这似乎会很好用;我不确定这对于订阅者是否会比@Biju 提出的解决方案更好:如下图所示:

    client +---> secondary: embedded broker ------> primary: network broker 
    

    例如,这是我的嵌入式代理(通常是非持久的)。

    <bean id="activeMQBroker" class="org.apache.activemq.broker.BrokerService">
        <property name="transportConnectors">
            <list>
                    <bean id="brokerConnection" class="org.apache.activemq.broker.TransportConnector">
                        <property name="connectUri">
                            <bean id="brokerURI" class="java.net.URI">
                                <constructor-arg value="tcp://localhost:61616" />
                            </bean>
                        </property>
                    </bean>
            </list>
        </property>
    
        <property name="persistent" value="true" />
    </bean>
    

    【讨论】:

    • 好的,但是如何使第二个代理本身能够容忍连接丢失? broker之间应该采用什么类型的连接,才能防止第二个挂掉,网络恢复后保证消息传递?
    • 嵌入式代理通常有一个文件存储,它将传入消息写入其中。桥应该容忍连接丢失(据我所知)。见activemq.apache.org/jms-to-jms-bridge.html
    • 到目前为止,具有故障转移传输功能的嵌入式代理工作正常。不过,Active MQ 中存在一个错误,它也阻止在订阅者进程中使用嵌入式代理:AMQ-3213。有时,即使使用一个嵌入式代理(发布者)和一个远程,也会出现同样的问题。解决方案似乎是正确的,而 AMQ 似乎有问题。
    • 我记得 ActiveMQ 在故障转移模式下偶尔对我来说似乎是错误的(主要是在我使用它时似乎没有像我预期的那样工作的极端情况),但我不确定它是否是我的设置或我对 JMS 的不了解。
    【解决方案2】:

    我能想到的唯一方法就是按照你的建议 -

    1. 拥有本地嵌入式代理并提供从该嵌入式代理到基于网络的代理的桥梁。即使是本地的也可能出现故障,因此您可能必须在资源(db 和 jms 基础架构)之间以事务方式发布
    2. 不要直接发布,而是有一个抽象来缓冲它 - 到数据库、文件或上面的本地嵌入式 jms,并提供一个从缓冲区到 JMS 队列的桥。

    【讨论】:

    • 我认为,如果嵌入式代理出现故障,则可以将其视为致命的发布者错误,例如数据库层出现故障
    • “缓冲的抽象......” - 完全正确!但我想要开箱即用的功能。如果我必须向它写入额外的缓冲和持久层,为什么还需要 JMS?
    • @Shcheklein,是的,如果消息的来源(db 说)和目的地(jms 队列)可以拉到一个公共事务中(XA),你不必编写任何缓冲层/跨度>
    【解决方案3】:

    如果队列管理器\代理在您描述的情况下非常常见,则分布式架构。

    确切的配置取决于您使用的特定产品,但它通常有据可查且易于管理

    关于本地冗余,您可以在容错配置中使用两个这样的队列管理器(同样——创建容错集群的确切方法取决于产品)——但这似乎有点过头了。

    JMS只对消息队列提供者的API进行标准化,其他的

    【讨论】:

    • 这是 JMS“规范”中最令人沮丧的方面(也没有定义安全性)。您可以编写完美可移植的 JMS 代码,但它不能开箱即用地部署。
    猜你喜欢
    • 2013-08-04
    • 1970-01-01
    • 2016-06-17
    • 2018-03-14
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多