tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From André Warnier>
Subject Re: [a bit, but not totally OT] Tomcat Behavior on Multiple HTTP requests from same browser
Date Thu, 21 Mar 2013 11:15:34 GMT

Christopher Schultz wrote:
> Hash: SHA256
> André,
> On 3/20/13 2:25 PM, André Warnier wrote:
>> Saurabh Agrawal wrote:
>>> All our assets are served from L3 CDN. So the asset requests
>>> never come to the application server.
>> That, I do not understand. I do not understand what you mean by
>> "assets" here, and I do not understand "L3 CDN". So I cannot tell
>> of this is relevant or not to the problem.
> CDN = Content Delivery Network. I'm not sure what "L3" (probably
> "Level 3", a data center operations company) is, but a CDN is
> basically a whole bunch of copies of your files geographically
> distributed such that requesting a file always gets the bits that are
> closest to you. Kind of a cool thing. ;)

Thank your for the above Rosetta Stone.  This computer business os so full of acronyms of

all kinds - some of them with multiple interpretations - that it is sometimes difficult to

grasp the meaning.  And I really don't feel like having to use Wikipedia every 3 words of

a post on the list.  Not when "static content is delivered by the Apache front-end" would

have done it.

> The bottom line is that Saurabh expects only dynamic requests to come
> to Tomcat, so keepalives should be much less useful than if Tomcat
> were to be serving everything. Imagine httpd out front serving all
> static content and forwarding dynamic stuff to Tomcat via AJP --
> that's almost exactly what's going on here, except that the static
> stuff is being served very efficiently from a network-topology
> perspective.
> Since AJP is in use, keepalive is almost entirely a red herring as
> typical AJP connections are permanently-connected to the web server.

Well, I would say so indeed forthe case of a html page wit embedded images e.g.
Butit may not be so in the "benchmark" case that Saurabh explained, with each of the 10000

clients making multiple requests to non-static content, presumably served by Tomcat.
A human user may have delays, that his testcase might not have.

>> So, by default, the keepAliveTimeout [for AJP] is set to
>> "infinite".
>> [snip]
>> And if the client keeps the connection open, but does not send any 
>> additional request on that connection, the Thread will wait 
>> theoretically forever (because that is what the documentation says
>> about the default value of these parameters).
> No, the defaults are different for non-AJP connections. Tomcat's
> default default is 60 seconds but the stock server.xml configures it
> to 20 seconds.

Right.  But my explanation was meant as an example only, to point out the interlinked 
effects of the various attributes and timeouts.
And 20 seconds is still an incredibly long time, in the context of 10000 "simultaneous" 
clients sending multiple requests each.

>> Now your case is a bit different, because - you are not using the
>> HTTP BIO connector (you use AJP)
> I think you've gotten yourself confused, here, unfortunately. You can
> use AJP with BIO, NIO, or APR (maybe you mixed-up AJP and APR between
> your eyes and your brain... the two are honestly too close to each
> other and it is very easy to do that).

Yes, I was confused and thank you for making me see the light.  I though that the AJP 
Connector was a beast all of it's own, and did not "use" these different underlying 
layers.  It is clear fom the documentation that it does though, I don't know how I could 
have overlooked that for so long.

> He is in fact using the BIO connector because he has specified
> protocol="org.apache.coyote.ajp.AjpProtocol".
>> - in front of your Tomcat, is an Apache httpd server.  This server
>> has its own keep-alive settings which apply to the connection of
>> the client with Apache httpd.  And these keep-alive settings are a
>> bit different from the Tomcat ones (for example, there is a
>> keep-alive timeout, but also a MaxKeepAliveRequests)
> +1
>> - between Apache httpd and Tomcat, there is the mod_jk module in
>> Apache, and that module uses its own timeouts (as set in
>>, and in addition it uses itself a pool of
>> connections to Tomcat, and this pool of connections has its own
>> rules for keeping alive a connection between Apache and Tomcat.
>> But the basic principles above apply, and may explain why you are
>> seeing what appears to be one Thread dedicated to one client,
>> forever.
> I think there might be a problem with the instrumentation, or just
> coincidences at a fairly implausible level. The trust of the matter is
> that Tomcat does not allocate a thread permanently to a remote client
> until ... whenever the client "disconnects" (whatever that means, as
> HTTP is a connection-less protocol).

(See the nitpick (*) below)

Possible, but see above again with the httpd/tomcat connections managed by the mod_jk 
module.  It does have and manage its own pool of connections, with each connection 
potentially "staying alive" for a time much longer than any individual client request.
I do not deny that.
But what I am not so sure of (and maybe Rainer could comment here) is this scenario :
- a client, via httpd+mod_jk, sends a single request to tomcat on a keep-alive connection,

and receives a response.  Now the client does not send another request anymore on the same

connection, but keeps it open "just in case".
Now say that at the client/httpd level, the keep-alive timeout is set to 30 seconds; and 
say that on the Tomcat AJP connector, the keep-alive timeout is set for 20 seconds.
What really happens ?
After this first request, Apache httpd would have to keep the client/httpd connection 
alive for 30 seconds, right ?  At the Apache-httpd level, that means that this "Apache 
child" process keeps its connection to the client open, and sits there waiting for another

request.  Mod_jk is not a separate animal; it is an Apache module, so it is code 
"embedded" in this one Apache-httpd child process.
So what does mod_jk really do ? he needed one connection to Tomcat, to send the first 
request and get the response, so he got it from the pool of connections.
mod_jk is aware that the client/httpd connection is keepalive, and it does not have any 
way to know that this client is not going to send another request to Tomcat.  So what does

mod_jk really do ?
Does it relinquish the one connection that he had to Tomcat back to the pool immediately 
after the first response has been served ? or does it keep its handle on that pool 
connection until the client/httpd timeout has expired ?
And assuming for a moment that it keeps this handle to himself for a while, what does that

mean at the Tomcat level ? is a Tomcat Thread also waiting on that same httpd/tomcat 
connection (at least for 20 seconds) ? or do Tomcat Threads *always* go back to the pool 
after serving one request ? or does it depend, and on what ?

There is also kind of a weird question here : what is really the purpose of the 
keepAliveTimeout attribute on the Tomcat AJP Connector ? I mean, connections to that 
Connector always come from some front-end module (be it mod_jk, mod_proxy_ajp or the 
isapi_redirector).  (It is very unlikely that they would come from some independent 
AJP-capable client).
Why would the AJP Connector need its own keepAliveTimeout attribute, if these front-end 
modules are themselves managing their connections to Tomcat, in the way that they deem 
appropriate ?
These front-end modules could pass to Tomcat the timeout that /they/ want, when they open

their individual pool connections to Tomcat, right?
Isn't that Connector keepAliveTimeout then more confusing than really useful ?
(And I guess that the same could be said for the connectionTimeout).

Come to think of it, that is probably why, in the case of the AJP Connector, the defaults

are "infinite". And maybe the attributes are left accessible for the rare edge cases where

they could prove useful.
If so, then I guess that a small note in the documentation would be useful.

(*) nitpick about HTTP being connection-less : that may be true in the sense that each 
request+response is supposedly independent from any other request+response.  But HTTP 1.1

explicitly introduces "persistent" TCP connections. And Microsoft has its own take on 
this, as for instance for Windows Integrated Authentication purposes, it is the 
*connection* which is authenticated, and each time the connection changes, the client has

to re-authenticate.  So the practice is a bit less connection-less than the theory.

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message