How to maintain session in tomcat with load balance?
We alredy seen that how to implement load balance with tomcat.
In this process there is a problem that tomcat cant maintain session during load balance.
Session is a key value pair. Session will be created if there is no session id in request header.
Once session is created it will send with response and the session value will be set in client browser.
Http is a stateless protocal so server cant find the session directly. So it will read the session id from request and the session id will be checked with group of session id. If id matches the same session id will be maintained else new session id will be created.
So for ever request new session id will be created. This problem will be resolved if the preceding request are dispatched to same tomcat or all tomcat’s should have same session id. Here request will be dispatched to different tomcat instance in round robin method.
There is two way to resolve this session issue. Those are Session Affinity/Sticky Session and Session Replication.
Session Affinity/Sticky Session:
if you have many instances of tomcat (eg: tomcat1 & tomcat2) and you start session on tomcat1, the subsequent requests will be forwarded to tomcat1 as long as tomcat1 running an up (you never reach tomcat2). It means that if tomcat1 now is down, then your subsequent request will be forwarded to tomcat2, with a different session (a new session created at tomcat1 for you). This is not very good because if your application responding on tomcat1, then moved to tomcat2, session data will be lost. Usually Sticky session is achieved in simple load balancing of Apache server in front of tomcat servers.
Session replication, means you will have the same session id regardless of your first or subsequent requests served by tomcat1 or tomcat2. It means that you session will be duplicated on both tomcat1 and tomcat2. Sometimes you served by tomcat1, sometimes you served tomcat2, although none of them is down. Usually this is achieved when tomcat cluster is created.
How to implement Session Affinity?
Session Affinity means redirecting all the reequests to the same tomcte.
Tomcat configuration file (conf/server.xml) contains a tag called has a property jvmRoute.
Session Affinity will be configured by assigning the tomcat instance name to this property.
So each and every session id will contain its tomcat instance name at end. So load balancer will easily find that to which tomcat instance the requests should be dispatched.
Sample Engine Tag:-
Note : – The above lines should be added in all tomcat’s context.xml file.
org.apache.catalina.session.PersistentManager is the class for Persistant Manager.
org.apache.catalina.session.FileStore is the class reperacents type of persistant manager.
directory – reperacentsfile path in the local machine.
Lets test the Manager :-
Create a jsp file to test which tomcat receives request.
# Create file Test/sestest.jsp
Note: create for each instance and change the tomcat instance name above
<%@page language="java" %>
Session serviced by tomcat1
||<%= session.getId() %>
||<%= session.getCreationTime() %>
Open a browser to http:///examples/jsp/sesstest.jsp
Click a number of times, you should stay with the same instance (sticky session working)
Shutdown an instance
- Retest using the browser and hopefully it should pickup the other instance but have the same session ID
JDBC Store :-
Similarly in JDBC store session details will be stored in database. Here i am going to use mysql database. You can use any RDBMS database.
Make sure that table is already created in database to store session.
Samle Query to create Table :-
create table tomcat_sessions (
session_id varchar(100) not null primay key,
valid_session char(1) not null,
max_inactive int not null,
last_access bigint not null,
Sample Context.xml configuration :-
Lets test the Manager :-
Do the previous steps to test jdbc store.
3. Delta Manager :-
In Delta Manager once session is created for session for any tomcat instance, this session will be copied to all tomcat instances. So that all tomcats will have same session id. If current tomcat instant goes off , any off the tomcat will receive’s the furthor request. Since all tomcat have same session, data will not be lost and no more session will be created.
But its not a good approch for large size cluster. Because every time it copies the session to all the tomcat instances. So it will take more time.
To setup Deta Manager we has to follow these steps :-
1. Enable the Web Application as distributable
We need to make the our web application distribuable. its simple add tag in web.xml file. In according to servlet specification tag in web.xml mention that any container to consider this application can work in distributed environment
Add any of this tag in web.xml file.
2. Add Entries in conf/server.xml filefor all instances.
we can add this tag in either inside the tag or tag.
Note: the port in bold is the one you need to change for each instance
here most of the code are boiler plate code. just copy and paste. if we need we can customize. for example we can change the multicat address and port number.
hereManager tag define the delta manager. Delta manager meansreplicateto all instances.
Tomcat Clustering use the Apache Tribes communication framework. This group commnicationframeworkis responsible for dynamicmembership(usingmulticast) , send andreceivethe session delta information usinguni-cast(normal TCP connection).
This is Membership definition. here address is multicast address. we can pick any address from Class D address range (22.214.171.124 to 126.96.36.199)and any port number.
Each and every tomcat send the heart beat signal to multicast address inperiodic(frequency) interval. all other tomcat whose joined the multicast address they canreceivethese signals and add the membership to the cluster. if heat beat signal is notrevivesomeparticularinterval(dropTime) from any one of the tomcat, then we need to consider that tomcat is failed.
All tomcat instances which is part of the clustering, should have same multicast address and port number.
here sender use the PooledParallelSender have pooled connections to use the send the session informationconcurrently. so its speedup the session replication process.
here we define which port Receiver can bind and used for receiving the session replicate information. here two properties are important. address and port. here address is ur system IP address and port is any unused port. hereaddress=”auto” its automatically pick the system IP address.
we have some interceptor
TcpFailureDetector-Its ensure that instance are dead. In some case multicast messages are delayed, all tomcat instances are think about that tomcat is dead. but this interceptor to make tcp unicast to failed tomcat and ensure that instances is actually failed or not.
another important listener is JvmRouteSessionIDBinderListener.
JvmRouteSessionIDBinderListener take care to change the client session id to tomcat2 when failure is occurred so load balancer redirect to tomcat2 without confusing.
3. Enable Multicast routing: –
In Linux Environment most of the system kernel is capable to process the multicast address. but we need to add route entry in kernel routing table.
sudo route add -net 188.8.131.52 netmask 240.0.0.0 dev eth0
here eth0 is myEthernetinterface. so changeaccordingto your interface
Inmulticastaddress is belong to Class D address Range(184.108.40.206 to 220.127.116.11). so we inform to kernel if any oneaccessthese address then it goes through eth0 interface.
make sure that the element is commented out.
4.Backup Manager :-
Backup Manager is replicate the copy of session data to exactly one other tomcat instances. This big difference between both managers. here which tomcat creates that is primary copy of the session. and another tomcat whose hold the replicate session is backup copy. If any one of the tomcat is down.
To setup a persistent session manager you must comment out the element in each instance, this disables the In-Memory replication mechanism, then add a context.xml file to each instance with the below.
The setup process of backup manager is same as Delta manager. except we need to mention the Manager as BacupManager (org.apache.catalina.ha.session.DeltaManager) inside element.