Have you ever seen this scenario before? A user has deployed an application to a Tomcat server. The application works great during testing and QA; however, when the user moves the application into production, the load increases and Tomcat stops handling requests. At first this happens occasionally and for only 5 or 10 seconds per occurrence. It's such a small issue, the user might not even notice or, if noticed, may choose to just ignore the problem. After all, it's only 5 or 10 seconds and it's not happening very often. Unfortunately for the user, as the application continues to run the problem continues to occur and with a greater frequency; possibly until the Tomcat server just stops responding to requests all together.
There is a good chance that at some point in your career, you or someone you know has faced this issue. While there are multiple possible causes to this problem like blocked threads, too much load on the server, or even application specific problems, the one cause of this problem that I see over and over is excessive garbage collection.
As an application runs it creates objects. As it continues to run, many of these objects are no longer needed. In Java, the unused objects remain in memory until a garbage collection occurs and frees up the memory used by the objects. In most cases, these garbage collections run very quickly, but occasionally the garbage collector will need to run a “full” collection. When a full collection is run, not only does it take a considerable amount of time, but the entire JVM has to be paused while the collector runs. It is this “stop-the-world” behavior that causes Tomcat to fail to respond to a request.
Fortunately, there are some strategies which can be employed to mitigate the affects of garbage collections; but first, a quick discussion about performance tuning.
Valves have been an integral feature of Apache Tomcat since version 4 was introduced over seven years ago. As their name suggests, valves provide a way of inserting functionality within a pipeline, in this case, the Tomcat request / response stream. One simply writes a subclass of
org.apache.catalina.valves.ValveBase or a class that implements the
org.apache.catalina.valves.Valve interface and then adds an XML element with the valve’s classname to the appropriate configuration file (in most classes as a sub element of Engine in server.xml). Then, at some point (we’ll come back to that) in the processing of a request, your valve’s invoke method will be called. The invoke method gets passed both the Request and the Response objects, and is free to do whatever it likes with them (though having the power doesn’t mean it’s a good idea to use it).
You may be familiar with this paradigm through servlet filters used by web applications to do application-specific processing of the request / response pipeline. The key distinction between servlet filters and Tomcat Valves is that Valves are applied and controlled through the configuration of the application server. Depending on the container definition where the Valve element appears in the Tomcat configuration, the valve could be configured for all applications on the application server, a subset of applications, or even a single application (by locating the Valve element within a given Context).
This is a simple powerful model that has been written about extensively. A Google search on “tomcat valve” turns up a multitude of descriptions, examples, and “how tos”. The Reference Page on “The Valve Component” that ships with Apache Tomcat 7 documents the mechanism thoroughly along with descriptions of the valve implementations that ship by default. So why yet another article on the subject? What do I hope to add to the canon?
The effort started simply enough: The plan was to demonstrate the configuration and use of the
ThreadDiagnosticsValve that ships with VMware’s vFabric tc Server, a commercial application server based on Apache Tomcat. Additionally I would write and configure a custom Valve, in this case, a valve to exercise tc Server’s
ThreadDiagnosticsValve so that I could demonstrate its use and effects without actually having to have a misbehaving application to trigger it. Not exactly Nobel material, but I thought it would be a useful adjunct to the existing documentation and an interesting exercise.
However, it didn’t go exactly as planned and looking at the reason it didn’t is probably as helpful in understanding Tomcat Valves as the original exercise.
Every effort is made to have each version of Apache Tomcat to ship with a system of reasonable defaults forsecurity purposes. This means that the standard defaults for the security settings are reasonably secure—it is not as secure as it could be, but not horribly insecure either. The default security level is essentially a compromise between security and usability. It is probably OK for simple use in production, but there are a number of things that all users should consider before deploying business applications on a standard installation of Apache Tomcat.
Apache Tomcat, and other containers, have been around for so long today that it has become increasingly harder to get started with them today.
In this article, we will take you back from the beginning with how to get started with Apache Tomcat. We will go into the lowest level, so you don't have to rely on an IDE or other system to get started. This article is written for those that have never used Apache Tomcat and wish to get started in an easy, yet explanatory, way that helps you to understand what is happening under the hood. This will fast track you to become very proficient with this light weight application server.
While there are a lot of different packages available to install Tomcat, for example some Linux distributions you can download it using that distributions package and dependency management. This is good, for the sake of simplicity, but once again, you lose the concept of what Tomcat is and what true dependencies it has as well on how to use it.
I strongly recommend only moving to a third party packaging of Apache Tomcat after you understand the container itself. This will help avoid complications when you try to create a plan for how you distribute, upgrade and maintain your software.
Rule 1. When learning, only download the software from http://tomcat.apache.org/
Now, since you are learning Apache Tomcat from scratch, I suggest you start with Apache Tomcat 7. As explained in an earlier post, the majority of features that are implemented, are driven by the (Servlet) and (JSP) specifications. Each time the Servlet specification is upgraded, new features added, the Apache Tomcat will plan for a new major release of Apache Tomcat. The latest version, Apache Tomcat 7, is based on the version of the Servlet specification, in this case, Servlet 3.0.
The Servlet 3 specification - implemented in Apache Tomcat 7 - allows web.xml fragments and annotations to be used to specify configuration information for a web application. This means that, instead of packaging up every configuration centrally in your web.xml file, every JAR can have its own xml fragment containing its own little bit of configuration for whatever classes are in that JAR. This makes it easy to add support for packages with very little effort. For instance, a Spring developer would no longer need to add the Spring application context to the web.xml file, rather they could take advantage of a web fragment in the Spring JAR that would automatically add this configuration information at runtime.
Annotations take this one step further, and allow developers to annotate code that dynamically configures application components such as Servlets and Filters. Java libraries and frameworks have been embracing annotations for some time. In fact, several IDE’s these days use annotations as a default, adding the @WebServlet annotation by default when you create a new Servlet in a dynamic web project.
Both annotations and web fragments will impact performance, particularly at application startup. Tomcat has to scan every class in every single jar file to detect if the class has been annotated as a Servlet, a Filter or Listener. This can add substantial time to application start up, which is not so much of a problem for production applications as they should start very infrequently, but it can be pretty problematic during development when you are repetitively restarting.
Tip: If you are not going to be using annotations or web-fragments, you should set your metadata-complete to true in your web.xml file to avoid the longer start up time. (
The Apache Tomcat team announces the immediate availability of Apache Tomcat 7.0.22
Apache Tomcat 7.0.22 includes bug fixes and new features compared to version 7.0.21 including:
Please refer to the change log for the complete list of changes:
Note that this version has 4 zip binaries: a generic one and three bundled with Tomcat native binaries for Windows operating systems runningon different CPU architectures.
Announced this morning by the Apache Tomcat team:
The Apache Tomcat team announces the immediate availability of Apache Tomcat 7.0.21
Apache Tomcat 7.0.21 includes security fixes, bug fixes and new features compared to version 7.0.20 including:
Java 7 has recently been released, and Apache Tomcat 8 project has just opened for development. It begs the question – are they related?
In short, not necessarily. We create a new major version of Tomcat when there are new versions of three specifications—Servlet, JavaServer Pages (JSP) and Expression Language (EL). Minor updates (maintenance releases) do sometimes get produced but major changes to all three specifications are released together as part of the J2EE specification. Once a new version of the J2EE specification is released, this is what governs the update to the next major version of Apache Tomcat, and it will implement the new features defined within these specifications.
For Tomcat 6, the defining specifications are the Servlet 2.5; JSP 2.1 and EL 2.1 specifications and for Tomcat 7 they are Servlet 3.0; JSP 2.2 and EL 2.2. Work on the Servlet 3.1 and EL 3.0 specifications is underway, and it is expected that there will be a new version of the JSP specification although I haven't seen any indication of work in that area yet. If the changes in JSP 2.2 are anything to go by, any changes in the JSP specification are likely to be minimal and will probably happen closer to the J2EE release. In terms of Java 7 support, Tomcat 8 will require the minimum Java version specified by the Servlet 3.1 specification. At the moment, I expect that that will be Java 7 but we won't know for sure until the specification is finalized.
As the work on the specifications proceeds (I am on the expert group for both Servlet 3.1 and EL 3.0) and the changes firm up then those changes will be implemented in the Tomcat 8 branch. So far, Tomcat 8 specific changes have been limited to re-factorings that change some of the internal APIs and therefore have not been back-ported to Tomcat 7 since we don't want to change APIs there unless we have to. Current ideas for what features (other than the specification changes) might be included in Tomcat 8 can be found in svn along with the Tomcat 8 specific changes so far.
Announced this morning by the Apache Tomcat team:
The Apache Tomcat team announces the immediate availability of Apache Tomcat 6.0.33 stable.
Apache Tomcat 6.0.33 is primarily a security and bug fix release. All users of older versions of the Tomcat 6.0 family should upgrade to 6.0.33.
Note that is version has 4 zip binaries: a generic one and three bundled with Tomcat native binaries for different CPU architectures.
Apache Tomcat 6.0 includes new features over Apache Tomcat 5.5, including support for the new Servlet 2.5 and JSP 2.1 specifications, a refactored clustering implementation, advanced IO features, and improvements in memory usage.
Please refer to the change log for the list of changes:
-- The Apache Tomcat Team
Apache Tomcat 7 contains a number of new features around database connection pooling, which help administrators keep their application available and serving content, collecting customer information, and supporting their applications. The main one that has garnered a lot of attention is the new JDBC Connection Pool feature introduced by Filip Hanik last year. Another connection pool attribute not yet discussed here on TomcatExpert.com is the new closeMethod for speeding up the closing of JNDI resources that would otherwise be closed during garbage collection.
This feature stemmed from a common challenge for applications that make use of database connection pools attached to databases with limited connections allowed. For instance, if a database allows 50 connections, and an application uses a connection pool of 50 connections, in theory everything should work. However, if the application is reloaded, the existing open connections in the old pool would not close until they have been garbage collected. So the new application connection pool while configured for 50 connections, could run out at 37 if the old connection pool had 13 connections open.