HTTP sessions are used to manage state. A common example is the contents of a shopping cart. A user might make multiple visits to a site over a period of hours or days, all the time putting more items in their cart. This article looks at how to manage this data across multiple HTTP sessions on WebSphere Liberty in AWS.

Welcome to the next in our series of articles on WebSphere Application Server in Amazon Web Services. The first article covered scaling and load balancing WebSphere Liberty, and the second article added in support for Docker and continuous integration. See those articles for an introduction to WebSphere Liberty and Amazon Web Services (AWS).

Approaches to HTTP session management

This article focuses on how to manage state data, such as the contents of a shopping cart, across HTTP sessions. There are different approaches to managing this state data. The simplest is to store each user’s session state in memory and then always route each session to the same server instance. Other common approaches include persisting session state to a database or sharing it across server instances using a distributed in-memory data grid. Let’s briefly look at the pros and cons of these approaches in an environment like AWS.

Storing state data in memory

Load balancing in AWS is performed at the level of virtual machines, or containers. Application servers will be regularly created and destroyed under a normally fluctuating workload. Storing state in memory will result in customers regularly finding their carts empty, even without unscheduled outages. That might be okay for some classes of application, but isn’t acceptable for the purposes of this article. We need to store state in a database or grid.

Storing state data in a relational database

A database is a valid choice for many customers. Liberty supports session persistence to a relational database via the sessionDatabase-1.0 feature. Amazon offers a cloud-based Relational Database Service (RDS). Other customers will have a relational database hosted in the AWS environment to store session state in.

Storing session state in a relational database will not be the right answer for everyone, though. As Amazon states:

‘With a Classic Load Balancer, we recommend that you enable multiple Availability Zones. With an Application Load Balancer, we require you to enable multiple Availability Zones.’

Storing state data in a distributed, in-memory grid

All serious AWS deployments should span multiple Availability Zones within a region. Customers not wanting to use Amazon RDS might find that distributing a database server across multiple availability zones makes its deployment very complex. Others might find that they have too much session-based activity which makes constant database access impractical. As the IBM Redbook WebSphere eXtreme Scale v8.6 Key Concepts and Usage Scenarios states:

In a well-crafted application, the database is often the limiting bottleneck resource. This is because when application servers become bottlenecks, they can be scaled out horizontally effectively. They scale out well because they primarily communicate only with the database, with little communication between each other. Scaling out a database is not nearly as easy nor effective.

In these cases, a distributed in-memory data grid can be used as a session cache. By replicating session state across the application server tier, a grid can ensure that users’ session state remains available even when individual application servers are stopped or fail. There are, of course, many data grids on the market. The Amazon ElastiCache web service offers Memcached or Redis, both of which are popular alternatives. This article shows how we can instead use WebSphere eXtreme Scale Liberty Edition (XSLD), an IBM product, to fill this role.

WebSphere eXtreme Scale (WXS)

WebSphere eXtreme Scale provides a high-performance, highly scalable caching framework. It can be used to cache HTTP session data, servlet and JSP fragments, and all sorts of application data and objects. See the IBM Redbook for a comprehensive overview.

This article outlines what is required to implement a highly available cache for HTTP session data. Our front tier of application servers will be load balanced by AWS: their lifetimes may be quite short. The cache is implemented as a second tier of WXS servers. Both tiers will be spread across multiple Availability Zones. WXS stores data in a data grid, conceptually, a distributed hash table. A grid is hosted by a data cache, a collection of WXS servers. A data cache can contain multiple member servers.

WXS can run either on WebSphere traditional or WebSphere Liberty servers. Similarly, WXS caches can be accessed from client applications running on either platform. In this case we will use Liberty throughout. Here’s a picture of the overall design:


xsld-deploment-1

Installing, configuring, and testing

This section summarizes what we learned from getting XSLD up and running in our AWS test environment.

Network configuration

The picture above shows how you can divide Liberty and XSLD instances across Availability Zones, but your own requirements may result in a very different network infrastructure. There’s a lot to consider when architecting an Amazon Virtual Private Cloud (VPC), as this 2014 article by Harish Ganesan demonstrates. The main eXtreme Scale-specific considerations are DNS naming and port configuration:

  • The XSLD server provides a graphical administration console on https://host:9443/wxsui, and a graphical interface to its REST-based administration endpoints on https://host:9445/ibm/api/explorer. Hosts in Amazon EC2 have an internal IP address and host name. They may also have an internet- or VPN-facing IP address and host name. The default host name for a virtual machine in EC2 is of the form ip-internal-ip-address.aws-zone.compute.internal. For security purposes, the XSLD API explorer is only accessible using the default host name; for example, https://ip-10.0.1.100.eu-central-1.compute.internal:9445/ibm/api/explorer. You may need to add a hosts entry on your client machine to be able to access this URL.
  • For port configuration, this article covers the main firewall traffic flows for the WXS (not XSLD) product. The most important difference we’ve seen is that the default XSLD listener port is 4809, compared to 2809 on WXS. WXS client to XSLD flows are initiated against port 4809, but then include random port numbers in the 30000-65535 range.
  • XSLD cache members communicate between themselves on ports 1527 and 6601.

eXtreme Scale client

The XSLD client is an extension to the WebSphere Liberty runtime. You can download a developer-licensed copy of WebSphere eXtreme Scale V8.6.1 for Developers – Liberty Profile. The client is packaged as a self-extracting JAR file, which you extract over an existing Liberty V16.0.0.x installation. The client-side configuration in the server.xml is straightforward:

<featureManager>
  <feature>elasticCacheClient-1.0</feature>
</featureManager>

<httpSessionElasticCache enabled="true">
  <elasticCacheClient>
    <elasticCacheCatalogCluster> 
      <server host="xsld.instance.1" port="4809"/> 
      <server host="xsld.instance.2" port="4809"/>
    </elasticCacheCatalogCluster>
  </elasticCacheClient>
</httpSessionElasticCache>
  

Note that the elasticCacheClient-1.0 feature in eXtreme Scale V8.6.1 replaces the eXtremeScale.webapp-1.1 and eXtremeScale.webGrid-1.1 features provided with V8.6.0 and earlier.

eXtreme Scale Liberty Deployment (XSLD) server

You can download a developer-licensed version of eXtreme Scale Liberty Deployment V8.6.1. Install it using IBM Installation Manager, either via the GUI or command line. You can do the post-installation configuration through the graphical administrative console on https://host:9443/wxsui, or using the REST administration UI on https://host:9445/ibm/api/explorer. Be sure that your REST client can reach the admin server’s internal DNS address, as per the network configuration section above. The key post-installation tasks are to:

  • Create a user
  • Create a group and add the user to that group
  • Create a grid, owned by the user you just created

Add additional members to a cache group using either the admin GUI or the REST admin API.

Testing HTTP session management and failover

HTTP session management is an extensive topic. For more information, read an extensive overview of the HTTP session management and an important set of best practices.

As discussed in the introduction, HTTP session state can be stored in memory or persisted using a database or data grid. Session persistence can be added to an application without changing the Java code: it’s enough to add and configure the elasticCacheClient-1.0 feature. There’s no way to tell at the browser that a session is being managed by eXtreme Scale. Any Liberty client will have three cookies: IBMSessionHandle_session, JSESSIONID and IBMID. We tested our setup in the following order:

  1. Install one XSLD instance, configured as above.
  2. Install two instances of WebSphere eXtreme Scale V8.6.1 for Developers – Liberty Profile (XSLD). Add and configure the elasticCacheClient-1.0 feature as above, both pointing to the same XSLD instance.
  3. Check for consistent javax.servlet.http.HttpSession attributes when directing a web browser from one Liberty instance to another.
  4. Install a second XSLD instance, configured as a second member of the existing cache group.
  5. HttpSession attributes should remain consistent if you remove either elasticCacheCatalogCluster entry from either Liberty client, or stop either XSLD server instance.

If you are looking for sample code, the WebSphere eXtreme Scale HTTP Session sample may prove useful. The downloadable ZIP file contains application source code, a packaged WAR file, and documentation which, while slightly dated, is still very informative. You can drop the WAR file straight into the dropins folder in a configured Liberty client, and then access it using a web browser at (by default) http://host:9080/HttpSessionWAR/HttpSessionSampleServlet.

Advanced topics

Multi-master replication (MMR)

We’ve shown how to add multiple members to a cache group in XSLD. This can be done for performance and availability, and is suitable for servers in multiple availability zones within a single AWS region. Replication between cache group members can be synchronous, taking place within a given transaction. Liberty clients using the elasticCacheClient-1.0 feature will seamlessly fail over between members of a single cache group.

Multi-master replication is a different technology, suitable more for disaster recovery purposes. Clients will not automatically fail over between multiple masters. Masters replicate asynchronously, outside of particular transactions. MMR is suitable for replication between geographically distant XSLD installations–between regions, in AWS terms. For more information, see this discussion of typical topologies.

To configure MMR then you must edit /opt/IBM/WebSphere/eXtremeScale/wlp/usr/servers/cs-default-[server-name]/server.xml within each installation. For example, if we have cacheGroup1 on hostA and cacheGroup2 on hostB, then this configuration should be added to hostA, where hostA and hostB are fully qualifed DNS names:

    <elasticCacheCatalogCluster id="cluster2" domainName="cacheGroup2">
         <server host="hostB" port="4809"/>
    </elasticCacheCatalogCluster>

    <elasticCacheCatalog name="hostA"
                         domainName="cacheGroup1"
                         enableMBean="true"
                         exitJVMOnTearDown="true"
                         mmrRef="cluster2"/>
  

For hostB add the following configuration:

    <elasticCacheCatalogCluster id="cluster1" domainName="cacheGroup1">
         <server host="hostA" port="4809"/>
    </elasticCacheCatalogCluster>

    <elasticCacheCatalog name="hostB"
                         domainName="cacheGroup2"
                         enableMBean="true"
                         exitJVMOnTearDown="true"
                         mmrRef="cluster1"/>
  

Manual connection to the WXS grid

WebSphere eXtreme Scale provides an API by which clients can connect to and interact with data grids. By default, a Liberty client can connect to an XSLD server with code of the form:

import com.ibm.websphere.objectgrid.ClientClusterContext;
import com.ibm.websphere.objectgrid.ObjectGrid;
import com.ibm.websphere.objectgrid.ObjectGridManager;
import com.ibm.websphere.objectgrid.ObjectGridManagerFactory;
import com.ibm.websphere.objectgrid.security.config.ClientSecurityConfiguration;
import com.ibm.websphere.objectgrid.security.config.ClientSecurityConfigurationFactory;
import com.ibm.websphere.objectgrid.security.plugins.builtins.UserPasswordCredentialGenerator;

// ...

ClientSecurityConfiguration csc = ClientSecurityConfigurationFactory.getClientSecurityConfiguration();
csc.setSecurityEnabled(true);
csc.setCredentialGenerator(new UserPasswordCredentialGenerator("username", "password"););
ObjectGridManager ogm = ObjectGridManagerFactory.getObjectGridManager();
ClientClusterContext ccc = ogm.connect("xsld.server.name:4809", csc, (URL) null);
ObjectGrid og = ogm.getObjectGrid(ccc, "testgrid1");

This sample prints out the contents of a particular grid:

import java.util.Iterator;
import com.ibm.websphere.objectgrid.ObjectMap;
import com.ibm.websphere.objectgrid.Session;
import com.ibm.websphere.objectgrid.Session.TxCommitProtocol;
import com.ibm.websphere.objectgrid.query.ObjectQuery;

// ...

private void printGrid (ObjectGrid og, PrintWriter pw, String gridName) throws Exception { 
  Session s = og.getSession();
  ObjectMap orderMap = s.getMap(gridName);
  s.setTxCommitProtocol(TxCommitProtocol.TWOPHASE);
  s.begin();
  ObjectQuery query = s.createObjectQuery("SELECT o FROM " + gridName + " o ");
  query.setPartition(-1);
  Iterator result = query.getResultIterator();
  while (result.hasNext()) { 
    Object o = result.next();
    pw.println("Found grid entry with value: " + o.toString() + "<br/>");
  }
  s.commit();
}

The WXS Knowledge Center and IBM Redbooks have many more extensive examples of programming to the WXS API.

Summary

HTTP session management is an important aspect of modern web applications. A production environment should be designed so that session state is persisted efficiently while allowing the number of application server instances to vary over time. Session state can be stored in local memory, or persisted to a database or an in-memory data grid. In this article we have shown how to use WebSphere eXtreme Scale Liberty Deployment as an HTTP session cache in the Amazon AWS environment. This can be done without changing application code, and gives a highly available solution distributed across multiple availability zones in an AWS region.

Acknowledgements

I’d like to thank Paul Chen, Abelard Chow, Gary DeVal and Jared Anderson for their invaluable help and advice during the writing of this article.

12 comments on"HTTP session management with WebSphere Liberty, eXtreme Scale, and Amazon Web Services"

  1. Carey Foushee June 30, 2017

    I login into app1 and store the User object in the Session in app1 using a managed bean. I then click a link that takes me to a page in app2. The @WebFilter intercepts the request and checks whether the session contains the User, but it does not find it there so it redirects them to the login page.

    I see this error in the log.

    [ERROR ] CWOBJ630E: The [[Lcom.ibm.ws.bytebuffer.internal.FastSyncHashBucket; class cannot be found in the application environment. Exception: java.lang.ClassNotFoundException: com.ibm.ws.bytebufffer.internal.FastSyncHashBucketat org.eclipse.osgi.internal.loader.BundleLoader.findClassInteral(BundleLoader.java:461)
    ….

    CONFIGURATION:

    I am using liberty 16.0.0.4 and running XSLD 8.6.1.2. I have 2 applications deployed to the same instance of liberty. I have a data grid named “session” I created using the Session type in the XSLD admin console.

    Here’s the liberty/wxs configuration:

    elasticCacheClient-1.0

    </httpSessionElasticCache

    Also, In the client web browser I can see that there is only one Cookie JSESSIONID for that server for path “/”, and I can see this in the data grid when I use the wxsui to look at the data.

  2. Neil Kolban June 26, 2017

    The links in the section:

    HTTP session management is an extensive topic. For more information, read an extensive overview of the HTTP session management and an important set of best practices.

    Do not seem to be valid anymore.

  3. JohnsonZhouJohnson December 13, 2016

    Would you please tell more about extreme liberty client and XSLD server configuration?
    1) the complete configuration file or both client side and server side or examples are welcome
    2) After download “developer-licensed version of eXtreme Scale Liberty Deployment V8.6.1”, unzip the file, run the relative server, accessing https://host:9443/wxsui needs username and password. According to the IBM information center, if using installation manager you can set password. But what’s the password if only using unzip to install?

    • Mark Nuttall December 15, 2016

      Hello, I was unable to get the unzip install to work. When I was writing the article, the unzip install only created one of the several server instances required for XSLD to work. Are you able to use the Installation Manager route? InstallationManager will correctly create all the server.xml files necessary for XSLD to start and function correctly.

      • JohnsonZhouJohnson December 19, 2016

        I got it worked under IBM’s help. For the unzip file, need to run command startXSMember to set the password and start relative servers.

        • @JohnsonZhouJohnson, the zip installation is unfotunately pretty `fu` at least for Linux. In addition to startXSMember script, you will have to:
          – make sure that Derby database is started before starting XSLD servers (there are some errors in the startup scripts, and I had to call script startNetworkServer manually)
          – find XSLD/wlp/usr/shared/config/serverSecurityConfig.xml and manually add there attribute authenticationSecret=”yourSecretKey” in the element
          – once you successfully started XSLD UI, create data grid for sessions.
          – configure your Liberty server for using XS by adding the following:

          elasticCacheClient-1.0

          – I’ve also added custom cloneId and reuseId in session config:

          Hope it will help you.

          • I see it has eaten whole server.xml config, so adding it once again, with tags removed:

            featureManager
            feature elasticCacheClient-1.0 feature
            /featureManager

            httpSessionElasticCache enabled=”true” gridName=”sessionGRidNameFromXS”
            elasticCacheClient
            elasticCacheCatalogCluster
            server host=”catalogServerHostName” port=”4809″
            elasticCacheCatalogCluster
            /elasticCacheClient
            /httpSessionElasticCache

            httpSession cloneId=”${wlp.server.name}” idReuse=”true”

      • JohnsonZhouJohnson December 19, 2016

        Mark, I still have trouble configuring the XSLD and client side server.xml configuration for “HTTP session management and failover”, do you have more detail of that session? The article is a little bit simple to describe the configurations. Thanks.

        • Mark Nuttall January 03, 2017

          Hello, the ‘elasticCacheCatalogCluster ‘ config in the ‘eXtreme Scale client’ section above was all the client side server.xml that I needed to get failover working. Are you working through the steps in the ‘Testing HTTP session management and failover’ section? When you say, ‘do you have more detail of that session’ are you referring to the javax.servlet.http.HttpSession mentioned in step 3, or something else?

Join The Discussion

Your email address will not be published. Required fields are marked *