Apache Tomcat ships with an optimized load balancing / reverse proxy protocol known as AJP or more formally as the Apache Tomcat Connector specification. This makes Tomcat a top choice among the many Java Servlet and JSP web app containers available. There was limited AJP support in Jetty (Eclipse Java Web Server), but this has been removed in the current Jetty 9.x rewrite. Jetty 9.0 stable was first released in March of 2013. Because of this, I recommend that multi-tier Java web app deployments consider the use of Apache Tomcat as the app container, and Apache Httpd with built-in mod_proxy_ajp as the load balancer web front end + ssl/tls layer (provides reverse proxy services using optimized AJP to your Tomcat instances).
In the past, Apache Httpd users were confused by the lack of support for mod_jk, an AJP module for httpd which usually needed to be compiled from source. Today we can forget mod_jk and use the distribution packaged and supported mod_proxy_ajp which provides the same capabilities as mod_jk without the headache of attempting to compile the mod_jk source into distribution-provided httpd software. Debian, Ubuntu, RHEL, and CentOS all provide mod_proxy_ajp packages with the essential security and bug-fix updates through apt and yum vendor-supported repositories. In order to convert from a plain HTTP-based reverse proxy configuration to the more tightly-integrated AJP, it’s as simple as changing the ProxyPass entries in your Apache Httpd configuration file(s). Here’s and example.
- Old HTTP-based reverse proxy configuration sample
ProxyPass /context http://servername:8760/context
ProxyPassReverse /context http://servername:8760/context
- New AJP-based reverse proxy configuration sample
ProxyPass /context ajp://servername:8761/context
ProxyPassReverse /context ajp://servername:8761/context
I understand there is an ongoing (eternal?) religious debate regarding the relative merits and disadvantages of HTTP vs AJP reverse proxy usage for Java web apps. There are two reasons I consider AJP to be a better option than plain HTTP reverse proxy solutions:
- When AJP is used, the Java web app receives the original headers from the front end web server as if the request was directly received from the original client. This is a HUGE ADVANTAGE! There is a little overhead required to make a reverse proxy request between front end and back-end while also passing along the original headers, but it IS TOTALLY WORTH IT because your app will be able to process the real request without elaborate workarounds attempting to configure the app to respond with front-end URL’s while ignoring the confusion introduced by reverse proxy HTTP request headers. If you use HTTP reverse proxy with Java web apps, you know what I’m talking about!
- AJP is proxy-aware, by this I mean that the front-end web server (load balancer / reverse proxy) and the back-end app server are both aware and actively participating in a proxy (and possibly load balancing) relationship. This enables the passing of original headers, direct monitoring of app server status, advanced native load balancing capabilities (monitored add or remove of app server nodes to the balanced set, true load-based connection assignment at front-end). These capabilities add a little overhead to the AJP protocol, but the added native load balancing and reverse proxy capabilities are definitely worth it in my opinion.
Not everyone will agree with this opinion. AJP is not an Internet Standard but rather an Apache Tomcat protocol specification that enhances the interaction between a front-end web server and any back-end Java app server(s). Even so, I feel that Java web app deployment teams and developers should Strongly consider AJP as a reverse proxy and load balancing solution of choice as long as Tomcat and Apache Httpd or other Web and App Server solutions are supporting this valuable multi-tier enhancement for better web app deployment capabilities.