Of all the bizarre things that are required to do on our day to day I had this one in the back burner for some time now. A while ago I was tasked to setup a few Apache Tomcat instances to serve a Java web application in the current infrastructure. Part of the challenge was to curb the poor performance given by the existing product being utilized in production to serve as a JEE container for their primary Java based web application. Tomcat by default usually results in a lighter install and is relatively easy to set up in most cases but in this particular infrastructure there were other considerations in the stack that impacted our approach to performance tuning. Apache provides a native library that should result in a performance increase across the board.
Per their description:
The Apache Tomcat Native Library is an optional component for use with Apache Tomcat that allows Tomcat to use certain native resources for performance, compatibility, etc.
Specifically, the Apache Tomcat Native Library gives Tomcat access to the Apache Portable Runtime (APR) library's network connection (socket) implementation and random-number generator. See the Apache Tomcat documentation for more information on how to configure Tomcat to use the APR connector.
- Features of the APR connector:
- Non-blocking I/O for Keep-Alive requests (between requests)
- Uses OpenSSL for TLS/SSL capabilities (if supported by linked APR library)
- FIPS 140-2 support for TLS/SSL (if supported by linked OpenSSL library)
On a Solaris installation using the SPARC architecture most of the packages you would be used to find readily available in binary have to be compiled from source. Most of us that dabble on Web Development seldom engage in the dark arts of Unix C++ and its tooling. Also, most Tomcat installs consist of a Linux stack where community maintained repositories contain precompiled binaries of whatever library we need for our deployments. What was supposed to be a routine performance tuning for Tomcat turned in to a journey of taming the intricacies of building Tomcat Native on Solaris SPARC. I hope this step by step provides a distilled way of compiling your own native tomcat while avoiding most pitfalls:
- Download and install Solaris Studio. You need Solaris' own C compiler binary. While you may be able to use gcc, my endeavor in that direction provided to be fruitless.
- Download the Apache Portable Runtime (APR) source and corresponding APR Utils source code
- On your shell, configure the following environment variables. Take note that the CFLAGS environment variable is being set to the SPARC 64bit arch. If you’re going to run Tomcat on a 32 bit JVM, you probably don’t want it set:
export CATALINA_HOME=/app/tomcat(or whatever your tomcat installation is located at)
export PATH=$PATH:/opt/solarisstudio12.4/bin/ && export CFLAGS="-m64 -xarch=native"
- If you haven’t already done so, configure a loopback interface for IPV6. APR will fail tests if it can't use an IPV6 interface during one of the tests:
ifconfig lo0 inet6 plumb && ifconfig lo0 inet6 ::1 up
- Change to the APR directory and run:
./configure make && make test && make install
- Let them run and when you finnish with make install you should have a compiled APR library in (typically) /usr/local/apr/
- Change to the APR Util directory where the source code was extracted and run:
./configure --with-apr=/usr/local/apr/( --with-apr parameter is where your recently compiled APR library was installed)
- Compile and install APR Utils
./configure && make && make test && make install
- Clear the CFLAGS environment variable if it was set before:
- Change to the tomcat native directory where you extracted the source. Execute the following:
./configure CC=cc --with-apr=/usr/local/apr/ --with-java-home=/app/jdk1.7.0/ --with-ssl=no --prefix=$CATALINA_HOME
You should have a newly minted tomcat native binary in your tomcat/lib directory. When you run tomcat the log will tell you if native APR was successfully loaded. Note that I didn’t enable SSL. There are 2 reasons for that. First, the post-heartbleed open SSL binary was not available, and we do SSL ofloading on our reverse proxy/load balancer so I don’t need the additional overhead. Make sure to replace the paths of the corresponding java home and $CATALINA_HOME parameters with the proper paths for java/tomcat.