Configuring JBoss EAP 6 – WildFly to use TCP for messaging

This tutorial shows how to use TCP for initial discovery and communication between cluster nodes of HornetQ servers running on JBoss EAP 6 / WildFly 8

First of all, let’s see the default mechanism used by the HornetQ messaging broker in JBoss/WildFly:

messaging tcp jboss wildfly

As you can see, the first step is server discovery and it’s done by JGroups, by default using UDP. Next, once that the servers have found each other, starts the communication between nodes. This happens via the Netty TCP Connections (JBoss EAP 6) or tunnelled via HTTP /WildFly).

That being said, there are two strategies for switching from UDP to TCP:

1) Rely on JGroups configuration

The simplest choice is to rely on JGroups. So, say for example that you have defined a list of static nodes via TCPPING

<subsystem xmlns="urn:jboss:domain:jgroups:2.0" default-stack="tcpping">
    <stack name="tcpping">
        <transport type="TCP" socket-binding="jgroups-tcp"/>
        <protocol type="TCPPING">
            <property name="initial_hosts">localhost[7600],localhost[7700]</property>
            <property name="port_range">10</property>
            <property name="timeout">3000</property>
            <property name="num_initial_members">2</property>
        </protocol>
        <protocol type="MERGE2"/>
        <protocol type="FD_SOCK" socket-binding="jgroups-tcp-fd"/>
        <protocol type="FD"/>
        <protocol type="VERIFY_SUSPECT"/>
        <protocol type="BARRIER"/>
        <protocol type="pbcast.NAKACK"/>
        <protocol type="UNICAST2"/>
        <protocol type="pbcast.STABLE"/>
        <protocol type="pbcast.GMS"/>
        <protocol type="UFC"/>
        <protocol type="MFC"/>
        <protocol type="FRAG2"/>
        <protocol type="RSVP"/>
    </stack>
</subsystem>

Then in your messaging subsystem comment out the socket-­binding section and include the jgroups-stack which references the JGroups stack (tcpping) and specify a jgroups­channel to be used by your cluster (if using different channels across your server groups you will end-up with a set of sub-clusters):

<broadcast­-groups>                         
   <broadcast-­group name="bg­group1">  
    <!--­­ <socket-­binding>messaging­group</socket-­binding> --­­>                                
   <jgroups­-stack>tcp</jgroups-­stack>                             
   <jgroups­-channel>hq­cluster1</jgroups-­channel>                                               
   <broadcast-­period>5000</broadcast-­period>                             
   <connector­-ref>netty</connector­-ref>                         
   </broadcast-­group>                     
</broadcast­-groups>                     

<discovery-­groups>                         
	<discovery­-group name="dg­group1">                      
        <!­­-- <socket­-binding>messaging­group</socket-­binding> --­­>   
	<jgroups-­stack>tcp</jgroups­-stack>                             
	<jgroups­-channel>hq­cluster1</jgroups­-channel>                             
	<refresh­-timeout>10000</refresh­-timeout>                         
	</discovery-­group>                     
</discovery-­groups>

 WildFly configuration

That above will work with JBoss EAP 6 or AS 7. If you are using WildFly replace the netty connector with the http-connector as shown here:

<broadcast-­groups>                         
   <broadcast-­group name="bg­group1">  
    <!-- ­­<socket-­binding>messaging­group</socket­-binding> --­­>                            
   <jgroups-­stack>tcpping</jgroups-­stack>                             
   <jgroups-­channel>hq­cluster1</jgroups-­channel>                                               
   <broadcast­-period>5000</broadcast-­period>                             
   <connector-­ref>http-connector</connector-­ref>                         
   </broadcast-­group>                     
</broadcast-­groups>                     

<discovery-­groups>                         
	<discovery-­group name="dg­group1">                      
	 <!­­-- <socket-­binding>messaging­group</socket-­binding> --­­>        
	<jgroups-­stack>tcpping</jgroups­-stack>                             
	<jgroups-­channel>hq­cluster1</jgroups­-channel>                             
	<refresh-­timeout>10000</refresh-­timeout>                         
	</discovery­group>                     
</discovery-­groups>

2) Using Clustered static discovery

Sometimes UDP is not available on your network so the initial discovery needs to be done using a static list of servers. This could be just one server that you know will always be available or a list of servers where at least one will be available.

In order to do that, perform the following steps:

1) Comment out the broadcast-group and discovery-groups at first:

<!--
	<broadcast-groups>
		<broadcast-group name="bg-group1">
			<socket-binding>messaging-group</socket-binding>
			<connector-ref>netty-connector</connector-ref>
		</broadcast-group>
	</broadcast-groups>
	<discovery-groups>
		<discovery-group name="dg-group1">
			<socket-binding>messaging-group</socket-binding>
		</discovery-group>
	</discovery-groups>  -->

 2) Next, within your cluster-connections section provide a static-connectors list:

<cluster-connections>
	<cluster-connection name="my-cluster">
		<connector-ref>netty-connector</connector-ref>
			<address>jms</address>                    
			<static-connectors> 
                             <connector-ref>cluster-node1</connector-ref>
			    <connector-ref>cluster-node2</connector-ref>
		        </static-connectors>
	</cluster-connection>	
</cluster-connections>

 3) The connectors  needs to be defined in the <connectors> section:

<connectors>
            <netty-connector name="cluster-node1" socket-binding="node1"/>
            <netty-connector name="cluster-node2" socket-binding="node2"/>
   . . . .
</connectors>

 4) The socket-binding in turn are defined into the socket-binding-group section as follows (supposing you have two other nodes on the same machine with an offset of 100 and 200):

<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
. . . . .
	<outbound-socket-binding name="node1">
		<remote-destination host="localhost" port="8180"/>
	</outbound-socket-binding>		
	<outbound-socket-binding name="node2">
		<remote-destination host="localhost" port="8280"/>
	</outbound-socket-binding>						 
</socket-binding-group>

 WildFly static discover

The same configuration can be applied on WildFly: the only difference is that you will switch from a netty connector to an http-connector.

Step 1) Comment out the broadcast/discovery groups

<!--
	<broadcast-groups>
		<broadcast-group name="bg-group1">
			<socket-binding>messaging-group</socket-binding>
			<connector-ref>http-connector</connector-ref>
		</broadcast-group>
	</broadcast-groups>
	<discovery-groups>
		<discovery-group name="dg-group1">
			<socket-binding>messaging-group</socket-binding>
		</discovery-group>
	</discovery-groups>  -->

 Step 2) use an http-connector

<cluster-connections>
	<cluster-connection name="my-cluster">
		<connector-ref>http-connector</connector-ref>
			<address>jms</address>                    
			<static-connectors> 
                            <connector-ref>cluster-node1</connector-ref>
			    <connector-ref>cluster-node2</connector-ref>
		</static-connectors>
	</cluster-connection>	
</cluster-connections>

 Step 3) Define the Connectors:

<connectors>
      <http-connector name="cluster-node1" socket-binding="node1">
                        <param key="http-upgrade-endpoint" value="http-acceptor"/>
      </http-connector>	
      <http-connector name="cluster-node2" socket-binding="node2">
                        <param key="http-upgrade-endpoint" value="http-acceptor"/>
      </http-connector>
   . . . .
</connectors>

 Step 4) Define the socket bindings:

<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
. . . . .
	<outbound-socket-binding name="node1">
		<remote-destination host="localhost" port="8180"/>
	</outbound-socket-binding>		
	<outbound-socket-binding name="node2">
		<remote-destination host="localhost" port="8280"/>
	</outbound-socket-binding>						 
</socket-binding-group>

 That’s all! Now your full-ha configuration will use a static list of servers.


Recommended Articles

Windup: Migrate Your JBoss EAP 7 Application to JBoss EAP 8 with Detailed Reports and Migration Steps

Learn how to use Windup for a migration report from JBoss EAP 7 to JBoss EAP 8. #Java #Middleware #CloudNative

Deploying Java Web Start Applications on WildFly/JBoss EAP 8

Learn how to deploy Java Web Start applications on WildFly/JBoss EAP 8 with this step-by-step guide.

Choosing the Right JDK for WildFly and JBoss EAP: A Comprehensive Guide

Which Java version should you use for WildFly and JBoss EAP? Check our JDK compatibility guide for WildFly 35+ & EAP 8.x to choose between Java 17, 21 & 25.

JBoss Tutorial for Beginners: JBoss EAP and WildFly quickstart

Discover the basics of JBoss EAP and WildFly in this comprehensive guide. Learn about Jakarta EE compatibility, modular architecture, and more.