Jason Sando

Sunday, October 22, 2006

Jetty 5.1 and 6.0 Performance on OS/400

At work we ran into some questions about Jetty (v5.1.6) and performance. We had a servlet that was building a large-ish SOAP response of about 400k as a String, and then using:

response.getWriter().write (result);

to send the entire 400k String back to our vb.net client. We assumed that modifying the code to write to the output a little at a time would actually improve performance, since Jetty would be able to send packets while our sevlet was waiting on local database resources to build the rest of the request. But that's not what happened.

I should mention the relevant details:
  • Jetty 5.1.6
  • OS/400 v5r2
  • JDK 1.4.2.
So we expected better performance, but instead it dragged to a crawl. A request that had been taking 2.5 seconds was now taking 30 seconds.

In response, my colleague Kris Jacobson wrapped the response writer in a BufferedWriter, with the default size. I haven't checked on 1.4.2, but on 1.5 the default is 8k (8192 bytes). And, voila! Performance came back to where it was before we rewrote the code (about 2.5 seconds).

So, I wrote a quick servlet, and an HttpClient console application to hit it, and test various combinations of buffer sizes and content lengths. And the results rather surprise me.

In fact, Jetty 5.1.6 already has a default buffer size of 8192. At least on Windows and Linux under JDK 1.5 and 1.6rc2. I tested on my local 100Mb network from my Fedora Core 5 machine hosting both Jetty 5.1.6 and Jetty 6.0.1, using the command line on my Windows XP box using JDK 1.6rc2. Results were nearly identical for both Jetty releases -- about 1.4 seconds to transfer 16 Megabytes. And that's with absolutely no change to the default buffer size, and without wrapping the response.getWriter() in another BufferedWriter.

So, methinks something is wonky on OS/400's JVM. I'll have to deploy my test servlet on the '400 and recheck everything.

I did learn through this that you don't need to add more buffering to what the Servlet container already provides. You should verify what the defaults are, and be aware of these calls:


Just because you call setBufferSize() doesn't mean the servlet container will set the buffer to exactly that size - it has some discretion about what makes sense.

We also ran into some problems with Keep-Alive connections from our VB.Net client to Jetty on the '400 that I need to research.