问题描述
我想做什么
我想运行 Apache httpd (2.4.x) 作为 Apache tomcat (9.0.x) 和 Elasticsearch 服务器的前端。
例如,用户应该看到
http://localhost/tomcat/
内部转发到
http://localhost:8080/
例如
http://localhost/tomcat/manager/status
(由 httpd 外部提供)
取自
http://localhost:8080/manager/status
(内部来自 Tomcat)
我做了什么
mod_proxy、mod_proxy_http、mod_rewrite 被激活。
在 httpd.conf 中我添加了
ProxyPass /tomcat http://localhost:8080
ProxyPassReverse /tomcat http://localhost:8080
或者替代
<Location "/tomcat">
ProxyPass http://localhost:8080/
ProxyPassReverse http://localhost:8080/
</Location>
什么不起作用
http://localhost/tomcat/
正确提供预期页面。但是,该页面上的链接不会调整为新的基本 URL。
例如,页面包含
<a href="/docs/">Documentation</a>
点击该链接转到
应该去http://localhost/tomcat/docs
但指向http://localhost/docs
请注意,如果可能,我想在 Apache httpd 端使用解决方案(而不是重新配置 Tomcat),因为稍后我想对 Elasticsearch 后端使用相同的机制。
另一个小问题
省略尾部斜杠时
http://localhost/tomcat
转发适用于 HTML 页面本身,但不适用于嵌入的资源,例如,Tomcat 徽标应检索为
http://localhost/tomcat/tomcat.svg
-> http://localhost:8080/tomcat.svg
而是指向
http://localhost/tomcat.svg
未翻译,因为它不再与位置模式匹配。
解决方法
但是,该页面上的链接不会调整为新的基本 URL。
这是您配置中的主要问题:Web 应用程序通常生成绝对 URI 路径,如 /manager/images/tomcat.svg
,而不是相对 URI 路径,如 images/tomcat.svg
。它们使用 HttpServletRequest#getContextPath
检索部署路径 (/manager
)。他们无法知道自己正在从另一条路径代理。
这就是为什么 Web 应用程序的原始 URL 和代理 URL 应该保持相同的 URI 路径的原因。在您的情况下,您应该在 /tomcat/manager
部署 Tomcat 管理器。这可以通过多种方式完成:
- 如果您的 Tomcat Manager 应用程序位于
<Host>
的应用程序库 ($CATALINA_BASE/webapps
) 中,请将目录重命名为tomcat#manager
(这通常发生在 Windows ), - 如果您的 Tomcat 管理器应用程序在
<Host>
的应用程序基础之外,请将上下文文件(在$CATALINA_BASE/conf/Catalina/<host_name>
中)从manager.xml
重命名为 {{ 1}}(这发生在像 Debian 这样的 Linux 发行版中), - 如果您在
tomcat#manager.xml
中定义应用程序上下文(不推荐),您可以使用server.xml
元素的path
属性。
数字符号 <Context>
将转换为 #
。
在 Apache 方面将 /
指令更改为:
ProxyPass