Tech Brainwave

A Road Map for Innovative Technologies

Tomcat Production Server – Performance Tuning

Posted by giftsam Posted on Nov - 29 - 2010

Introduction
Think about this situation, you had developed an application which contains excellent layout, latest features and all the other things which relishes the application. But if it lacks in performance means, No matter what surely the application will be rejected by the customers. Customers always expect their application should have a better performance. If you used Tomcat server for your production, then this article gives you some aspects to improve the performance of the Tomcat Server. Thanks for the resources provided in this ITWorld article. After pondering the net I had understand that the latest release of Tomcat gives the better performance and stability when compared to Old version. So always use the latest version of Tomcat. Now in this article, the following steps are used to improve the performance of the tomcat server,

  1. Increase JVM heap memory
  2. Resolve JRE memory leaks
  3. Thread pool setting
  4. Compression
  5. Database performance tuning
  6. Tomcat Native Library
  7. Other options

Step 1 – Increase JVM heap memory
If you had used tomcat, definitely you would have heard about “Permgen Space” error. Simply said “OutOfMemoryError”. Mostly this error will occur in the production environment. The reason for this error is tomcat has very small memory for the running process, this error can be resolved by doing some changes in the Tomcat configuration file named “catalina.bat(In windows)/catalina.sh(In Linux)”. The changes to be made is to increase the JVM heap memory. That is , the JVM does not invoke the garbage collector often, so the server can focus more in serving web requests and the requests are completed faster. The file(catalina.sh) to be changed is located at “\tomcat server folder\bin\catalina.sh” and the configuration to be made in this file is given below,


JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8
-server -Xms1024m -Xmx1024m
-XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m
-XX:MaxPermSize=512m -XX:+DisableExplicitGC"

-Xms – Specifies the initial heap memory
-Xmx – Specifies the maximum heap memory
The changes will gets activated, Once you restart the Tomcat Server. Next we shall see how to handle the memory leak,

Step 2 – Resolve JRE memory leaks
Another main reason for the performance lack is memory leak, as I said before always use the latest tomcat server to get better performance and scalability. Now the phrase becomes true. This error can be resolved if we use the latest tomcat server version 6.0.26 and above. Since it contains a listener to handle the JRE and permgen memory leak. The listener used here is,


<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />

You can find the above listener class configuration in the server.xml file which resides in “tomcat project folder/conf/server.xml”. Next we shall see how to tune the connector attribute “maxThreads”.

Step 3 – Thread pool setting
Thread pool specifies the number of web request load that comes in, So this part should be handled carefully in order to get the better performance. This can be accomplished by tuning the connector attribute “maxThreads”. The value of the maxThreads should be based on the volume of the traffic. If the value is low, then there will not be enough threads to handle all of the requests, so it undergoes in to the wait state and comes back only when an another request thread gets freed. If we set maxThreads value too high means then the Tomcat startup time will take longer. So its up to us, Put a right value in the maxThreads.


<Connector port="8080" address="localhost"
maxThreads="250" maxHttpHeaderSize="8192"
emptySessionPath="true" protocol="HTTP/1.1"
enableLookups="false" redirectPort="8181" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />

In the preceding configuration, maxThreads value is given as “250″. This specifies the maximum number of simultaneous requests that can be handled by the server. If not specified, the default value of this attribute “200″. Any further simultaneous requests will receive “connection refused” errors until the another request gets freed. The error looks like the below,



org.apache.tomcat.util.threads.ThreadPool logFull SEVERE: All threads (250) are
currently busy, waiting. Increase maxThreads (250) or check the servlet status

If  the application results in the above error, Always investigate whether the above error caused by a single request that takes too long. The reason is, Sometimes if the database connection is not released means, it will not allow to process additional request.

Note: If the number of request exceeds “750″ means, Instead of setting the value “750″ in the maxThreads attribute, Its better to go for the “Tomcat Clustering” with multiple tomcat instances. That is, In the case of “1000″ request,  set “maxThreads=500″ for the two instances of tomcat,  Instead of a single Tomcat with maxThreads=1000.

According to my perspection, the exact value can be determined only by testing the application in various environment. Next we shall see how to compress the mime types.

Step 4 – Compression
Tomcat has an option to compress the mime-types by doing some configuration in the server.xml file. This compression should be done in the connector like the below,


<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8181" compression="500"
compressableMimeType="text/html,text/xml,text/plain,application/octet-stream" />

In the preceding configuration, the files will be compressed when the number of bytes is >= 500. If the files not to be compressed by the size means, Set the attribute compression=”on”. Otherwise the default the setting in Tomcat is “off”. Next we shall see, How to tune the database.

Step 5- Database performance tuning
Tomcats performance gets lacked while waiting for the database queries to get executed. Nowadays most of the application uses Relational databases, which may contains “NamedQueries”.  If so, by default the tomcat will load the named queries initially, this may increase the performance. Another important thing is, always ensure that all the database connections are closed properly. Also setting the correct value in the database connection pool is very essential. I mean the values in maxIdle, maxActive, and maxWait attributes of the Resource element. Since the configuration depends on the application requirements, I cannot specify the right values in this article. You can find the correct values by invoking the performance testing for the database.

Step 6 – Tomcat Native Library
Tomcat native library, “Apache Portable Runtime(APR)” provides superior scalability, performance and better integration with the native server technologies and gives optimal performance in the production environment. The installation steps is explained in the article Tomcat Native Library – (APR) Installation.

Step 7 – Other options
Some of the other options are,

  • Enable the web browser cache, so that the static content which resides in the webapps folder loads faster, By doing this the performance is greatly increased.
  • Tomcat server should be automatically restarted, whenever the machine starts.
  • Normally HTTPS request is slow when compared to the HTTP request. But what ever if you want some good security for the application means, we should prefer HTTPS instead of HTTP.

Thats all folks. In this article I have given some stuffs to improve the Tomcat server performance. If you find this article is useful to you or if you have any other options to improve the performance, dont forget to leave your valuable comments. Have a joyous code day.

19 Responses so far.

  1. nick says:

    Using different connector will also have different results on performances, depending on what kind of data you are serving and your server architecture. Books like the definitive guide to tomcat 6 cover it well. Another point is the importance of load testing. Each server and each app will require different tomcat tuning and a good load test plan will let you monitor this. I think your next article should cover this! Good job for this one though.

    Thumb up 3 Thumb down 0

    [Reply]

    giftsam Reply:

    Thanks for your comments. Yes you are right, Each server and each application will require different tomcat tuning. As you said, I will write an article about load testing in the forth coming days. Also I would like to ask you a question. What web application test tool do you use to test your application. I have tried out selenium.

    Thumb up 0 Thumb down 0

    [Reply]

  2. Great article. Thanks for putting this up.

    Thumb up 2 Thumb down 0

    [Reply]

    giftsam Reply:

    Thanks James!!

    Thumb up 0 Thumb down 0

    [Reply]

  3. Dark side of maxthreads is not only Tomcat startup time. If you allow too many threads to operate simultaneously, you might be hogging you CPUs, and thus slowing *all* requests.

    I’ve seen setups in which the system was *way* much responsive limiting the maxThreads in a low (15 or so) number, resulting in a lesser “lead time” of requests. The problem of refusing was not such because the exceeding connections were waiting in the Apache HTTPd…

    But as you said, *testing* your setup is the only real way of getting the truth. Good article!

    Thumb up 2 Thumb down 0

    [Reply]

    giftsam Reply:

    Thanks for your substantive hint, I too had experienced too many threads will slow down all the request. if you set the maxThreads value as 15 in a Mission Critical Application(1000+ simultaneous request) means, the request processing will be low. In that case, I will set the maxThreads value quite high. If not I will go for clustering.
    Have you used Tomcat in a Mission critical applications. Do you have suggestions for handling Mission Critical Applications??

    Thumb up 0 Thumb down 0

    [Reply]

  4. bill m says:

    What about Apache Portable Runtime?

    http://tomcat.apache.org/tomcat-6.0-doc/apr.html

    Tomcat can use the Apache Portable Runtime to provide superior scalability, performance, and better integration with native server technologies. The Apache Portable Runtime is a highly portable library that is at the heart of Apache HTTP Server 2.x. APR has many uses, including access to advanced IO functionality (such as sendfile, epoll and OpenSSL), OS level functionality (random number generation, system status, etc), and native process handling (shared memory, NT pipes and Unix sockets).

    Thumb up 3 Thumb down 0

    [Reply]

    giftsam Reply:

    Hi Bill,
    Thanks for the excellent suggestion, I had updated the article.

    Thumb up 0 Thumb down 0

    [Reply]

  5. deekay says:

    Great tips for performance tunning.. i will try out all these option..

    Thumb up 0 Thumb down 0

    [Reply]

    giftsam Reply:

    Hi Deekay,
    Thanks a lot!!

    Thumb up 0 Thumb down 0

    [Reply]

  6. [...] Quite some time back, I had wrote an article about Tomcat Production Server – Performance Tuning. In that article, I have missed out an important feature “Apache Portable [...]

    Thumb up 2 Thumb down 0

  7. [...] Tomcat Production Server – Performance Tuning (tags: tomcat java) [...]

    Thumb up 0 Thumb down 0

  8. swaps says:

    This is the Great article i have fallow your suggesation and found good result on tomcat performance. if you can provide an article on clustring it would be a great.

    Thumb up 0 Thumb down 0

    [Reply]

  9. rips says:

    Very Informative …

    Thumb up 0 Thumb down 0

    [Reply]

  10. james says:

    Thanks, this is really a helpfull blog.

    Thumb up 1 Thumb down 0

    [Reply]

  11. good post useful when setting up a new production box.

    Thumb up 0 Thumb down 0

    [Reply]

  12. Sachin says:

    Thanks for your great article.

    Thumb up 0 Thumb down 0

    [Reply]

  13. Manasa P says:

    Definitely be helpful for new learners .Superb Article

    Thumb up 0 Thumb down 0

    [Reply]