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.
Good thing is also that you can serve your static content like images, javascript and css files from apache web server(apache web server is somewhat faster in serving static content than tomcat), and let the tomcat application server to handle the real applcation processing.
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.
Tomcat A
<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:
jsessionid=4C87288CB0CDB71D0DCA412E178A1480.tomcatB
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.
- proxy
- proxy_balancer
- proxy_ajp
a2enmod proxy
a2enmod proxy_balancer
a2enmod proxy_ajp
Restart apache and tomcat servers and you'll have load balancing set up with minimal configuration.
This is such an elegant solutionm My firm is delighted to find, implement and cut costs
ReplyDeletewhere the alternative was a specific router
with additional IT involvement.
- Juraj
am getting this error when try to do in Ubuntu
ReplyDeleteWed Sep 26 12:33:58 2012] [error] ajp_check_msg_header() got bad signature 4854
[Wed Sep 26 12:33:58 2012] [error] ajp_ilink_receive() received bad header
[Wed Sep 26 12:33:58 2012] [error] ajp_read_header: ajp_ilink_receive failed
[Wed Sep 26 12:33:58 2012] [error] (120007)APR does not understand this error code: proxy: read response failed from (null) (192.168.1.108)
[Wed Sep 26 12:33:58 2012] [error] ajp_check_msg_header() got bad signature 4854
[Wed Sep 26 12:33:58 2012] [error] ajp_ilink_receive() received bad header
[Wed Sep 26 12:33:58 2012] [error] ajp_read_header: ajp_ilink_receive failed
[Wed Sep 26 12:33:58 2012] [error] (120007)APR does not understand this error code: proxy: read response failed from (null) (192.168.1.121)
Great Article and Useful Article.
ReplyDeleteOnline Java Training
Online Java Training from India
Online Java Training
Online Java Training From India
Java Training Institutes in Chennai
Java Training in Chennai
Very interesting blog. Many blogs I see these days do not really provide anything that attracts others, but believe me the way you interact is literally awesome. You can also check my articles as well.
ReplyDeleteAdmissiongyan, the best German overseas education consultant in Bangalore, since 2012 for study abroad incl. Germany, France, Italy, Sweden, Ireland, NL, or UK.
best overseas consultants in bangalore
ms in mechanical engineering in germany
Masters in Mechanical Engineering in Germany
free education in germany
mba in germany
ms in germany for indian students
study ms in germany
study in germany consultants