尝试了多个论坛来查明真相。我希望在这里能得到一些指导:
以下是我正在使用的堆栈:Red Hat Enterprise Linux Server 版本 5.6(Tikanga)Glassfish 3.0.1 上的 Liferay 6.0.6 MySQL 5.0.77 Apache 2.2.3
Liferay 门户为最终用户提供了各种 portlet。静态内容(网页)、静态资源(主要是 1mb - 80mb 大小的 pdf 和 mp3 文件)、文件上传和下载功能(主要是 40-60mb 的 mp3 文件)以及这些 MP3 文件的在线流媒体。
以下是奇怪的最终用户体验:在正常负载下:(20-30)用户上传,下载或流式传输文件,20-30 用户访问静态内容(其中一些是下载),我们看到以下内容:
1) 单击链接会触发下载 MP3 的一部分(该部分长度为几秒钟)。
2)点击链接会触发页面内容的下载而不是渲染。
3) 单击链接会导致页面向最终用户转储二进制数据而不是预期的内容。
4)单击链接将返回 javascript 文件的文本而不是呈现页面。
每次发生都是完全随机的(或看起来如此)。有时有效,有时无效。它似乎与浏览器或客户端操作系统无关。使用 SSL 连接而不是常规 http 时,奇怪的事件似乎发生得更频繁。
Apache 仅充当代理服务器(反向)。它基本上将所有请求传递给 Glassfish。Apache 不提供任何静态内容代理。
我们从头开始重建了整个堆栈,并重新部署了 portlet wars,但问题仍然存在。Liferay 作为单个服务器运行(不是集群)。我们在 Apache 中禁用了 mod_cache。随着服务器负载的增加,问题会更加频繁。今天早上负载很轻,我们几乎没有遇到问题,但网站的使用量会增加,特别是今晚 9 点左右(CST)到周三早上。您可以尝试网站 (http://preview.bsfinternational.org),我预计您在随机点击网站上的链接时可能会遇到其中一种怪异现象(仅在登录时调用 https)。同样,https 似乎加剧了这个问题。
这看起来非常像一个缓存问题,但我不知道从哪里开始剥洋葱。Apache?Liferay?Glassfish?MySQL?甚至 Redhat?我们被难住了,我们发帖到的大多数论坛(LifeRay 和 Glassfish)都很少给出建议。我只是想知道从哪里开始寻找。我知道我们可以有一个 portlet
编辑:在十六进制编辑器中打开文件,这些文件似乎是下载的页面而不是渲染的页面,我们看到前 4000 个字符是“垃圾”,然后看到“HTTP/1.1....”“正常”标头。因此,有些东西正在转储偏移量 4000 以内的乱码字符(在十六进制编辑器中查看时)。也许这是个线索?
EDIT2:4000h 偏移量为 16k (16384)。我认为这是缓存问题,但不知道在哪里可以找到这种大小的缓存设置。我看到 Apache 中提到了 16k LRU 缓存缓冲区,但我知道 Glassfish(或者可能是 Liferay)使用 ehcache。这能引起某些人的想法吗?有什么想法吗?
答案1
找出问题所在的关键是从等式中移除不同的部分 - 或者在无法拦截的地方拦截流量。
例如:
- 您可以尝试不使用 Apache。如果您无法公开访问,您可以尝试通过从防火墙后面访问 glassfish 来重现,同时它也通过 Apache 提供内容 - 或者设置一个与生产系统完全分离的镜像系统并尝试在该系统上重现。另一种选择是使用 wireshark/记录 apache 和 glassfish 之间的流量
- 如果您可以通过这种方式重现(不使用 apache),请在 tomcat 上设置相同的系统,并对其进行负载(可能是人工负载,因为您不想在生产中这样做,可以使用强化等)
- 如果您无法在没有 apache 的情况下进行重现,请剥离 apache 配置 - 消除 gzip,消除(或强制)https,使用 mod_jk 或 mod_proxy 连接 Apache / Glassfish(您目前正在使用的另一个)
由于问题似乎出在 HTTP 方面(生成非法 HTTP 响应),我希望排除数据库作为原因。
还有一些不太技术性的建议:
解决此类问题的另一种通用方法是让别人看一下,而不要告诉他们你已经做了什么 - 只是坐在那里让他们解释他们在看什么,也许你会发现一些你还没有想到或之前没有检查过的东西。
并且,为了欺骗你的大脑:使用不同的计算机或桌子进行测试:改变物理视角来观察系统有时是产生不同想法的好原因。听起来很愚蠢,但有时大脑想要被欺骗。
答案2
所以这就是答案(不是完整的答案,但至少是解决方案)。我们有一个第三方 portlet,它对某些 URL 中含有 \secure 的 URL 强制实施 SSL 连接。我们删除了该 portlet,问题就解决了。
当我有机会检查代码时,我可能能够找出 portlet 中导致问题的原因。但我们已经运行了几个星期,没有遇到任何问题,portlet 肯定是导致问题的原因(据我所知)。