Mod_jk and Tomcat stuck at Sending Reply - apache

Currently, the server at work is underperforming and the way it's set up is not ideal either. For this reason I'm trying to find a new way to do things that will hopefully help with both, performance and deployment.
The approach I decided for is to have tomcat instances for our webapps (currently there are two, so it'd be an instance per webapp) and use Apache as a "front". I'm not experienced in this, so It's normal I'm having issues here and there, but so far I've manage to get this going.
What I expect is to redirect from mysite.com index page to either mysite.com/service1 or mysite.com/service2. Service1 was setup in out test server at port 8080 and service2 at 8081. I installed Apache2 and mod_jk yesterday and set up apache with the contents of mysite.com. Today I started the configurations, that ended up as follow:
workers.properties
worker.list=s1
worker.s1.type=ajp13
worker.s1.port=8009
#host is localhost by default according to the documentation
jk.load
LoadModule jk_module /usr/lib/apache2/modules/mod_jk.so
JkWorkersFile /etc/apache2/workers.properties
JkLogFile /var/log/apache2/mod_jk.log
JkLogLevel debug
JkMount /service1/* s1
Service1's server.xml connector (The rest is all default)
<Connector protocol="AJP/1.3" port="8009" redirectPort="8443" />
I had more, but because of the errors, I took a step back and tried with only one tomcat for now. I will add the second tomcat and a loadbalancer.
Ok, so what's going on?
I can access the server and the index page of our system with no problem. The problem is when I try to redirect to service1. It just loads without response, but if I try to access service1 directly by port 8080, it works properly (I tired commenting out this connector. No luck).
Looking at server-status, I see the request stuck at w/sending reply, and in mod_jk.log I see that the worker properly matches the request. So while my configurations seem to be right, there is something in between happening. I don't really know if it's something with Apache, Tomcat or Mod_jk. I also tried to follow several guides of how to do this, but all of them got me to 404s. Looking around here and ServerFault didn't shed much light unfortunately so I'm the one asking now.
Am I missing something? Should I just use another approach? I'm very new at this and I'm at loss right now. The configuration and the logs show that nothing is really wrong (at first glance, at least...) so I'm entirely sure if my case scneario is even posible with mod_jk... HOnestly to run it back and try with proxy is very tempting at this point, but if I am, I'd rather know where Im wrong.
Additional info: Running on Ubuntu Server 18.04, lastest apache2 and mod_jk avaliable from apt (as of Apr 14), java 1.8 and Tomcat 8.5.64.

There was a change in Tomcat last year (from version 8.5.51 and version 9.0.31), which introduced a secretRequired attribute to the AJP connector with a default of true (cf. documentation). Hence you can either:
add a shared secret between the AJP connector and mod_jk
or add secretRequired="false" to the AJP connector:
<Connector protocol="AJP/1.3" port="8009" secretRequired="false" redirectPort="8443" />
Remark: AJP is a very old protocol and rarely used. Since your installation is pretty new, you might consider using directly HTTP (cf. this talk).

Related

apache and IP oddities

I installed Apache 2.4 in order to publish a java (Struts2) application using Tomcat 8 as AS.
For a while it worked out well then something happened "strange" (to put it mildly).
By typing "http://localhost/appName" all continues to work out wonderfully.
Typing "http://publicIP/AppName " it opens pop up asking for a password to access the network printer!
The PC address on which they reside, Servers and Application, is 192.168.0.104, the one of the printer is just 193.168.0.103, exactly the previous by the point of view of the router (working in DHCP mode).
But (I may be *** but not to this extent) to the PC I manually set 104 as the fixed IP (which is still set - and anyway, when I check the Client List on the monitor of the router, I find right 104 as IP assigned to the PC).
No one has changed the settings to httpd.conf (ServerName is always 104), let alone the various mod_jk.conf or workers.properties or server.xml of Tomcat (so much so that, as I said, typing in the browser the local address all still works)!
...what could possibly have happened?
It sounds like your firewall is port forwarding port 80 to the private IP of the printer, rather than the apache server. The fact that you're getting the printer means the problem is not related to the apache or tomcat configuration.
Something new happened so I think Apache or Tomcat conf is related.
I restarted the router: at first, typing in the browser "http:// publicIP/appName", all was working, after several minutes, typing the app address, it asks me if i wanna download a (unspecified) file and accessing directly to Apache (typing "http:// publicIP") it answers "It works"!
Accessing to "http:// localhost/appName" anytime all works fine!
I restarted the router for a second time: accessing to "http:// publicIP/appName", error message "File not found" and typing "http:// publicIP", it asks me the pw to access to an IPcam! I thinked: "It's trivial! if it aims for the IPcam... it can't find my app!" ("http:// localhost/appName" ever all fine, of course!)
But no: i restarted for a third! Maybe all ok for several minutes and after: "http://publicIP/appName" returns still a "File not found" message but "http://publicIP" tells me "It works!"...!!!
Maybe the connector (or the connector configuration) bears some responsibility for this whole mess?
If my suspicious can have some substance I add the code.
I've a basic manual configuration:
at the end of httpd.conf
include "C:/Program Files/apache-tomcat-8.0.23/conf/jk/mod_jk.conf"
in mod_jk.conf:
LoadModule jk_module modules/mod_jk.so
JkWorkersFile "C:/Program Files/apache-tomcat-8.0.23/conf/jk/workers.properties"
(JkLogFile, JkLogLevel, JkLogStampFormat, JkOptions, JkRequestLogFormat are also set)
JkMount /appName ajp13
JkMount /appName/* ajp13
in workers.properties:
worker.list=ajp13
worker.ajp13.type=ajp13
worker.ajp13.host=localhost
worker.ajp13.port=10009
worker.ajp13.lbfactor=50
worker.ajp13.cachesize=10
worker.ajp13.cache_timeout=600
worker.ajp13.socket_keepalive=1
worker.ajp13.socket_timeout=300
and finally, in server.xml:
Connector port="10009" protocol="AJP/1.3" redirectPort="8443" enableLookups="false" /
thank you!
PS - I have another suspicious too: the IPcam remote monitor works on port 80... there may be some relationship? (but that don't explain the download request...)

Load Balancing and Clustering in Liferay- css not loading

I am trying to Implement clustering in liferay 6.2 on my local system using sticky sessions.
I followed below steps to configure this.
1 install Apache Webserver and made following changes in httpd.conf
Added below code snippet at the end of file.
<Proxy balancer://clusterdemo>
BalancerMember ajp://localhost:8009/ route=INT1 smax=15 max=50 loadfactor=20
BalancerMember ajp://localhost:8010/ route=INT2 smax=15 max=50 loadfactor=20
</Proxy>
<Location / >
ProxyPass balancer://clusterdemo/ stickysession=JSESSIONID
</Location>
and uncommented below lines
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule status_module modules/mod_status.so
2 Extracted two copies of Liferay 6.2 bundle and changed the port nos accordingly
3 Changed jvmRoute in server.xml file of both Liferay tomcat bundle.
First Instance
<Engine name="Catalina" defaultHost="localhost" jvmRoute="INT1">
Second Instance
<Engine name="Catalina" defaultHost="localhost" jvmRoute="INT2 ">
4 Added below properties in portal-ext.properties file of both Liferay instance and configured same database for both instances.
cluster.link.enabled=true
cluster.link.autodetect.address=localhost:3306
5 Restarted Apache Webserver and both Liferay instance
If i hit http://127.0.0.1/web/guest/welcome url in browser i can see login page and by entering username and password i am able to login.
Problem
Now my problem is css files are not getting loaded properly as shown in below image.But with classic theme its working fine.
I think its able to load css file from Liferayhome\tomcat-7.0.42\webapps\ROOT\html\themes\classic but not from Liferayhome\tomcat-7.0.42\webapps\welcome-theme any reason??/.
Firbug Screenshot
Could you please help me help me in this?
**Update:**I further checked few things in browser and looking at cookie i can verify its transferring control to both instances.
Cookie:COOKIE_SUPPORT=true; JSESSIONID=48705C436A9BE3D054577705EA41FA77.INT1; GUEST_LANGUAGE_ID=en_US
Cookie:COOKIE_SUPPORT=true; JSESSIONID=C04FBBD76B10422D292827B301320DC4.INT2; GUEST_LANGUAGE_ID=en_US
Thanks in Advance
You're missing several other steps in correct Liferay clustering as well. From the top of my head,
Document Library
Search Index
are obvious missing steps. Please go through the Liferay clustering documentation and note that this is only part of the story: In Liferay's System Administration Training we'll take almost a full day to discuss all of the different clustering options. That doesn't mean that clustering takes that long - it's just that there is no single correct cluster configuration, but it all depends on the available infrastructure and expected load and use cases for your portal.
As of the missing CSS files - please monitor what replies exactly you get back from Apache/Liferay - e.g. use Firebug or similar tools to check if you get 404, 500 or others back, and what the error message is.
As of configuring sticky sessions, I'm typically configuring tomcat to indicate the server name (look up jvmRoute for server.xml) so that it automatically adds its name to the sessionid and Apache has a chance to know which tomcat created the session.
After your comments, more things to check:
Identify which server you're balanced to. Then access the missing resources through http - e.g. port 8080 or 8081 (or whatever that server has configured)
Check if this only happens when INT1 goes down but not when INT2 does (or vice versa)
Check if this happens when you're balanced to another server than initially (e.g. you're on INT1, take down INT1, get balanced to INT2 -> Problem? You're on INT1, take down INT2, stay on INT1 -> Problem?)
Make sure the AJP forwards are correct - you use localhost in your question. It's quite untypical to have two machines on the same server. If you changed this for the question, make extra extra extra sure that the hostnames are valid and do not contain typos. - and they're routable. Try nmap from the Apache host to the appservers to make sure the ports are reachable and no firewall steps in between Apache and your appserver
While you do all of this, keep your eyes open and don't blindly follow this advice: There's so much to pay attention to that it's impossible to list everything in this answer.
Also, this gets closer to system administration rather than programming and might be better suited for serverfault.com.
I don't know much about Liferay, but I have dabbled with Tomcat.
I'd suggest you check how ROOT and welcome-theme are configured in server.xml (and/or any context XML files).

Long URLs in combination with Apache httpd and Tomcat

I'm currently in the process of configuring Apache httpd to direct all traffic for '/api/foo' to a specific Tomcat instance via AJP (using mod_proxy_ajp). For this purpose I have the following ProxyPass rule in my httpd configuration file:
ProxyPass /api/foo ajp://localhost:9999/api/foo connectiontimeout=300 timeout=300 retry=3
This Tomcat instance has the following connector defined in its server.xml:
<Connector port="9999" protocol="AJP/1.3" redirectPort="9443"/>
With this configuration I reach my Tomcat instance correctly when visiting /api/foo. However, when the URL becomes bigger than 300 characters I can't seem to reach my Tomcat instance, sometimes.
The first hour it could be that I get a timeouts and the other hour it could be that everything comes through just fine.
When I get timeouts, I see the following errors in my httpd error log:
[error] (70007)The timeout specified has expired: ajp_ilink_receive() can't receive header
[error] ajp_read_header: ajp_ilink_receive failed
[error] (70007)The timeout specified has expired: proxy: read response failed from 127.0.0.1:9999 (localhost)
And the following result in my httpd access log:
"GET /api/foo/barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr HTTP/1.1" 503 323 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:33.0) Gecko/20100101 Firefox/33.0"
The strange thing is that this request doesn't seem to reach my Tomcat instance. I don't see anything reaching my application logging, and I also don't see the request in my Tomcat access log.
Does anyone have an idea what could be the cause of this problem? The timeout is set to more than 1 minute, so I'd expect the request to at least reach my Tomcat instance...
As a last note, I've tried setting the AJP connector's packageSize to 65536 and Apache httpd's LimitRequestFieldSize and ProxyIOBufferSize to 65536. This didn't solve the problem.
In the absence of a better answer I though I would share my experience with a similar and possibly the same problem and give you a recommendation to change the connector you are using.
I have also received the same ajp_read_header: ajp_ilink_receive failed errors while using mod_proxy_ajp in slightly different environments using apache 2.2 & tomcat 6.
I've tried many various and recommended fixes including the connector timeout and other connector settings when we encountered our issue.
From what I've read, some of these will work in different scenarios and the error ajp_ilink_receive failed message seems to be quite generic. In your case this occurs when the URL is longer than 300 characters - well sometimes at least..
After trying many of the different connector properties both from within the tomcat server.xml and the apache ProxyPass settings appended after the ajp:// URI I pretty much gave up going down this path. Since then I have tried mod_proxy and mod_jk which both seem fix the issue or at the very least there is no more ajp error. But this wouldn't happen with mod_proxy anyway because it doesnt connect with ajp.
So I suggest to change your tomcat connector to either mod_proxy or mod_jk. There are various write ups on the differences but the pages here and here on tomcat expect are a reasonably good source of information. You;ll want to choose between mod_proxy and mod_jk based on your setup. mod_jk, while different, is actually not too hard to set up (but you may have to build the mod_jk.so for apache).
Summarising the different connectors;
mod_jk: highest recommendation. ajp connector. purpose designed. different configuration setup that resides outside apache. difficult to configure when connecting a webapp with a certian name to a different url name.
mod_proxy: http connector. reportedly more stable than mod_proxy_ajp. problems with passing ssl variables?
mod_proxy_ajp: least recommended but most common. ajp connector. extension of mod_proxy. easy implementation.
If this doesn't work for some reason. Others have had success looking into problems on the tomcat side such as long running queries.

Guide to setting up Apache2 with multiple distinct Tomcat 7 instances

I realize this question has probably been asked numerous times, but I have not been able to find a good, up-to-date answer. The only guide I have been able to find was from 2005 and was on tomcat 5. It seems a lot of the OS paths have changed.
Our situation is this:
We want to run multiple instances of tomcat 7 on a single server. Each tomcat serves up a different address. For instance, www.oursite.com should be served from a separate tomcat than test.oursite.com. So, for example the base tomcat installtion will sit in /opt/tomcat/ and the instance specific directories (this is what I could make out from that old tutorial) will be in /home/user1/some/path/ and /home/user2/some/path so that everything is seperated nicely.
Can anyone point to a good tutorial, or maybe explain here the steps to set this up? I'm a bit new to apache setups.
Are there any advantages / drawbacks to doing it this way? Would a single tomcat instance be better? We need to be able to bring down sites one at a time without influencing each other. Also, our DNS provider prevents us from setting up stealth redirects, so we have to go through apache to have nice URLs rather than redirecting straight to the tomcats.
Thanks
I believe you have 2 questions here:
How to run multiple tomcat instances in the same server and should
you?
How to configure apache httpd to do virtual host and front
tomcat?
For 1. The following is a very good tutorial on how to run multiple tomcat instances in the same server: http://java.dzone.com/articles/running-multiple-tomcat, but should you? the answer is "it depends". If you have a super powerful box and it is under utilized, you should. It also depends on what type of application you runs for each individual sites. It will definitely help you "bring down sites one at a time without influencing each other". With apache httpd configuration which I will explain in the next section, you can also run the each site on separate machines (physical or vm).
For 2. In you case, you just need to configure apache httpd to do virtual host and use ajp to connect to tomcat.
<VirtualHost *:80>
ServerName www.oursite.com
ProxyPass / ajp://tomcat.oursite.com:8009/www retry=5
ProxyPassReverse / ajp://tomcat.oursite.com:8009/www
</VirtualHost>
<VirtualHost *:80>
ServerName test.oursite.com
ProxyPass / ajp://tomcat.oursite.com:8010/test retry=5
ProxyPassReverse / ajp://tomcat.oursite:8010/test
</VirtualHost>
In the above configuration, you need to configure DNS entries of both www.yoursite.com and test.yoursite.com to point to the same host. It also assume you run both your www and test webapps on different tomcat instances on the same host tomcat.oursite.com, one on ajp port 8009 and the other one on ajp port 8010. You can also change it to a different server of its own. It's very flexible. FYI, following is how to configure ajp in tomcat: http://tomcat.apache.org/tomcat-6.0-doc/config/ajp.html
I found a problem with the apache mod_proxy_ajp connector in such a configuration, it absolutely won't allow you to use any other port when setting up multiple virtual hosts each with its own tomcat instance.
Having spent some time ruling out port conflicts, tomcat configuration issues, firewall issues I have concluded that ProxyPass and ProxyPassReverse will not work when using any port other than 8009 by default.
The solution is likely to be to switch to mod_jk, which also solves problems seen in mod_proxy_ajp with basic configurations not loading or rewriting urls embedded within tomcat hosted pages without extensive configuration changes if the tomcat instance is rooted to a subdirectory. This doesn't seem to happen with Mod_Jk

Apache/Tomcat error - wrong pages being delivered

This error has been driving me nuts. We have a server running Apache and Tomcat, serving multiple different sites. Normally the server runs fine, but sometimes an error happens where people are served the wrong page - the page that somebody else requested!
Clues:
The pages being delivered are those that another user requested recently, and are otherwise delivered correctly. It's been known for two simultaneous requests to be swapped. As far as I can tell, none of the pages being incorrectly delivered are older than a few minutes.
It only affects the files that are being served by Tomcat. Static files like images are unaffected.
It doesn't happen all the time. When it does happen, it happens for everybody.
It seems to happen at times of peak demand. However, the demand is not yet very high - it's certainly well within the bounds of what Apache can cope with.
Restarting Tomcat fixed it, but only for a few minutes. Restarting Apache fixed it, but only for a few minutes.
The server is running Apache 2 and Tomcat 6, using a Java 6 VM on Gentoo. The connection is with AJP13, and JkMount directives within <VirtualHost> blocks are correct.
There's nothing of use in any of the log files.
Further information:
Apache does not have any form of caching turned on. All the caching-related entries in httpd.conf and related imports say, for example:
<IfDefine CACHE>
LoadModule cache_module modules/mod_cache.so
</IfDefine>
While the options for Apache don't include that flag:
APACHE2_OPTS="-D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -D JK"
Tomcat likewise has no caching options switched on, that I can find.
toolkit's suggestion was good, but not appropriate in this case. What leads me to believe that the error can't be within my own code is that it isn't simply a few values that are being transferred - it's the entire request, including the URL, parameters, session cookies, the whole thing. People are getting pages back saying "You are logged in as John", when they clearly aren't.
Update:
Based on suggestions from several people, I'm going to add the following HTTP headers to Tomcat-served pages to disable all forms of caching:
Cache-Control: no-store
Vary: *
Hopefully these headers will be respected not just by Apache, but also by any other caches or proxies that may be in the way. Unfortunately I have no way of deliberately reproducing this error, so I'm just going to have to wait and see if it turns up again.
I notice that the following headers are being included - could they be related in any way?
Connection: Keep-Alive
Keep-Alive: timeout=5, max=66
Update:
Apparently this happened again while I was asleep, but has stopped happening now I'm awake to see it. Again, there's nothing useful in the logs that I can see, so I have no clues to what was actually happening or how to prevent it.
Is there any extra information I can put in Apache or Tomcat's logs to make this easier to diagnose?
Update:
Since this has happened again a couple of times, we've changed how Apache connects to Tomcat to see if it affects things. We were using mod_jk with a directive like this:
JkMount /portal ajp13
We've switched now to using mod_proxy_ajp, like so:
ProxyPass /portal ajp://localhost:8009/portal
We'll see if it makes any difference. This error was always annoyingly unpredictable, so we can never definitively say if it's worked or not.
Update:
We just got the error briefly on a site that was left using mod_jk, while a sister site on the same server using mod_proxy_ajp didn't show the error. This doesn't prove anything, but it does provide evidence that swithing to mod_proxy_ajp may have helped.
Update:
We just got the error again last night on a site using mod_proxy_ajp, so clearly that hasn't solved it - mod_jk wasn't the source of the problem. I'm going to try the anonymous suggestion of turning off persistent connections:
KeepAlive Off
If that fails as well, I'm going to be desperate enough to start investigating GlassFish.
Update:
Dammit! The problem just came back. I hadn't seen it in a while, so I was starting to think we'd finally sorted it. I hate heisenbugs.
Could it be the thread-safety of your servlets?
Do your servlets store any information in instance members.
For example, something as simple as the following may cause thread-related issues:
public class MyServlet ... {
private String action;
public void doGet(...) {
action = request.getParameter("action");
processAction(response);
}
public void processAction(...) {
if (action.equals("foo")) {
// send foo page
} else if (action.equals("bar")) {
// send bar page
}
}
}
Because the serlvet is accessed by multiple threads, there is no guarantee that the action instance member will not be clobbered by someone elses request, and end up sending the wrong page back.
The simple solution to this issue is to use local variables insead of instance members:
public class MyServlet ... {
public void doGet(...) {
String action = request.getParameter("action");
processAction(action, response);
}
public void processAction(...) {
if (action.equals("foo")) {
// send foo page
} else if (action.equals("bar")) {
// send bar page
}
}
}
Note: this extends to JavaServer Pages too, if you were dispatching to them for your views?
Check if your headers allow caching without the correct Vary HTTP header (if you use session cookies, for instance, and allow caching, you need an entry in the Vary HTTP header for the cookie header, or a cache/proxy might serve the cached version of a page intended for one user to another user).
The problem might be not with caching on your web server, but on another layer of caching (either on a reverse proxy in front of your web server, or on a proxy near the users). If the clients are behing a NAT, they might also be behind a transparent proxy (and, to make things even harder to debug, the transparent proxy might be configured to not be visible in the headers).
8 updates of the question later one more issue to use to test/reproduce, albeit it might be difficult (or expensive) for public sites.
You could enable https on the sites. This would at least wipe out any other proxies caches along the way. It'd be bad to see that there are some forgotten loadbalancers or company caches on the way that interfere with your traffic.
For public sites this would imply trusted certificates on the keys, so some money will be involved. For testing self-signed keys might suffice. Also, check that there's no transparent proxy involved that decrypts and reencrypts the traffic. (they are easily detectable, as they can't use the same certificate/key as the original server)
Although you did mention mod_cache was not enabled in your setup, for others who may have encountered the same issue with mod_cache enabled (even on static contents), the solution is to make sure the following directive is enabled on the Set-Cookie HTTP header:
CacheIgnoreHeaders Set-Cookie
The reason being mod_cache will cache the Set-Cookie header that may get served to other users. This would then leak session ID from the user who last filled the cache to another.
I had this problem and it really drove me nuts. I dont know why, but I solved it turning off the Keep Alive on the http.conf
from
KeepAlive On
to
KeepAlive Off
My application doesn't use the keepalive feature, so it worked very well for me.
Try this:
response.setHeader("Cache-Control", "no-cache"); //HTTP 1.1
response.setHeader("Pragma", "no-cache"); //HTTP 1.0
response.setDateHeader("Expires", 0); //prevents caching at the proxy server
Have a look at this site, it describes an issue with mod_jk. I came accross your posting while looking at a very similar issue. Basically the fix is to upgrade to a newer version of mod_jk. I haven't had a chance to implement the change in our server yet, but I'm going to try this tomorrow and see if it helps.
http://securitytracker.com/alerts/2009/Apr/1022001.html
I'm no expert, but could it be some weird Network Address Translation issue?
We switched Apache from proxying with AJP to proxying with HTTP. So far it appears to have solved the issue, or at least vastly reduced it - the problem hasn't been reported in months, and the app's use has increased since then.
The change is in Apache's httpd.conf. Having started with mod_jk:
JkMount /portal ajp13
We switched to mod_proxy_ajp:
ProxyPass /portal ajp://localhost:8009/portal
Then finally to straight mod_proxy:
ProxyPass /portal http://localhost:8080/portal
You'll need to make sure Tomcat is set up to serve HTTP on port 8080. And remember that if you're serving /, you need to include / on both sides of the proxy or it starts crying:
ProxyPass / http://localhost:8080/
It may be not a caching issue at all. Try to increase MaxClients parameter in apache2.conf. If it is too low (150 by default?), Apache starts to queue requests. When it decides to serve queued request via mod_proxy it pulls out a wrong page (or may be it is just stressed doing all the queuing).
Are you sure that is the page that somebody else requested or a page without parameters?,
you could get weird errors if your connectionTimeout is too short at server.xml on the tomcat server behind apache, increase it to a bigger number:
default configuration:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
changed:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="2000000"
redirectPort="8443" />