20 Tips for Using Tomcat in Production
Published: 17 May 2012
I've been working with Apache Tomcat for years and always seem to stumble upon new
information related to the proper setup and configuration for a production
environment. I've decided to put the instructions and tips I've collected
together in one place.
1. If you're running
on a 1.5+ JVM...
Add the following to
your JAVA_OPTS in catalina.sh (or catalina.bat for Windows): -XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/home/j2ee/heapdumps Then use a tool such as YourKit to analyze the heapdump file.
2. When using Jasper 2
in a production Tomcat server you should consider...
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.
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 from the users. To do this, simply add something like the following to
your web.xml:
5. Use a logging
toolkit.
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.
Update (comments from the user@tomcat.apache.org mailing list): The following should be considered when using
the shared library directory: 1. The shared classloader is searched in last
resort when looking for classes, according to http://tomcat.apache.org/tomcat-5.5-doc/class-loader-howto.html. 2. Because the classes are shared, they
share configuration and singletons and if they store objects statically they
will prevent your application from unloading.
This is turning out to
be a more controversial suggestion...
Starting with Servlet
Spec 2.3 (I think) there has been an emphasis on putting everything a web app
needs to run into its war file.
Shared classloaders
are evil, but not as evil as the invoker servlet. With a shared loader you can
easily get Singleton assumptions being wrong, class cast exceptions, versioning
woes, and other issues. Saving a little perm memory just doesn't justify it.
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.
10. Use a valve to
filter by IP or hostname to only allow a subset of machines to connect.
This can be configured
at the Engine, Host, or Context level in the conf/server.xml by adding something like the following:
11. 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 toCATALINA_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:
12. 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.
14. Do NOT run Tomcat
as root.
15. Precompile JSPs.
16. Secure directory
listings.
In CATALINA_HOME/conf/web.xml:
17. 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.
18. Monitor
application applications via Tomcat MBeans.
Consider JDK 1.5 or
even better JDK 1.6
To take advantage of
performance improvements.
Update (comments from users@tomcat.apache.org mailing list):
Update (comments from users@tomcat.apache.org mailing list):
Note that you can gain
even more performance if you recompile your "string concatenation
hungry" (d="aaaa"+b+"ccc") support libraries for JDK
5+ on a multi-CPU system. This is because JDK 5 uses the non-synchronized StringBuilder instead of the JDK 4- synchronized StringBuffer. And synchronization over multiple CPUs takes
a few more cycles than on single CPU machines.
19. 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.
20. Use GZIP
compression.
Look for the service
connector you wish to configure for compression and add two attributes, compression and compressableMimeType. For example:
port="80"
maxHttpHeaderSize="8192"
URIEncoding="UTF-8"
maxThreads="150"
minSpareThreads="25"
maxSpareThreads="75"
enableLookups="false"
redirectPort="8443"
acceptCount="100"
connectionTimeout="20000"
disableUploadTimeout="true"
compression="on"
compressableMimeType="text/html,text/xml,text/plain,application/xml">
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.
No comments:
Post a Comment