Stefan Großmann
Stefan Großmann

Reputation: 1026

Is it possible to configure a failover for JMS-Bridge to a JMS-Cluster with Wildfly 10?

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:

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?

Upvotes: 2

Views: 1175

Answers (1)

Stefan Gro&#223;mann
Stefan Gro&#223;mann

Reputation: 1026

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.

Upvotes: 2

Related Questions