是否可以使用 Wildfly 10 配置 JMS-Bridge 到 JMS 集群的故障转移?



我有两个JMS服务器,它们在独立的全ha环境中作为JMS集群链接在一起。这些服务器托管着我的JMS目的地(我们称之为JMS-Master)。

此外,还有一个服务器被配置为独立的完整服务器(我们将其命名为JMS-Slave)。此服务器具有指向 JMS 主题的 JMS 桥。

对于此配置,我在 JMS-Slave 上创建了两个到远程服务器的套接字绑定:

<outbound-socket-binding name="remote-server-1">
<remote-destination host="a.b.c.d" port="8080"/>
</outbound-socket-binding>
<outbound-socket-binding name="remote-server-2">
<remote-destination host="a.b.c.d" port="18080"/>
</outbound-socket-binding>

我在消息传递子系统配置的两个 http 连接器上使用它们:

<http-connector name="remote-1-http-connector" socket-binding="remote-server-1" endpoint="http-acceptor"/>
<http-connector name="remote-2-http-connector" socket-binding="remote-server-2" endpoint="http-acceptor"/>

我创建了一个池连接工厂:

<pooled-connection-factory name="remote-connection" entries="java:/jms/remoteCF" connectors="remote-1-http-connector remote-2-http-connector" user="testuser" password="testpassword" failover-on-initial-connection="true"/>

最后,我配置 JMS 桥:

<jms-bridge name="HelloWorldQueue-jms-bridge" quality-of-service="DUPLICATES_OK" failure-retry-interval="5000" max-retries="-1" max-batch-size="10" max-batch-time="100">
<source connection-factory="ConnectionFactory" destination="queue/HelloWorldQueue"/>
<target connection-factory="jms/RemoteConnectionFactory" destination="queue/HelloWorldQueue" user="heinz" password="becker" >
<target-context>
<property name="java.naming.factory.initial" value="org.jboss.naming.remote.client.InitialContextFactory"/>
<property name="java.naming.provider.url" value="http-remoting://a.b.c.d:8080, http-remoting://a.b.c.d:18080"/>
</target-context>
</target>
</jms-bridge>

结果:

  • 如果两个JMS主服务器都启动了,并且我启动了JMS-Slave, 一切正常。
  • 如果其中一个 JMS 主服务器关闭并且我启动了 JMS-Slave,它 也有效。jms 网桥连接到可用节点。
  • 但是如果我关闭JMS从属的JMS桥到的节点 已连接,没有故障转移。

我正在寻找一种配置,其中 JMS 桥在崩溃到可用节点后"重新连接",而没有将其放入与 JMS-Master 相同的集群中。

我怎样才能做到这一点?是否有其他可能性可以获得类似的行为?或者是否有一个完全不同的设置的建议?

我想我自己找到了两种可能的解决方案。但它们都有一些缺点。

第一个是使用 JMS 核心桥。请参阅红帽 JBoss 文档中的配置核心网桥:

不要将核心网桥与 JMS 网桥混淆。使用核心桥 桥接任意两个 JBoss EAP 消息传递实例并使用核心 API。 JMS 桥接可用于桥接任意两个符合 JMS 1.1 的 JMS 提供程序并使用 JMS API。最好使用核心桥 而不是尽可能使用 JMS 桥。

核心网桥或多或少是开箱即用的故障转移。已经使用一个连接器,它会自动进行故障转移。它在第一次连接期间检索群集拓扑,并在其生存期内使用它。为了能够在 JMS-Master 关闭时启动网桥,我们可以添加其他连接器:

<subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">
<server name="default">
....
<bridge name="my-core-bridge" static-connectors="remote-1-http-connector remote-2-http-connector" queue-name="jms.queue.HelloWorldQueue" user="username" password="pwd"/>
</server>
...
</subsystem>

核心桥的缺点似乎是它不支持开箱即用的JMS-Topics。只有 JMS 队列似乎在没有开销的情况下工作。

但是也可以配置一个JMS桥,它重新连接到另一个服务器。为了建立连接,JMS-Bridge 在属性"java.naming.provider.url">配置的服务器之一上进行 JNDI 查找。此查找仅在启动期间执行,一旦完成,它将使用检索到的远程连接工厂(此处称为 RemoteConnectionFactory)进行连接和重新连接。但它使用的是JMS-Master的RemoteConnectionFactory!因此,有必要 在此处配置此连接工厂:

<connection-factory name="RemoteConnectionFactory" entries="java:jboss/exported/jms/RemoteConnectionFactory" connectors="master-1-http-connector master-2-http-connector" ha="true" block-on-acknowledge="true" reconnect-attempts="-1"/>

如果此 RemoteConnectionFactory 具有连接到每个 JMS 主服务器的连接器,那么 JMS-Bridge 将检索所有必要的信息,以便在必要时重新连接到另一台服务器。我问题的桥配置现在可以工作而无需修改:

<jms-bridge name="HelloWorldQueue-jms-bridge" quality-of-service="DUPLICATES_OK" failure-retry-interval="5000" max-retries="-1" max-batch-size="10" max-batch-time="100">
<source connection-factory="ConnectionFactory" destination="queue/HelloWorldQueue"/>
<target connection-factory="jms/RemoteConnectionFactory" destination="queue/HelloWorldQueue" user="username" password="pwd" >
<target-context>
<property name="java.naming.factory.initial" value="org.jboss.naming.remote.client.InitialContextFactory"/>
<property name="java.naming.provider.url" value="http-remoting://a.b.c.d:8080, http-remoting://a.b.c.d:18080"/>
</target-context>
</target>
</jms-bridge>

我的"jms-bridge配置"的缺点是它的复杂性。

最新更新