Distributed session caching

Caching HTTP sessions in your applications helps provide high availability for users and enables functions such as shopping cart retrieval in e-commerce applications. The JCache Session Persistence feature in Open Liberty provides failover of non-persistent user session data with distributed in-memory HTTP session caching.

You can store HTTP sessions locally on a server, on a relational database, or in the in-memory storage of your application. However, a cached session on the server can be lost if the application instance fails. Also, a relational database might not be part of your application architecture. With distributed caching, you don’t need a single dedicated server or database to store a cached HTTP session. HTTP session cache data is distributed across multiple servers that act as a cluster.

The JCache Session Persistence feature builds on an existing technology called JCache that offers a standardized distributed in-memory caching API. Though the feature builds on JCache, your application doesn’t need to use the JCache API. Open Liberty handles the session caching in the web container layer. For more information about how Open Liberty handles HTTP session data, see the HttpSession interface.

Session caching in your application

Distributed session caching with the JCache Session Persistence feature works the same way as non-distributed session caching in an application. If your application already caches HTTP session data, you don’t need to make any code changes in the application to use the the JCache Session Persistence feature. Instead, configure the JCache Session Persistence feature in your server.xml file and reference the library that contains your chosen JCache implementation. To benefit from the JCache Session Persistence feature, you must join at least two servers together.

The following diagram shows two Open Liberty servers that share a persisted session cache by using a JCache implementation:

diagram that shows multiple Open Liberty servers that share a persisted session cache
Distributed session caching

The diagram shows how multiple Open Liberty servers can share a persisted session cache. Each server stores a local session cache in-memory on the server. By using an underlying JCache provider like Hazelcast, those sessions are persisted. When a new server joins the cluster, it has access to HTTP session data that is created by other servers in the same cluster. Similarly, if a server in the cluster fails, its HTTP session data is preserved by other servers in the cluster. Besides the open source Hazelcast implementations, you can also use other implementations like WebSphere eXtreme Scale, Infinispan, and Ehcache.

Join multiple servers together

The JCache Session Persistence feature is only useful when it is connected to at least one other server, which forms a cluster. Open Liberty servers can behave in the following ways in a cluster:

Client-Server model

An Open Liberty server can act as the JCache client and connect to a dedicated JCache server.

Peer-to-Peer model

An Open Liberty server can connect with other Open Liberty servers that are also running with the JCache Session Persistence feature and configured to be part of the same cluster.

Your choice of model depends on the needs of your application, the resources that are available, and the specifications of your chosen JCache implementation. Each JCache implementation configures the cluster instances differently. For more information, see the documentation for your chosen implementation.

The following examples show two applications, service A and service B, that are both running on different Open Liberty servers that are part of the same cluster. In the example, service A sets the value for the foo attribute to equal bar. Service B can then retrieve that value for the foo attribute from the distributed cache that is shared by all servers in the cluster.

@WebServlet("/ServiceA")
public class ServiceA extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.setAttribute("foo", "bar");
    }
}
@WebServlet("/ServiceB")
public class ServiceB extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        String result = session.getAttribute("foo");
        System.out.println("Session attribute foo=" + result);
    }

}

Customize your JCache implementation

Most JCache implementations provide sensible default settings. However, if you need to customize your implementation, you can specify a JCache configuration file and reference it from your server.xml file. The following example Hazlecast configuration file customizes how Hazelcast defines the cluster:

<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-3.9.xsd"
           xmlns="http://www.hazelcast.com/schema/config"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <group>
    <name>myCluster</name>
    <password>super-secret</password>
  </group>
</hazelcast>

In this example, specifying the myCluster group name causes the Hazelcast instance to connect only with other instances that are also named myCluster.