我在本地 ubuntu 开发机上有一个网站,其中包含一些 mod 重写规则,我们正尝试使用这些规则强制 Google 和其他机器人索引正确的页面,而不是像它们一直所做的那样使用我们的 ajax 代码片段。虽然规则比下面的代码片段长一点,但通过一次禁用所有内容,我发现即使是最基本的重写也会在生产服务器上失败,但在开发机上运行良好,甚至通过 cUrl 处理 14k 请求的负载测试,也没有问题。我们使用重写是因为 proxypass 在 中不起作用<if>
,并且不能基于 工作%{QUERY_STRING}
。
我们之前使用的ProxyPass:
ProxyPreserveHost on
ProxyPass ajp://127.0.0.1:8009/other/view retry=0
ProxyPassReverse ajp://127.0.0.1:8009/request/view
简单的重写会导致开发环境中 0.3 秒的 mod_proxy 请求在生产环境中花费超过 30 秒的时间:
RewriteRule ^(.*)(/request/view) ajp://localhost:8009/other/view [P]
两台服务器都是ubuntu,使用相同版本的apache:
Server version: Apache/2.4.52 (Ubuntu)
Server built: 2022-06-14T12:30:21
都使用LogLevel warn
我使用 diff 来验证两个文件是否包含相同的重写规则。我检查过它们都加载了相同的模块(dev box 确实加载了一个不在 prod 上的模块,fcgid,但我们反正也不使用 cgi)。我们能想到的唯一值得注意的事情是,dev 是 http,而 prod 是 https。加载上述重写条件和规则时会立即出现此问题,并会恢复到指令ProxyPass
- 它不是基于 tomcat9 的。
我需要有关故障排除的下一步的帮助,谢谢。
答案1
我始终不知道为什么会发生这种情况,但我确实确定这是由于[P]
服务器上的标志(mod_rewrite 转发到 mod_proxy)处理中的错误造成的。以下解决方法与我们更大的重写链兼容:
<location /request/view>
...
# passthrough to reprocess url matching
RewriteRule "/request/view$" "$0/proxy" [PT]
</Location>
#new location that just uses ProxyPass
<Location /request/view/proxy>
ProxyPreserveHost on
ProxyPass ajp://127.0.0.1:8009/other/view retry=0
ProxyPassReverse ajp://127.0.0.1:8009/request/view
</Location>
我怀疑 mod_rewrite 在我们服务器上传递给 mod_proxy 的方式在使用 ssl 时效率非常低。