Run a Tomcat Cluster with Redis session persistence on Oracle Cloud
This blog demonstrates a Clustered Tomcat application on Oracle Application Container Cloud
- Redis is used as the (HTTP) session store (with Spring Session)
- Deploy it on Oracle Application Container Cloud using CI/CD feature in Oracle Developer Cloud
We will focus on HTTP Session management (of the app on Tomcat cluster) and its implementation aspects
- Persistence — using a Redis backed store which can be configured to flush (persist) to disk
- Stateless — non-sticky session management
- High Availability— failure of a (application) node does not affect the session data (hence the user) as long as we have at least one node alive
- Scalability — the application can scale (horizontally or vertically) without affecting user/session data
HTTP Session persistence
Tomcat
It has support (out of the box implementations) for in-memory and persistent HTTP session stores
- In-memory: Configure Tomcat to use the
org.apache.catalina.ha.tcp.SimpleTcpCluster
implementation - Persistent: Use a file or JDBC store to persist HTTP session info
Tomcat HTTP session store support in Oracle Application Container Cloud
Both in-memory and persistent modes of Tomcat are supported
- In-memory: This is made possible due to multicast support in Oracle Application Container cloud. Check out this tutorial for details
- Persistent store: You can use Oracle Database Cloud (or any other RDBMS which can be accessed using JDBC) as the persistent HTTP session store. There is a tutorial for this too !
Solution details
To implement persistent HTTP Session store for clustered Tomcat app, we have a few options at our disposal
- Extend Tomcat specific interfaces/classes (e.g
org.apache.catalina.session.ManagerBase
) or use an existing plugin e.g. Redisson support for Tomcat
2. Build/use a more generic solution — ideally runtime agnostic
Spring Session & Redis combo on Oracle Application Container Cloud
This blog demonstrates option #2. It uses a Redis based implementation of Spring Session
- Based on the
Servlet
specification — hence container neutral i.e. it can work for anyServlet
compliant container (other than Tomcat) - A custom
Servlet Filter
implementation which is responsible for enforcing usage of Spring SessionHTTPSession
implementation

Project is available here — in terms of business logic, it just consists of
- a simple HTTP
Servlet
- (Spring) configuration class to enable Redis
- Another utility class to ensure that the Servlet filter kicks in for every HTTP request
Application packaging
We follow the bring-your-own-runtime
mantra. The code repository has the following structure
- the source code (
src
directory) - Tomcat 8.x (
tom-accs
directory) - bootstrap script (
start.sh
)
#!/bin/bash
if [ -z “$PORT” ];
then
PORT=”8080"
fi
echo “PORT set to $PORT”
# Update server.xml with env vars
sed “s/__PORT__/${PORT}/g” server.template.xml > tom-accs/conf/server.xml
sh tom-accs/bin/catalina.sh run
In addition to the Tomcat startup script invocation, the start.sh script ensures that the
server.xml
with correct environment variable ($PORT in our case) is generated during application start up
- templated version of (Tomcat)
server.xml
(server.xml.template
) manifest.json
— the mandatory deployment descriptor
{
“runtime”:{“majorVersion”:”8"},
“command”:”sh ./start.sh”,
“notes”:”Tomcat on ACCCS with Redis Session Sharing”
}
Setup
Oracle Developer Cloud
Let’s configure Oracle Developer Cloud for the Continuous Build as well as Deployment process. You can refer to previous blogs for the same (some of the details specific to this example will be highlighted here)
References
- Bootstrap the application in Oracle Developer Cloud — Project & code repository creation
- Continuous integration setup — Configure build job
- Deployment setup — Continuous Deployment (CD) to Application Container Cloud
Build Job configuration
The build job for this application is generic in nature, but it has some application specific nuances (Build Steps) which will be highlighted in this section
Build Step #1 — Invoke the Maven build to produce the required artifact i.e. a WAR file in this case

Build Step #2 — copy the WAR file into the Tomcat webapps
directory and zip everything up (for the final cloud ready artifact)

The end result is a zip file which consists of the binary (WAR file) as well the runtime (Tomcat installation) where its going to execute
Provide Oracle Application Container Cloud (configuration) descriptor
We provide the application (sizing) details as well as Redis co-ordinates (host and port)

Deployment confirmation in Oracle Developer Cloud

Post-deployment status in Application Container Cloud


Test the application
Let’s test the application using cURL
and the redis-cli
tool
First time access
We will just invoke a HTTP GET
on our application URL
curl https://accs-tomcat-redis-<mydomain>.apaas.em2.oraclecloud.com/accs-tomcat-redis-spring/
- This will create a new HTTP session — highlighted in green
- Notice the ACCS instance (in green) which processed the request

Add session data & access the application
We will now use the Session ID received above by passing it along with a request which will add some session data — this is a HTTP POST
with parameters name
and val
which are stored in the HTTP session
curl -X POST -H “Cookie: SESSION=09217ecb-6b90–41bf-952f-b41b65070fa2” “https://accs-tomcat-redis-<mydomain>.apaas.em2.oraclecloud.com/accs-tomcat-redis-spring/?name=k1&val=v1"
To access the application, we execute HTTP GET
operation as in execute in step #1 (along with Session ID in the header)

Notice that we get back our session data (highlighted in red) which we had added in the previous step
Let’s see our session state in Redis using the redis-cli
. Execute aHGETALL
command to a Redis Hash
(data structure) where the session is stored (the hash name is in a pre-determined format based on the Session ID)
<redis-host>:6379> hgetall spring:session:sessions:09217ecb-6b90–41bf-952f-b41b65070fa2

Notice the Session data (key-value pair k1, v1) which we added in the previous step — it is highlighted in green
Add some more data, access the application & check Redis
Lets rinse and repeat…
curl -X POST -H “Cookie: SESSION=09217ecb-6b90–41bf-952f-b41b65070fa2” “https://accs-tomcat-redis-<my-domain>.apaas.em2.oraclecloud.com/accs-tomcat-redis-spring/?name=abhishek&val=gupta"
In Redis, you will see the newly added session data (highlighted in red)

You (obviously) see the same session data reflected in the application as well — notice the Oracle Application Container Cloud instance names highlighted in red
- subsequent requests are catered by different instances, but
- the session data is consistent since its retrieved from the persistent store (Redis)

Scale in & access the application again
Lets reduce the number of instances to 1 — please refer to the documentation for details

- Session data will be consistent
- Request will be served by the same Application Container Cloud instance (we just have one now)
Add session data (again)
curl -X POST -H “Cookie: SESSION=09217ecb-6b90–41bf-952f-b41b65070fa2” “https://accs-tomcat-redis-<my-domain>.apaas.em2.oraclecloud.com/accs-tomcat-redis-spring/?name=accs&val=rocks"
Check Redis — you will see the data getting persisted there
Scale out, access the application & check Redis
Lets go back to our 2-instance topology — refer documentation for how to scale out. You will see that
- On repetitive access, different Application Container Cloud instances will serve the request
- the application Session data returned will be same as above
- Redis will also retain the same state
Test the CI/CD flow
Make some code changes and push them to the Developer Cloud service Git repo. This should
- Automatically trigger the build, which once successful will
- Automatically trigger the deployment process, and
- Redeploy the new application version to Application Container Cloud
Recap
All is well that ends well! We were able to configure and implement a stateless, scalable, highly available and persistent HTTP Session management strategy using Redis and Spring Session for a Tomcat web app on Oracle Application Container Cloud
Don’t forget to…
- check out the tutorials for Oracle Application Container Cloud — there is something for every runtime !
- other blogs on Application Container Cloud
The views expressed in this post are my own and do not necessarily reflect the views of Oracle.