Today, a user posted a question on serverfault.com, and I jumped in with my thoughts;
Currently we have a single tomcat 7 running as our application server, but with users increasing we were thinking of the following…
We want to cluster the two tomcats, is there any disadvantage?
Would hardware loadbalancers before tomcat not be enough, what’s the advantage of putting apache servers?
We want to offload SSL at Load-Balancer, an impacts or issues we see in this approach?
1) We want to cluster the two tomcats, is there any dis-advantage.
The main disadvantage is that it is more complex to manage a cluster of services, with a lot of up front investment of time and requires more resources in your datacentre. You also have the added complexity of managing the sessions that are balanced, otherwise your client loses their login and cookies at each new request (see below for comment on that)
However you are trading that for increased capacity and resilience to failure. I would look at using something to manage the configuration of the tomcat instances, such as ansible or chef, or even pre-built docker containers for tomcat. It’s a lot of work initially, but pays off in buckets over the longer term.
2) Would hardware loadbalancers before tomcat not be enough, what’s the advantage of putting apache servers?
I have not used a hardware load balancer for a long time, I’ve mostly moved to AWS and cloud services, so I can’t speak of running your own hardware load balancer, However both apache and nginx are easy to configure as front end proxies to tomcat7. Previously I have used apache extensively in production, and there are lots of good tutorials that explain the nuances;
With apache you have the option of mod_proxy or mod_proxy_ajp. Generally mod_proxy with http is easier to setup, and ajp is supposed to be faster as it uses a binary format to communicate. (but I’ve not actually compared speed) Another reason for using mod_proxy_ajp is that it also sends through the SSL details to tomcat, so if you app uses SSL information for auth, but you have handed off the HTTPS at the front end, you will need mod_proxy_ajp.
An additional advantages of using apache as a front end, is that you get all the configurability such as logging and authentication as a bonus. So you can get the aggregated log of both tomcat servers in one place, rather than to go and get the logs files from each node. So you can use any log analysis tool that works with apache to produce stats for your app.
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_balancer modules/mod_proxy_balancer.so LoadModule proxy_http_module modules/mod_proxy_http.so <VirtualHost *:80> ServerName mydomain ServerAlias *.mydomain <Proxy balancer://mycluster> BalancerMember http://app1.example.com:8080 BalancerMember http://app1.example.com:8080 </Proxy> ProxyPass /test balancer://mycluster </VirtualHost>
or using mod_proxy_ajp
<VirtualHost *:80> ServerName mydomain ServerAlias *.mydomain <Proxy "balancer://cluster"> BalancerMember "ajp://app1.example.com:8009" loadfactor=1 BalancerMember "ajp://app2.example.com:8009" loadfactor=2 ProxySet lbmethod=bytraffic </Proxy> ProxyPass "/app" "balancer://cluster/app" </VirtualHost>
You also have to take account of maintaining sessions between back-ends. This depends on your application, but you usually start a session in the web app, and the load balancer uses that cookie to route the requests to the correct back end;
ProxyPass "/app" "balancer://cluster/app" stickysession=JSESSIONID
There are some details on how that works here;
3) We want to offload SSL at Load-Balancer, an impacts or issues we see in this approach?
I think this is the standard approach. It’s much easier to configure apache with certs than tomcat, and I understand that apache handles SSL much more efficiently than tomcat (not sure if thats still true in 2016…) and that this will result in increased performance.
I guess the main issue for the tomcat app is that it is behind https:// but it doesn’t know it. So you have to be careful how links are generated and to be sure that they are presented to the client correctly. Obviously if all links are relative to the server e.g.
<a href=/my/path/to/thing.html">Click</a> then it should work out ok.