Make Tomcat Production Ready

I recently attending a training for Tomcat Performance and it was something really wonderful. The instructor, Ritesh Tyagi, gave insights to a lot of things that a developer should keep into mind while coding.

At the very end of the session, he gave us things that one should look upon to make Tomcat ready for Production usage.

  1. Increase the Heap Size - This parameter you can decide based on how heavy is your application. You can configure this value in setenv.sh in the bin/ directory of your tomcat installation. Also, make sure these values are same so that the JVM does not have to spend time procesing for shrinking and growing of the Heap Size. Check more details here.

    export CATALINA_OPTS="-Xms512M -Xmx1024M"



  2. Use multiple Concurrent-Mark-Sweep-GC - If your application is very heavy and you occasionally face Out of Memory error, try setting the -XX:+UseConcMarkSweepGC option. This enables to run multiple (default 2) Concurrent Mark Sweep GC so that your Tenured Space gets cleaned up more often.

    A word of caution before using this option: Use this only as a temporary fix. If you application is running out of memory very soon, you need to do a memory analysis of your application to find the memory leaks. Read the Official Document for GC Tuning here.



  3. Dump GC Details - Another configuration which needs to be set in setenv.sh. Taking the heap dump and gc dump in a file when out of memory occurs, will give you the snapshot of the JVM memory at the time of error. You can analyze more on the snapshot to locate the actual root cause. Enable this feature as:

    -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -verbose:gc -Xloggc:/tmp/gc.log



  4. Increasing the No. of Worker Threads - By default, Tomcat comes bundled with default configuration of 200 worker threads. These worker threads correspond to No. of request which Tomcat can serve at a point of time. If your application is going to serve a lot more clients than 200, you need to change it. This is the attribute maxThreads for your Connector tag in server.xml inside conf/ directory. Refer to the full documentation of Connector attribute list here.



  5. Keep the Memory Limits to be Same - As mentioned in 1st point, best practice is to keep the minimum sizes and maximum sizes of the memory specifications to be same. This allows to remove the burden of JVM to monitor shrinking and growing of Heap. Fixes size will allocate the Heap Size initially and JVM is out of picture.



  6. Memory Parameters for YoungGen Space, Survivor Space and PermGen Space - Read the full specification for the below parameters here and here.

    -XX:NewRatio=3 -XX:NewSize=32m -XX:MaxNewSize=32m -XX:SurvivorRatio=6 -XX:MaxPermSize=64m



  7. Disable Console Logging - By default, the tomcat logs are output to console as well as log files inside log/ directory. On Production environments, you would ideally require only file logging and there is no need for console logging. You need to disable the Console Appender in log4j.properties in the conf/ directory.

    Also, there are logs generated for manager and host-manager apps. Do not forget to remove the appender configurations for these as well because they too are not going to have any information related to your app.

    Finally, the file appender used for tomcat logging is DailyRollingFileAppender. Instead of this, use RollingFileAppender with maxBackIndex and maxFileSize properties. This will allow only limited set of logs to be generated with which you can log enough details for any error that might occur. Here is a sample configuration for RollingFileAppender.

    log4j.appender.R=org.apache.log4j.RollingFileAppender
    log4j.appender.R.File=example.log
    log4j.appender.R.MaxFileSize=100KB
    log4j.appender.R.MaxBackupIndex=7
    log4j.appender.R.layout=org.apache.log4j.PatternLayout
    log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n



  8. Remove unnecessary Apps - Tomcat comes bundled with a lot of example applications. These are available in the webapps/ directory. On Production environments, these are not required and hence you can remove the same.



  9. Use Valves - A unknown feature of tomcat, yet so powerful. These valves are similar to plugins in your tomcat which allows you to pretty interesting things. A Valve element represents a component that will be inserted into the request processing pipeline. Say for example, a hacker tries to pull down your site by flooding request to your tomcat server. With the host which is making so much of requests, you can blacklist that request in tomcat using org.apache.catalina.valves.RemoteAddrValv. There is a huge list is of Valves that gets shipped with Tomcat. Check out here. And that's not all. If you think you can build one of your own, go ahead and give something back to the community.



  10. Use Load Balancing - Sometimes your request hit is so large that you tomcat keeps crashing all the time. You might think of having multiple tomcats with a load balancer. Check out load balancing documentation here.



  11. Changes in web.xml - Apart from the web.xml for each application, tomcat itself has a web.xml for configuration of JSP and Servlet processing. There are some configuration which you need to set for Production environment. The entire documentation for the same is here.
    • fork - This specifies whether the compilation of the JSP will be done in a new JVM or not. Make sure this is set to true. You would not want the compilation of the JSP to be done in the same JVM as the running tomcat.
    • development - Specifies whether the Tomcat is running in Development mode or not. Make sure this value is set to false
    • checkInterval - This is the interval after which the JSPs are checked for any modification and new compilation unit needs to be generated. Usually for Production environments, the deployments are not ad-hoc and manually done. They are scheduled and done with deployment tools like Ant or Maven. Thus, you don't need to be checking the JSPs for any modification. Free the tomcat from this task so that it focuses more on request handling.



  12. Enable Compression for Response - Last but not the least, enable compression for the response output that you send out to the browser. This will enable faster transmission for responses to the clients thereby increasing usability of your application. Here is how you do it in server.xml.

    <Connector acceptcount="100"
            compressablemimetype="text/html,text/xml"
            compression="on" compressionminsize="2048"
            nocompressionuseragents="gozilla, traviata"
            port="8080" redirectport="8443" />
    


Hope this helps you setting up your tomcat next time. And also, if you have set it up already, check out what you missed. :-)

Comments

Post a Comment

Popular posts from this blog

Personal Contact Manager

An apt quote

Alone