Sticky session configuration in WildFly

This article is a walk through the configuration of Sticky sessions in Web applications which you are running on the top of WildFly application server or JBoss EAP.

What is a Sticky Session ?

Sticky session is a mechanism by which HTTP Requests (identified by an unique HTTP Session) are served by the same application server node. There are several ways to configure Sticky sessions in WildFly depending on the version of the application server.

In any case, make sure that your applications has been configured for clustering, including the distributable element in web.xml:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
   <distributable/>
</web-app>

In the next paragraphs, we will go through the most common configurations.

WildFly as front end load balancer

In this kind of configuration, a WildFly using the load-balancer profile, sits in front of a cluster of WildFly servers. If you are new to this configuration, check this article: Configuring WildFly as Load Balancer for a Cluster

This is the simplest option. The embedded Web Server (Undertow) does not need any specific configuration in order to maintain session stickiness. You can check the value of sticky-session through the proxy resource of modcluster.

[standalone@localhost:9990 /] /subsystem=modcluster/proxy=default:read-resource
{
    "outcome" => "success",
    "result" => {
        "advertise" => true,
. . . . .
        "smax" => -1,
        "socket-timeout" => 20,
        "ssl-context" => undefined,
        "status-interval" => 10,
        "sticky-session" => true,
        "sticky-session-force" => false,
        "sticky-session-remove" => false,
        "stop-context-timeout" => 10,
        "ttl" => -1,
        "worker-timeout" => -1,
        "dynamic-load-provider" => {"configuration" => undefined},
        "load-provider" => {"dynamic" => undefined},
        "ssl" => undefined
    }
}

As you can see, by default the sticky-session attribute is true. More in detail, here is a description of the three attributes you can set to configure session stickiness:

  • sticky-session, if true, the load balancer will try to keep the session on the node it originated from. If the node is not responsive and sticky-session-force is false, the balancer will route the request to a different node.
  • sticky-session-force, if true, the session sticks to the node it originated from, throwing an exception when it’s not available. Please note: when true this option de facto disables failover of HTTP Sessions
  • sticky-session-remove, if true, the balancer removes the stickiness to the former node after a failover. When false, the balancer returns the session to the former node when it becomes available again.

Important! Since WildFly 18 it’s possible to use the ranked load balancing mechanism. You can read more here: Configuring Ranked Load Balancing in WildFly

Mod_cluster as front end load balancer

Another option is to use Apache’s mod_cluster’s modules to communicate with WildFly cluster. Also in this case, to check if sticky sessions are enabled, query the sticky-session attribute::

/subsystem=modcluster/proxy=default:read-resource(include-runtime=true)
{
    "outcome" => "success",
    "result" => {
     . . . .
        "sticky-session" => true,
        "sticky-session-force" => false,
        "sticky-session-remove" => false,
        "stop-context-timeout" => 10,
        "ttl" => -1,
        "worker-timeout" => -1,
        "dynamic-load-provider" => {"configuration" => undefined},
        "load-provider" => {"dynamic" => undefined},
        "ssl" => undefined
    }
}

As you can see, sticky-session is by default set to true.

Now let’s see in practice how it works.Assumed you have set up a cluster of WildFly application servers, we will now run a two node clusters, using mod_cluster in front of it:

jboss as 7 clustering sticky session mod_cluster

Let’s try running a sample Servlet which dumps some logs on the node where it’s being executed:

jboss eap tutorial install
As you can see, our minimal JSP (which dumps the sessionid), is running on the same server node between each request.
Now let’s test set to false the sticky-session attribute as follows:

/subsystem=modcluster/proxy=default:write-attribute(name=sticky-session,value=false)

As you can see, with sticky-session=”false”, each request is balanced across the cluster and, using the default session replication to keep data in synch between nodes.

jboss eap tutorial install

Besides it, it’s worth to notice the other the value of the other attributes included in the mod_cluster’s proxy element:

  • sticky-session-force: Indicates whether the reverse proxy should run an error in the event that the balancer is unable to route a request to the node to which it is stuck.
  • sticky-session-remove: Indicates whether the reverse proxy should remove session stickiness in the event that the balancer is unable to route a request to the node to which it is stuck.

Configuring sticky sessions with mod_jk

Then, if you are using mod_jk to load balance requests in front of your wildFly cluster, you can use the following sample configuration:

worker.list=loadbalancer, status

worker.template.port=8009
worker.template.type=ajp13
worker.template.ping_mode=A
worker.template.socket_timeout=10

worker.node1.reference=worker.template
worker.node1.host=192.168.1.100

worker.node2.reference=worker.template
worker.node2.host=192.168.1.101

worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=node1,node2
worker.loadbalancer.sticky_session=True

worker.status.type=status

Make sure that worker nodes are part of a loadbalancer and that loadbalancer is in the worker.list. Sticky sessions are enabled by default. In the above example they are in the configuration just for your reference.

Using Apache Apache Module mod_proxy_balancer

If you want to use a pure httpd solution, then you can add the Apache Module mod_proxy_balancer to your configuration.

<Proxy balancer://mycluster>
  BalancerMember http://localhost:8080 route=instance1
  BalancerMember http://localhost:8180 route=instance2
</Proxy>
<Location /webapp>
  ProxyPass balancer://mycluster/webapp stickysession=JSESSIONID
</Location>

This approach is transparent to clients and back-ends. However it suffers from some problems: unequal load distribution if clients are hidden behind proxies, stickyness errors when a client uses a dynamic IP address that changes during a session. Finally, loss of stickyness, if the mapping table overflows.

Found the article helpful? if so please follow us on Socials