{"id":432,"date":"2012-06-21T13:04:37","date_gmt":"2012-06-21T05:04:37","guid":{"rendered":"http:\/\/rmohan.com\/?p=432"},"modified":"2012-06-21T13:04:37","modified_gmt":"2012-06-21T05:04:37","slug":"apache-server-load-balancing-for-multiple-virtual-hosts-tomcat","status":"publish","type":"post","link":"https:\/\/mohan.sg\/?p=432","title":{"rendered":"Apache Server Load Balancing for Multiple Virtual Hosts Tomcat"},"content":{"rendered":"<p><strong>Apache Server Load Balancing for Multiple Virtual Hosts Tomcat<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>apache<br \/>\nvi \/etc\/http\/conf\/httpd.conf<\/p>\n<p>NameVirtualHost *:443<br \/>\nNameVirtualHost *:80<\/p>\n<p>&lt;VirtualHost *:80&gt;<br \/>\nServerName server1.rmohan.com<br \/>\nRedirect permanent \/ https:\/\/server1.rmohan.com\/<br \/>\n&lt;\/VirtualHost&gt;<\/p>\n<p>&lt;VirtualHost *:443&gt;<br \/>\nServerName server1.rmohan.com<br \/>\nSSLProxyEngine On<br \/>\nKeepAlive On<\/p>\n<p>&lt;Proxy balancer:\/\/Cluster&gt;<br \/>\nBalancerMember ajp:\/\/localhost:18009 disablereuse=On route=jvm1<br \/>\nBalancerMember ajp:\/\/localhost:28009 disablereuse=On route=jvm2<br \/>\n&lt;\/Proxy&gt;<\/p>\n<p>ProxyPass \/ balancer:\/\/Cluster\/ stickysession=JSESSIONID<br \/>\n&lt;\/VirtualHost&gt;<\/p>\n<p>&lt;VirtualHost *:80&gt;<br \/>\nServerName server2.rmohan.comm<br \/>\nRedirect permanent \/ https:\/\/server2.rrmohan.com\/<br \/>\n&lt;\/VirtualHost&gt;<\/p>\n<p>&lt;VirtualHost *:443&gt;<br \/>\nServerName server2.rmohan.com<br \/>\nSSLProxyEngine On<br \/>\nKeepAlive On<\/p>\n<p>&lt;Proxy balancer:\/\/Cluster&gt;<br \/>\nBalancerMember ajp:\/\/localhost:18009 disablereuse=On route=jvm1<br \/>\nBalancerMember ajp:\/\/localhost:28009 disablereuse=On route=jvm2<br \/>\n&lt;\/Proxy&gt;<\/p>\n<p>ProxyPass \/ balancer:\/\/Cluster\/ stickysession=JSESSIONID<br \/>\n&lt;\/VirtualHost&gt; [\/apache]<\/p>\n<p>And these VirtualHost blocks go on for as many servers as needed. I know it doesn\u2019t look pretty and in fact it\u2019s incorrect since the VirtualHost for SSL connection shouldn\u2019t have a ServerName directive. Not unless you\u2019re using the SNI with mod_gnutls or some specific combination of server and browser like Apache 2.2.12 or later and Mozilla Firefox 2.0 or later. In my environment it did work and so this was used for a while. The first improvement on the configuration that I attempted looked like this:<\/p>\n<p>[apache] NameVirtualHost *:80<\/p>\n<p>&lt;VirtualHost *:80&gt;<br \/>\nServerName server1.rmohan.com<br \/>\nRedirect permanent \/ https:\/\/server1.rmohan.com\/<br \/>\n&lt;\/VirtualHost&gt;<\/p>\n<p>&lt;VirtualHost *:80&gt;<br \/>\nServerName server2.domain.com<br \/>\nRedirect permanent \/ https:\/\/server2.rmohan.com\/<br \/>\n&lt;\/VirtualHost&gt;<\/p>\n<p>KeepAlive On<\/p>\n<p>&lt;Proxy balancer:\/\/wwwCluster&gt;<br \/>\nBalancerMember ajp:\/\/localhost:18009 route=jvm1<br \/>\nBalancerMember ajp:\/\/localhost:28009 route=jvm2<br \/>\n&lt;\/Proxy&gt;<\/p>\n<p>NameVirtualHost *:443<\/p>\n<p>&lt;VirtualHost *:443&gt;<br \/>\nProxyPass \/ balancer:\/\/Cluster\/ stickysession=JSESSIONID<br \/>\n&lt;\/VirtualHost&gt;<\/p>\n<p>[\/apache]<\/p>\n<p>At first it semed ok, but then I noticed that it produced a strange side-effect.<br \/>\nThe balancer worked, but the redirect from HTTP to HTTPS didn\u2019t. Therefore this configuration was not acceptable.<br \/>\nThinking about it some more I realized that I don\u2019t actually need to know the name of the host when redirecting it to my backend server because in my case it will process the Host header and provide the appropriate result. Googling for the redirection to HTTPS alternative I found this page which suggests that Apache\u2019s RewriteEngine could be used to achieve this result. So here\u2019s my final configuration that does the redirect to HTTPS, load balancer\u2019s sticky sessions are functioning properly and everything gets redirected to one of the backend servers chosen by the balancer regardless of the hostname that was used to access it. In other words it works the way I need it to.<\/p>\n<p>[apache]<\/p>\n<p>NameVirtualHost *:80<\/p>\n<p>&lt;VirtualHost *:80&gt;<br \/>\nRewriteEngine On<br \/>\nRewriteCond %{HTTPS} off<br \/>\nRewriteRule (.*) https:\/\/%{HTTP_HOST}%{REQUEST_URI}<br \/>\n&lt;\/VirtualHost&gt;<\/p>\n<p>ProxyPass \/ balancer:\/\/Cluster\/ stickysession=JSESSIONID<\/p>\n<p>&lt;Proxy balancer:\/\/Cluster&gt;<br \/>\nBalancerMember ajp:\/\/localhost:18009 route=jvm1<br \/>\nBalancerMember ajp:\/\/localhost:28009 route=jvm2<br \/>\n&lt;\/Proxy&gt;<\/p>\n<p>NameVirtualHost *:443<\/p>\n<p>&lt;VirtualHost *:443&gt;<br \/>\nSSLEngine on<br \/>\n&lt;\/VirtualHost&gt;<\/p>\n<p>[\/apache]<\/p>\n<p>And if you\u2019re using Apache server with PHP rather than JAVA I found this article to be a good read on setting up load balancer with sticky sessions for PHP.<\/p>\n<p>ProxyPass \/ balancer:\/\/cluster\/ lbmethod=bytraffic<\/p>\n<p>BalancerMember http:\/\/server1.rmohan.com:8080\/<br \/>\nBalancerMember http:\/\/server2.rmohan.com:8080\/<br \/>\nBalancerMember http:\/\/server3.rmohan.com:8080\/<\/p>\n<p>ProxyPassReverse \/ http:\/\/www.rmohan.com\/<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Apache Server Load Balancing for Multiple Virtual Hosts Tomcat<\/p>\n<p>&nbsp;<\/p>\n<p>apache vi \/etc\/http\/conf\/httpd.conf<\/p>\n<p>NameVirtualHost *:443 NameVirtualHost *:80<\/p>\n<p>&lt;VirtualHost *:80&gt; ServerName server1.rmohan.com Redirect permanent \/ https:\/\/server1.rmohan.com\/ &lt;\/VirtualHost&gt;<\/p>\n<p>&lt;VirtualHost *:443&gt; ServerName server1.rmohan.com SSLProxyEngine On KeepAlive On<\/p>\n<p>&lt;Proxy balancer:\/\/Cluster&gt; BalancerMember ajp:\/\/localhost:18009 disablereuse=On route=jvm1 BalancerMember ajp:\/\/localhost:28009 disablereuse=On route=jvm2 &lt;\/Proxy&gt;<\/p>\n<p>ProxyPass \/ balancer:\/\/Cluster\/ stickysession=JSESSIONID &lt;\/VirtualHost&gt;<\/p>\n<p>&lt;VirtualHost *:80&gt; ServerName server2.rmohan.comm Redirect [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[],"_links":{"self":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/432"}],"collection":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=432"}],"version-history":[{"count":1,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/432\/revisions"}],"predecessor-version":[{"id":433,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/432\/revisions\/433"}],"wp:attachment":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=432"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=432"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=432"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}