In this example I use mod_proxy and mod_proxy_ajp which is built into Apache web server from versions 2.2 and up. AJP stands for Apache Jserv Protocol wich is binary packet-oriented protocol and apache web server communicates with tomcat over TCP connections, maintains persistent connections and reuses a connection for multiple request/response cycles.
By having apache web server in front of multiple tomcat application servers you can achive to handle more concurent requests and also have some sort of failover in case one of the nodes breaks down.
For example purposes I'll install two tomcat application servers and apache web server on the same physical machine but in the real world that would probably be separate machines.
1. First, I install two separate instances of tomcat application servers(download and unzip). You will need to change the ports in server.xml config file to avoid port conflicts.
<Server port="8005" shutdown="SHUTDOWN"> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcatA">Tomcat B
<Server port="8006" shutdown="SHUTDOWN"> <Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8010" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcatB">Last line has attribute jvmRoute and is concerned to session stickyness explained further bellow.
For test purposes deploy some dummy application under /balance context.
Try to start both instances to see if everything is ok.
2. Install apache web server. I am using Ubuntu:
sudo apt-get install apache2
3. Edit virtual host configuration file.
On Ubuntu, I edit /etc/apache2/sites-enabled/000-default.
<Proxy balancer://tomcatservers> BalancerMember ajp://localhost:8009 route=tomcatA loadfactor=1 BalancerMember ajp://localhost:8010 route=tomcatB loadfactor=2 </Proxy> <Location /balancetest> Allow From All ProxyPass balancer://tomcatservers/balance stickysession=JSESSIONID nofailover=off </Location>We defined load balancer for two nodes (tomcatA and tomcatB) and proxy pass for load balancer. In proxy pass we defined that all request going to /balancetest are proxied to tomcat application server to /balance context. Entering url http://localhost/balancetest will display jsp page or whatever either from tomcatA or tomcatB depending on load balancer.
The load balancer supports session stickyness wich means that all request for some session identifier are proxied to same tomcat web application instance in cluster that first served the client. To track this information tomcat adds jvmRoute information that uniquely identifies tomcat application server in the cluster.
So, jsessionid cookie would look something like this:
Apache web server will compare route value defined in balancer with cookie value to proxy request to tomcat instance that maintains corresponding session.
It is important that jvmRoute attribute in server.xml config file and route attribute in virtual host config file are identical for some tomcat instance.
Load factor attribute allows to distribute load between nodes. If load factors are equal, load is equally distributed. In our case tomcatB will recieve two times more requests than tomcatA.
4. And for this to work following modules must be enabled on apache server.
Restart apache and tomcat servers and you'll have load balancing set up with minimal configuration.