EJB Load Balancing across multiple clusters in JBoss EAP 7.1+

Solution Unverified - Updated

Environment

Red Hat JBoss Enterprise Application Platform

Issue

  • We have two clusters containing 3 nodes each and does JBoss EAP 7.1 support EJB load balancing across more than 1 JBoss Cluster?

Resolution

It is recommended that you load balance across only one cluster, as it is an unusual use case to load balance EJBs across more than one cluster, as typically the cluster would have all the same EJBs deployed in them.

If you list a host1 in cluster1 and host2 in cluster2 in the InitialContext, then it will connect to host1 and stick to cluster1 unless host1 is unavailable, then it will failover to host2 and stick to cluster2.

To load balance across 2 clusters, you would need to invoke the EJBs over HTTP and use a loadbalancer that points to both clusters. In JBoss EAP 7.1 it has a technology preview where you can invoke an EJB over Http through a load balancer, and in EAP 7.2 this feature will be fully supported. If the same EJB is in two different clusters, you could use a load balancer and invoke the EJB via the Load Balancer where the Load Balancer can route to all nodes in both clusters.

How to invoke an EJB / JNDI over HTTP in EAP 7.1

If an InitialContext is created with 2 hosts, each in a different JBoss cluster, then once an EJB request is made to the hosts, the client will get the cluster view returned for that cluster and then attempt to establish connections to those cluster nodes. After which it will load balance across the cluster, but it will establish a cluster affinity to one of the clusters, as typically a client will want to call a particular cluster and not have EJB calls going to different clusters.

  public static Context getInitialContext(String host1, Integer port1, String host2, Integer port2, String username,
    String password) throws NamingException {
    Properties props = new Properties();
    props.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");
    props.put(Context.PROVIDER_URL, String.format("remote+http://%s:%d,remote+http://%s:%d", host1, port1, host2, port2));
    if (username != null && password != null) {
       props.put(Context.SECURITY_PRINCIPAL, username);
       props.put(Context.SECURITY_CREDENTIALS, password);
    }    
    return new InitialContext(props);
  }

Related Solutions

Components
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.