【发布时间】:2010-09-19 18:42:42
【问题描述】:
这个错误让我发疯了。我们有一台运行 Apache 和 Tomcat 的服务器,为多个不同的站点提供服务。通常服务器运行良好,但有时会在为人们提供错误页面时发生错误 - 其他人请求的页面!
线索:
- 正在传送的页面是其他用户最近请求的页面,否则会正确传送。众所周知,两个同时请求被交换。据我所知,错误传递的页面都不会超过几分钟。
- 它只影响 Tomcat 服务的文件。图片等静态文件不受影响。
- 它不会一直发生。当它发生时,它会发生在每个人身上。
- 这似乎发生在需求高峰期。但是,需求还不是很高——它肯定在 Apache 可以应付的范围内。
- 重新启动 Tomcat 修复了它,但只维持了几分钟。重新启动 Apache 修复了它,但只有几分钟。
- 服务器正在运行 Apache 2 和 Tomcat 6,在 Gentoo 上使用 Java 6 VM。与 AJP13 的连接,
<VirtualHost>块中的JkMount指令是正确的。 - 任何日志文件都没有任何用处。
更多信息:
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 也没有打开缓存选项,我可以找到。
toolkit's suggestion 很好,但在这种情况下不合适。是什么让我相信错误不可能出现在我自己的代码中,因为它不仅仅是正在传输的几个值 - 它是整个请求,包括 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
我们现在改用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。
更新:
该死!问题刚刚回来。我有一段时间没看到它了,所以我开始认为我们终于把它整理好了。我讨厌海森虫。
【问题讨论】:
-
为了完全消除缓存的可能性,您可以在所有请求前插入一个servlet过滤器,根据mnot.net/cache_docs设置适当的响应头
-
这不是一个坏主意。我还可以向 Apache 添加显式指令,以防止缓存任何相关地址。它可能无法解决任何问题,但它可以做的最糟糕的事情是帮助消除选项。
-
我会倾向于你的应用正在做的事情。日志应该向您显示交换页面的时间。我认为最多的线索将来自于追求交换页面的场景。
-
这当然是我的第一个想法,但我已经多次检查我的代码,但没有找到任何东西。就像我说的,被交换的不仅仅是几个对象,而是整个请求上下文、cookies 等等。
-
马库斯你找到什么了吗?我也面临同样的问题,但只有一次客户用打印屏幕报告过。我正在使用 JDK6、Tomcat 6、Struts 1.0 和磁贴。我无法复制或看到代码中的任何问题。我跟踪了我们的代码完成的日志跟踪,看起来tomcat确实混淆了会话并同时显示了其他用户请求的页面。两者之间不涉及 Apache Web 服务器。