Monday, December 15, 2008

Tomcat Performance Tuning Tips



Tomcat Performance Tuning Tips

Most companies I have worked for use Tomcat as Servlet Container. It is de facto standard just like how Apache been used as Web Server. However, most of us just drag our war file to the webapp folder and use Tomcat with all the settings as default out of the box. It works fine in development environment but may not in production. This article will give you advice in several areas:

  1. Production Tomcat Architecture
  2. Tuning tomcat for performance
  3. Resolving problems which affect availability

Tomcat(Production)

In production Tomcat relies on a number of resources which can impact its overall performance. Understanding the overall system architecture is key to tuning performance and troubleshooting problems.

  1. Hardware: CPU(s), memory, network IO and file IO
  2. OS: SMP (symmetric multiprocessing) and thread support
  3. JVM: version, tuning memory usage, and tuning GC
  4. Tomcat: version (example, Tomcat 6 supports NIO)
  5. Application: Application design can have the largest impact on overall performance
  6. Database: concurrent db connection is allowed (pooling and object caching)
  7. Web Server: Apache can sit in front of Tomcat and serves the static content. It also can do load balancing across multiple Tomcat instances.
  8. Network: Network delays.
  9. Remote Client: How fast is the communication protocol? Content can be compressed.


Performance Tuning

How to see performance

  • Request latency is key b/c it reflects the responsiveness of your site for visitors.
  • Test environment should match production as closely as possible.
  • The data volume is important to simulate in database side.
  • Test HTTP requests with different request parameters (test corner cases)
  • Use load test to simulate the traffics (ex. JMeter)
  • Final tests should be over longer periods like days because JVM performance changes over time and can actually improve if using HotSpot. Memory leaks, db temporary unavailable, etc can only be found when running longer tests.

JVM

  • Sun Java and later releases inlcude some profiling optimizer customized for long running server application.
  • Tomcat will freeze processing of all requests while the JVM is performing GC. On a poorly tuned JVM this can last 10’s of seconds. Most GC’s should take <>
  • Tune the -Xms (min) and -Xmx (max) java stack memory (set them to the same value can improve GC performance)
  • Make sure the java process always keeps the memory it uses resident in physical memory and not swapped out to virtual memory.
  • Use -Xincgc to enable incremental garbage collection
  • Try reducing -Xss thread stack memory usage

Tomcat

  • Tomcat 6 supports NIO.
  • Set "reloadable" false - remove unnecessary detection overhead
  • Set "liveDeploy" to false - liveDeploy controls whether your webapps directory is periodically checked for new war files. This is done using background thread.
  • Set "debug" to 0
  • Set "swallowOutput" to true - This makes sure all output to stdout or stderr for a web application gets directed to the web application log rather than the console or catalina.out. This make it easier to troubleshoot problems.
  • Connector configuration - minProcessor, maxProcessor, acceptCount, enableLookups. Don’t set the acceptCount too high b/c this sets the number of pending requests awaiting processing. It is better deny few requests than overload Tomcat and cause problems for all requests. Set "enableLookups" to false b/c DNS lookups can add significant delays.

dbcp

  • We use connection pool provided by Spring instead
  • Using middleware to persist and cache objects from your database can significantly improve performance b/c of fewer db calls, less thrashing of the JVM for creation and subsequent GC of object craeted for resultset.

Application design and profiling

  • If the data used to generate a dynamic page rarely changes, modify it to a static page which you regenerate periodically.
  • Cache dynamic page
  • Use tool like JProble to profle your web applications during development phase
  • Look for possible thread synchronization bottlenecks
  • Date and Time thread synchronization bottleneck

Troubleshooting

Collecting and analyzing log data from production

Common problems on production

  • Broken pipe - For HTTP Connector indicates that the remote client aborted the request. For web server JK Connector indicates that the web server process or thread was terminated. These are normal and rarely due to a problem with Tomcat. However, if you have long request, the connectionTimeout may close the connection before you send your response back.
  • Tomcat freezes or pauses with no request being processed - usually due to a long pause of JVM GC. A long pause can cause a cascading effect and high load once Tomcat starts handling requests again. Don’t set the "acceptCount" too high and use java -verbose:gc startup argument to collect GC data.
  • Out of Memory Exception - look into application code to fix the leak (profile tool can help). Increase available memory on the system via -Xmx. Restart tomcat!
  • Database connection failure - connection used up when traffic is spike.
  • Random connection close exception - when you close your connection twice. First close(), the connection returns to the pool. It may be picked up by another thread. Now, second close() may close a connection that is being used by other thread. Don’t close connection twice, use JDBC Template from Spring to avoid this problem.



Saturday, December 13, 2008

Java Application Design and Performance Tips



Java Application Design Tips

Developing jav applications requires you to keep certain strategies in mind during the design phase. It is best to strategically design an application before you begin coding. Correcting the code because you failed to consider all of the "gotchas" before developing the application can be a painful process for Java Application Design.

Here are some design strategies to consider for Java Application Design:

  • Keep it simple. Remove unnecessary features, possibly making those features a separate, secondary application. (Java Application Design)

  • Smaller is better. This consideration should be a "no brainer" for all developers. Smaller applications use less memory.(Java Application Design)

  • Minimize memory usage. To minimize the amount of memory used at run time, , do not depend on the garbage collector. You should manage the memory efficiently yourself by setting object references to null when you are finished with them. Another way to reduce run-time memory is to use lazy instantiation, only allocating objects on an as-needed basis. Other ways of reducing overall and peak memory release resources quickly, reuse objects, and avoid exceptions. (Java Application Design)

Java Application Performance Tips


Code for performance. Here are some ways to code with the aim to achieve the best Java Application performance:

  • Use local variables. It is quicker to access local variables than to access class members.

  • Avoid string concatenation. String concatenation decreases performance and can increase the application's peak memory usage.

  • Use threads and avoid synchronization. Any operation that takes more than 1/10 of a second to run requires a separate thread. Avoiding synchronization can increase performance as well.

  • Separate the model using the model-view-controller (MVC). MVC separates the logic from the code that controls the presentation.