这个错误一直让我发疯。我们有一台运行 Apache 和 Tomcat 的服务器,为多个不同的站点提供服务。通常服务器运行良好,但有时会在为人们提供错误页面的地方发生错误 -其他人请求的页面!
线索:
- 正在传递的页面是其他用户最近请求的页面,否则会正确传递。众所周知,两个同时请求被交换。据我所知,错误传递的页面都没有超过几分钟。
- 它只影响 Tomcat 提供的文件。图像等静态文件不受影响。
- 它不会一直发生。当它发生时,它会发生在每个人身上。
- 它似乎发生在需求高峰期。然而,需求还不是很高——它肯定在 Apache 可以应付的范围内。
- 重新启动 Tomcat 修复它,但只有几分钟。重新启动 Apache 修复了它,但只有几分钟。
- 服务器运行 Apache 2 和 Tomcat 6,在 Gentoo 上使用 Java 6 VM。与 AJP13 的连接,块
JkMount
内的指令<VirtualHost>
是正确的。 - 任何日志文件都没有任何用处。
更多的信息:
Apache 没有开启任何形式的缓存。httpd.conf 和相关导入中所有与缓存相关的条目都说,例如:
<IfDefine CACHE>
LoadModule cache_module modules/mod_cache.so
</IfDefine>
虽然 Apache 的选项不包括该标志:
APACHE2_OPTS="-D DEFAULT_VHOST -D INFO -D LANGUAGE -D SSL -D SSL_DEFAULT_VHOST -D PHP5 -D JK"
Tomcat 同样没有打开缓存选项,我可以找到。
工具包的建议很好,但在这种情况下不合适。是什么让我相信错误不可能出现在我自己的代码中,因为它不仅仅是正在传输的几个值 - 它是整个请求,包括 URL、参数、会话 cookie 等等。人们正在返回显示“您以 John 身份登录”的页面,而他们显然不是。
更新:
根据几个人的建议,我将向 Tomcat 服务的页面添加以下 HTTP 标头以禁用所有形式的缓存:
Cache-Control: no-store
Vary: *
希望这些标头不仅会受到 Apache 的尊重,而且还会受到任何其他可能阻碍的缓存或代理的尊重。不幸的是,我没有办法故意重现这个错误,所以我只能等着看它是否会再次出现。
我注意到包含以下标题 - 它们可以以任何方式相关吗?
Connection: Keep-Alive
Keep-Alive: timeout=5, max=66
更新:
显然这在我睡着的时候又发生了,但现在已经停止发生了,我醒着看到它。同样,我可以看到日志中没有任何有用的信息,因此我不知道实际发生了什么或如何防止它。
是否有任何额外的信息可以放入 Apache 或 Tomcat 的日志中以使其更易于诊断?
更新:
由于这种情况再次发生了几次,我们改变了 Apache 连接到 Tomcat 的方式,看看它是否会影响事情。我们使用mod_jk
这样的指令:
JkMount /portal ajp13
我们现在切换到 using mod_proxy_ajp
,如下所示:
ProxyPass /portal ajp://localhost:8009/portal
我们会看看它是否有什么不同。这个错误总是令人讨厌地不可预测,所以我们永远无法确定它是否有效。
更新:
我们刚刚在使用 的站点上短暂收到错误mod_jk
,而同一服务器上使用的姊妹站点mod_proxy_ajp
没有显示错误。这并不能证明什么,但它确实提供了证据表明切换到mod_proxy_ajp
可能有所帮助。
更新:
我们昨晚在使用 的网站上再次遇到错误mod_proxy_ajp
,很明显这并没有解决它 -mod_jk
不是问题的根源。我将尝试关闭持久连接的匿名建议:
KeepAlive Off
如果这也失败了,我会绝望地开始调查 GlassFish。
更新:
该死!问题刚刚回来。我有一段时间没看到它了,所以我开始认为我们终于把它整理好了。我讨厌海森虫。