We're facing a /serious /issue with the non-native AJP connector.
To put it most simply, some requests seem to "get lost" in Tomcat in
various cases involving concurrent requests -- and not egregious numbers
of concurrent requests, either.
For instance,
1. Use a Tomcat 5.5.23 with a configuration like:
<Connector port="8010"
minSpareThreads="4" maxSpareThreads="12"
maxThreads="18" acceptCount="282"
tomcatAuthentication="false"
useBodyEncodingForURI="true" URIEncoding="UTF-8"
enableLookups="false" redirectPort="8443"
protocol="AJP/1.3" />
(which are intended solely for making it easier to test concurrency
issues that to overrun a realistic 'maxThreads' setting) and as a
control, similar thread pool settings on the direct HTTP connector:
<Connector port="8080" maxHttpHeaderSize="8192"
minSpareThreads="4" maxSpareThreads="12"
maxThreads="18" acceptCount="282"
enableLookups="false" redirectPort="8443"
connectionTimeout="20000" disableUploadTimeout="true" />
2. Use an Apache 2.2.4 with mod_proxy_ajp with a configuration like:
<Proxy balancer://ajpWorker>
BalancerMember ajp://localhost:8010 min=16 max=300 smax=40
ttl=900 keepalive=Off timeout=900
</Proxy>
RewriteEngine on
RewriteRule ^(/TestApp/(.*\.jsp(.*)|servlet/.*|.*\.jar))$
balancer://ajpWorker$1 [P]
(on Windows in this case; similar results can be obtained on Linux
at least)
3. Use a simple test JSP page (placed in a web app containing nothing
else):
<[EMAIL PROTECTED] session="false"
%><[EMAIL PROTECTED] contentType="text/html" pageEncoding="UTF-8"
%><%!
private static final String titleString = "Sleepy Test JSP Page";
%><html>
<head>
<%
String sleepSeconds = request.getParameter( "secs" );
if ( sleepSeconds == null )
sleepSeconds = "1";
long secsToSleep = Long.parseLong( sleepSeconds );
Thread.sleep( 1000L * secsToSleep );
%>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title><%=titleString%></title>
</head>
<body>
<center>
<h2><%=titleString%>: SUCCESS!</h2>
[Slept <%= secsToSleep %> seconds.]
</center>
</body>
</html>
4. Hit the page with ab
* First, test direct Tomcat connections:
o ab -n 24 -c 24 -A wcadmin:wcadmin
http://hostname:*8080*/TestApp/test.jsp?secs=3
+ Result: All requests complete sucessfully in
6118 ms.
* Second, test connections via Apache:
o ab -n 24 -c 24 -A wcadmin:wcadmin
http://hostname/TestApp/test.jsp?secs=3
+ Result: Only 17 requests complete before ab
times out.
* Third, test connections via Apache again soon (under the
BalancerMember 'timeout' seconds) after the last test
o ab -n 24 -c 24 -A wcadmin:wcadmin
http://hostname/TestApp/test.jsp?secs=3
+ Result: Only 9 requests complete before ab times
out.
Something is clearly /horribly/ wrong with the handling of any
concurrency over 'maxThreads' in this case. Even so, there seems to be
some sort of "off-by-one" error in that only 17 requests complete, not
18. Worse, this has a lingering effect that decreases Tomcat's ability
to concurrent requests thereafter (with this impact seemingly being much
worse the longer the BalancerMember timeout is set to -- and we have
some very long running requests and thus need this timeout to be /very/
large).
This is not the only ill effect we've seen when hitting Tomcat 5.5.24
with concurrent requests in this manner, but it is a good place to start.
As for the native connector, it just works here. So why don't I just
use it? Well, first off, we have to support Tomcat on Windows (32 and
64-bit), Linux, Solaris, HPUX (PA-RISC and Itanium), and AIX. We've
been unable to get the connector built on some of these platforms and on
some we can't get the resulting binary to function (specifically on
AIX). Further, we had some stability issues with the native connector
in the past and had considered the Java connector the safest, if not
fastest, option -- and to a degree given that everything is Java I still
feel that's the case. Finally, however, this connector should just
plain work. Tomcat shouldn't be a cripple unless/until you manage to
build a native connector for your platform.
Any troubleshooting and/or debugging ideas (e.g. where exactly to place
breakpoints, what logs to turn on, etc, etc) would be /greatly/ appreciated.
--
Jess Holle
[EMAIL PROTECTED]
P.S. If this should go to the user's mailing list instead that's fine,
but this really seemed like a developer-oriented issue to me.