Boost Tomcat performance for static content

PippoProxy offers an alternative to standard Apache-Tomcat implementations

1 2 Page 2
Page 2 of 2

You can complete this customization by either editing your web.xml deployment descriptor or using PippoProxy's Ant scripts. PippoProxy's Ant scripts have all you need if you want to deploy PippoProxy as a standalone Web application. Thus, you should need to edit your web.xml only when you integrate PippoProxy into an existing Web application.

To edit your deployment descriptor, place PippoProxy's Java classes into your J2EE application's WEB-INF/lib directory as a JAR according to the Servlet specification and then edit the web.xml deployment descriptor. For packaging PippoProxy's classes into a JAR, you can use the jarPkg Ant target after editing the file:


# # Application name. # application_name=pp

# # Local temp directory to do stuff. # outdir=build

For example, if your PippoProxy home is /usr/local/pippoproxy, launching ant jarPkg in the previous instance of will package PippoProxy's Java classes into the JAR /usr/local/pippoproxy/build/dist/pp.jar and the HTTP client library used by PippoProxy into the JAR /usr/local/pippoproxy/build/dist/HTTPClient.jar. These JARs should be copied into your J2EE application's WEB-INF/lib directory. Next, edit the web.xml deployment descriptor, setting all parameters, whose semantics are described in the next section.

If you want to deploy PippoProxy as a standalone Web application—running under http://[domain]:[port]/pippo/, for example—edit the file (as above), setting the property deploy_local as below:

   # Local Tomcat webapps. 
   deploy_local=C:/java/tomcat/5.0/Tomcat 5.0/webapps

So configure the file (see next section) and launch ant deploy to generate PippoProxy's war file and copy it into Tomcat Web applications automatically.

As a further deployment mode, you can allocate a complete Tomcat server as a proxy server using PippoProxy. In this mode, PippoProxy will proxy all URLs matching the pattern http://[domain]:[port]/* (for further details, see PippoProxy documentation).

Advanced settings

This section describes parameters used by PippoProxy, whether you configure them manually in your J2EE application's deployment descriptor or edit them in the file.

  • ENABLE_SESSION_ATTR_KEY_FOR_LOGIN: True for checking the value of a session attribute before proxying (e.g., true).
  • SESSION_ATTR_KEY_FOR_LOGIN: The eventual attribute to check before proxying (e.g., my_attr_for_proxy).
  • CACHE_ENABLED: True (static content only) for enabling PippoProxy's cache (e.g., true).
  • CACHE_TIMEOUT: Lifetime (in milliseconds) of a resource before being removed from the cache (e.g., 3600000).
  • CACHE_MAX_MEMORY_SIZE: The maximum size (in MB) of memory cache (e.g., 10).
  • CACHE_MAX_DISK_SIZE: The maximum size (in MB) of filesystem cache (e.g., 50).
  • CACHE_PATH_DIR: The absolute path where resources are stored (e.g., /usr/local/pippoproxy/cache).
  • REMOTE_HOST: The remote host to proxy (e.g.,
  • REMOTE_PORT: The remote port to proxy (e.g., 80).
  • IS_ROOT: True for making the application server act as a proxy server (e.g., true); in this mode, PippoProxy handles all http://[domain]:[port]/* URLs. See PippoProxy documentation for further details.
  • LOCAL_PREFIX: The local prefix under which PippoProxy runs (e.g., by setting /lp, PippoProxy handles all client requests matching the URL pattern http://[domain]:[port]/[context]/lp/*).
  • REMOTE_PREFIX: The remote prefix to proxy (e.g., by setting /2.1, a client request for http://[domain]:[port]/[context]/lp/index.html will map to http://[REMOTE_HOST]:[REMOTE_PORT]/2.1/index.html).
  • NOT_ALLOWED_HEADERS: The pipe-separated list of HTTP headers to block (e.g., Content-Encoding|Content-Type).
  • PROXY_ENABLED: True if a further proxy server is available for reaching the internal server to proxy (e.g., true).
  • PROXY_HOST: The eventual proxy host for reaching the internal server to proxy (e.g., my_company.proxy).
  • PROXY_PORT: The eventual proxy port for reaching the internal server to proxy (e.g., 80).
  • PROTOCOL: Only http currently supported.
  • INIT_CONNECTION: The initial number of HTTP connections (e.g., 10).
  • MAX_CONNECTION: The maximum HTTP connections in the pool (e.g, 15).

Performance comparisons

This section compares the performance of PippoProxy deployed to Tomcat (5.5.4) and a standard Apache(2.0.49)-Tomcat(5.5.4) pair connected with mod_jk2 in the same machine.

Note: mod_jk2 has been configured so that the required resources are not forwarded by Apache to Tomcat, but handled locally by Apache itself ( file).

Testing platform:

  • Intel 730 GHz Pentium III
  • Single processor
  • 256 MB RAM
  • Linux 2.6.8

The tests attempt to simulate user scenarios where the same set of static resources is requested at a high repetition rate, hence, where the efficiency of the cache directly affects overall performance. Two file sizes have been used, 13 KB and 128 KB, and the same resource is requested 1,000 and 500 times, respectively.

As shown in Figure 7, the performance gap relative to the standard proxy increases as the file size increases. This is due to the fact that the PippoProxy cache works on the well-known principle of temporal locality, where programs tend to reuse data and instructions they have recently used (see Resources for more information).

Figure 7. Performance of PippoProxy compared with a traditional Apache-Tomcat pair for file sizes of 13 KB and 128 KB. Click on thumbnail to view full-sized image.

For small files, mod_jk and PippoProxy performances are quite similar, since the file initial-access time is a substantial portion of the total time for handling requests. But for larger files, differences among diverse caching behaviors are more evident. Though elapsed time for first calls is quite comparable, after 500 calls, on average, PippoProxy is five times faster than mod_jk. See Figure 8, where PippoProxy's throughput increases as the file size increases, while mod_jk throughput decreases.

Figure 8. PippoProxy's throughput increases as the file size increases. Click on thumbnail to view full-sized image.

This comparison shows how PippoProxy's built-in cache speeds up the delivery of static content for medium to large file sizes, without any penalty on the delivery of dynamic content, since the latter is managed in both cases by the supporting servlet engine.


This article introduced PippoProxy, a one-to-one replacement for standard Apache-Tomcat proxy solutions, and illustrated application scenarios in which this Tomcat-embeddable HTTP proxy offers clear advantages over standard Apache-Tomcat proxy solutions. Regardless of the deployment scenario, in case of static (or quasi-static) content, PippoProxy caching proves to be efficient; its performance is five times that of the traditional mod_jk-based proxy. Finally, PippoProxy does not require any optional modules or even a Web server for connecting to Tomcat, and configuration and deployment are easy when using Apache Ant.

I'd like to thank my manager Marco Fillo at Virgilio for his support while preparing this article and Vanessa di Lima for her invaluable assistance.

Gino Tesei is a senior software architect at Virgilio, one of the largest Italian Web portals. He specializes in search engines, e-shopping, and financial Websites. He has previously worked on a variety of projects in the finance and fashion industries. He is the creator of PippoProxy, has authored several technical articles, and is a member of the Java User Group Milano.

Learn more about this topic

This story, "Boost Tomcat performance for static content" was originally published by JavaWorld.

Copyright © 2005 IDG Communications, Inc.

1 2 Page 2
Page 2 of 2