Thursday, July 30, 2009

Tips for Using Tomcat in Production

  1. If you're running on a 1.5+ JVM, add the following to your JAVA_OPTS in (or catalina.bat for Windows):

    1. -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/j2ee/heapdumps

    Then use a tool such as YourKit to analyze the heapdump file.

  2. Straight from the Tomcat documentation on Jasper 2...

    When using Jasper 2 in a production Tomcat server you should consider making the following changes from the default configuration.
    development - To disable on access checks for JSP pages compilation set this to false.
    genStringAsCharArray - To generate slightly more efficient char arrays, set this to true.
    modificationTestInterval - If development has to be set to true for any reason (such as dynamic generation of JSPs), setting this to a high value will improve performance a lot.
    trimSpaces - To remove useless bytes from the response, set this to true.

  3. Use Tomcat's clustering/session replication capability to minimize application user impact during maintenance periods.
  4. Implement custom error pages to hide raw exception messages. To do this, simply add something like the following to your web.xml:

    1. <error-page>
    2.    <error-code>404</error-code>
    3.    <location>/error/404.html</location>
    4. </error-page>

  5. Eliminate System.out and System.err statements from application code and use a logging toolkit such as Log4J for application logging.
  6. Leverage Tomcat's shared library directory. If you're loading several applications with several of the same library dependencies, consider moving them from the applications' WEB-INF/lib directory to Tomcat's shared library {catalina.home}/shared/lib. This will reduce the memory used by each application and result in smaller WAR files.

  7. Tweak memory parameters. Most of the time you will want to make a change to the default settings. The best advice here is to create a development environment that matches your production environment and load test the application. While you do this you can also use a profiler to identify bottlenecks, etc.
  8. Remove unnecessary applications.
  9. Secure the Manager application. By default there are no users with the manager role. To make use of the manager webapp you need to add a new role and user into the CATALINA_HOME/conf/tomcat-users.xml file.

    1. <role rolename="manager">
    2.    <user username="darren" password="ReallyComplexPassword" roles="manager"></user>
    3. </role>

    Use a valve to filter by IP or hostname to only allow a subset of machines to connect (i.e. LAN machines). This can be configured at the Engine, Host, or Context level in the conf/server.xml by adding something like the following:

    1. <!-- allow only LAN IPs to connect to the manager webapp -->
    2. <!-- contrary to the current Tomcat 5.5 documation the value for 'allow' is not a regular expression -->
    3. <!-- future versions may have to be specified as 192.168.1.* -->
    4. <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="192.168.1.*"></Valve>

  10. Strip down server.xml by removing comments to make it easier to read and remove connectors that you don't need. An easy way to do this is the following: Rename CATALINA_HOME/conf/server.xml to CATALINA_HOME/conf/server-original.xml and rename CATALINA_HOME/conf/server-minimal.xml to CATALINA_HOME/conf/server.xml. The minimal configuration provides the same basic configuration, but without the nested comments is much easier to maintain and understand. Do not delete the original file as the comments make it useful for reference if you ever need to make changes. Unless you are using Tomcat with the Apache server, comment out this line in CATALINA_HOME/conf/server.xml:
    <Connector port="8009" enableLookups="false" redirectPort="8443" protocol="AJP/1.3">

  11. Split your Tomcat installation for added flexibility when it comes time to upgrade Tomcat. See the "Advanced Configuration - Multiple Tomcat Instances" section in the RUNNING.txt file of the Tomcat distribution.
  12. Precompile JSPs (at build time).
  13. Secure directory listings. In CATALINA_HOME/conf/web.xml:

    1. <servlet>
    2.    <servlet-name>default</servlet-name>
    3.    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>   
    4.    <init-param>
    5.       <param-name>debug</param-name>
    6.       <param-value>0</param-value>
    7.    </init-param>
    8.    <init-param>
    9.       <param-name>listings</param-name>
    10.       <param-value>false</param-value>  <!-- make sure this is false -->
    11.    </init-param>
    12.    <load-on-startup>1</load-on-startup>
    13. </servlet>

  14. If you have multi-core CPUs or more than one CPUs on your server, it might be beneficial to increase the thread pool beyond the default 250. On the other hand, if you have a slow server, decreasing the thread pool will decrease the overhead on the server.
  15. Monitor application applications via Tomcat MBeans. This article provides some great insight on how to do this.
  16. Consider JDK 1.5 or even better JDK 1.6 to take advantage of performance improvements.

  17. Use the -server JVM option. This enables the server JVM, which JIT compiles bytecode much earlier, and with stronger optimizations. Startup and first calls will be slower due to JIT compilation taking more time, but subsequent ones will be faster.
  18. Use GZIP compression. Look for the service connector you wish to configure for compression and add two attributes, compression and compressableMimeType. For example:
    1. <Connector>
    2.    port="80"
    3.    maxHttpHeaderSize="8192"
    4.    URIEncoding="UTF-8"
    5.    maxThreads="150"
    6.    minSpareThreads="25"
    7.    maxSpareThreads="75"
    8.    enableLookups="false"
    9.    redirectPort="8443"
    10.    acceptCount="100"
    11.    connectionTimeout="20000"
    12.    disableUploadTimeout="true"
    13.    compression="on"
    14.    compressableMimeType="text/html,text/xml,text/plain,application/xml">
    15. </Connector>

    For more information, read the Tomcat HTTP Connector documentation.

  19. The default Tomcat configuration provides good protection for most requirements, but does not prevent a malicious application from compromising the security of other applications running in the same instance. To prevent this sort of attack, Tomcat can be run with a Security Manager enabled which strictly controls access to server resources. Tomcat documentation has a good section on enabling the Security Manager.


  1. Great batch of tips, Manoj. Thanks a lot!

  2. This was so amazing! Most useful blog post that I have ever read! Thanks so much for posting a step by step!
    website design