2

I have two JMS-Servers which are linked together as a JMS-Cluster in a standalone-full-ha environment. These servers are hosting my JMS-Destinations (let’s call them JMS-Master).

Additionally there is a server which is configured as standalone-full server (let’s name it JMS-Slave). This server has a JMS-Bridge to a JMS-Topic.

For this configuration I created at the JMS-Slave two socket bindings to the remote servers:

<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>

I use them at two http-connectors at the messaging subsystem configuration:

<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"/>

And I created a pooled-connection-factory:

<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"/>

Finally I configure the 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="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>

The result:

  • If both JMS-Master servers are up and I start the JMS-Slave, everything works.
  • If one of JMS-Master servers is down and I start the JMS-Slave, it works as well. The jms-bridge connects to the available node.
  • But if I shutdown the node to which the JMS Bridge of the JMS-Slave is connected there is no failover.

I am looking for a configuration where the JMS-Bridge is “reconnecting” after a crash to the available node without having it into the same cluster than the JMS-Master.

How can I achieve this? Are there other possibilities to get a similar behavior? Or is there a proposal for a complete different setup?

Stefan Großmann
  • 866
  • 9
  • 20
  • While only slightly related, when I was testing a vendors JMS clients connection to 4 of our servers nodes in a HA Domain, when the topology would change a topology change update was sent out and if I recall correctly, the JMS client would then switch to another of the nodes. I know it doesnt help much. I wonder if you can turn on some debug and see whats *not* occurring – JGlass Feb 01 '18 at 13:37

1 Answers1

2

I think I found two possible solutions for the problem myself. But they have both some disadvantages.

The first one is to use a JMS-Core-Bridge. See Configuring Core Bridges at the Red Hat JBoss docs:

Do not confuse a core bridge with a JMS bridge. A core bridge is used to bridge any two JBoss EAP messaging instances and uses the core API. A JMS bridge can be used to bridge any two JMS 1.1 compliant JMS providers and uses the JMS API. It is preferable to use a core bridge instead of a JMS bridge whenever possible.

The Core-Bridge does a fail-over more or less out of the box. Already with one connector it would do a failover automatically. It retrieves the cluster topology during the first connect and uses it during its lifetime. And to be able to start the bridge if a JMS-Master is down, we can add additional connectors:

<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>

The disadvantage of a core-bridge seems to be that it does not support JMS-Topics out of the box. Only JMS-Queues seem to work without overhead.

But it is possible as well to configure a JMS-Bridge that it reconnects to another server. To establish a connection, the JMS-Bridge proceeds a JNDI-lookup at one of the servers configured by the property "java.naming.provider.url". This lookup is just executed during startup and once it is done, it uses the retrieved remote connection-factory (here named RemoteConnectionFactory) to connect and reconnect. But it is using the RemoteConnectionFactory of the JMS-Master! Therfore it is necessary to configure the this connection factory there:

<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"/>

If this RemoteConnectionFactory has a connector to each JMS-Master, the JMS-Bridge retrieves all necessary information to do a reconnect to another server, if necessary. The bridge configuration of my question is working now without modification:

<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>

The disadvantage of my "jms-bridge configuration" is its complexity.

Stefan Großmann
  • 866
  • 9
  • 20
  • A link to Stefan's detailed (and helpful) example: https://github.com/stefangrossmann/remote-jms-example – Guillaume Aug 25 '20 at 11:37