【问题标题】:Correctly setup Tomcat behind Apache with mod_proxy_ajp使用 mod_proxy_ajp 在 Apache 后面正确设置 Tomcat
【发布时间】:2011-03-30 13:09:38
【问题描述】:

我一直在修补 Apache + Tomcat,以便我可以通过 apache(干净且清晰的 url 摇滚)为多个 Tomcat 应用程序(在不同的机器上)提供服务。我已经成功地配置了mod_proxy_ajpmod_rewrite,以至于我可以在不同的机器上为两个tomcat 应用程序提供服务,而几乎没有任何问题。

我发现的唯一问题是其中一个应用程序(我在 Struts2 中开发)有很多链接和表单,它们是使用 <s:a /><s:url /><s:form /> 标签生成的。这些标签生成的url一般是这样的:

/WebApp/path/to/some.action

感谢 ModRewrite 的魔力,这通常不是一个 问题,指向此类 url 的超链接会被快速重写并重定向到 /app/path/to/some.action(尽管我确实收到了大量的 302 回复)。

真正的问题发生在执行 POST 请求时。大家可能都知道,我无法使用 mod_rewrite 重定向 POST 请求......所以最后......我所有的 POST 请求都不起作用,因为 mod_rewrite 重定向到正确的 url 但作为 GET 请求.

我已经阅读了一些关于mod_proxy_html 以及它如何帮助我重写 Tomcat Web 应用程序返回的 url...但感觉很麻烦。

这是我当前的 apache 配置:

## HACKING BEGINS RIGHT HERE

# cookies
ProxyPassReverseCookiePath /WebApp /app
# this is for CSS, IMGs, JS and redirecting urls with /WebApp*
RewriteRule ^/WebApp(.*)$ /app$1 [R,L]
<Location /app>
    ProxyPass ajp://localhost:8009/WebApp
    ProxyPassReverse ajp://localhost:8009/WebApp
    Order allow,deny
    Allow from all
</Location>

# the other app
ProxyPassReverseCookiePath /WebApp2 /other
<Location /other>
    ProxyPass ajp://200.9.4.6:8009/WebApp2
    ProxyPassReverse ajp://200.9.4.6:8009/WebApp2
    Order allow,deny
    Allow from all
</Location>

我的POST请求问题必须有解决方案...有什么想法吗?我可以以某种方式配置一些允许 Struts2 输出正确 url 的东西吗?

感谢您的帮助。

【问题讨论】:

  • 离题。尝试服务器故障。

标签: apache tomcat mod-proxy


【解决方案1】:

可能有几种方法可以解决这个问题。

如果您能够以您在 URL 中使用的相同名称将您的应用程序部署到 Tomcat,那将是最简单的。所以你的应用程序app 将是/webapps/app[.war] 而不是/webapps/WebApp,这将完全避免重写。

否则,以下内容应该有效,并且应该在您当前的重写规则之前进行。 [PT] 应该允许 Apache 仍然代理请求(这在使用 mod_jk 时有效,不确定我是否已使用/测试过 mod_proxy_ajp):

RewriteCond %{REQUEST_METHOD} POST
RewriteRule ^/WebApp(.*)$ /app$1 [PT,L]

一旦您的 bean 处理了 POST 请求,您就可以将请求发送到将被重定向的 URL。最后,POST URL 对用户来说并不重要,所以它不必是一个漂亮的 URL。

编辑如下:

我在 Apache mod_proxy 上看到 ProxyPassReverse 应该与 [PT] 标志一起使用。而且我能够复制您遇到的问题,并且下面的配置适用于我的基本 JSP 页面,其表单发布到另一个 JSP 页面。

<VirtualHost *:80>
    ServerName localhost
    RewriteEngine On

    RewriteCond %{REQUEST_METHOD} !POST
    RewriteRule /WebApp/(.*) /app/$1 [R,L] 

    RewriteCond %{REQUEST_METHOD} POST
    RewriteRule /WebApp/(.*) /app/$1 [PT,L]

    <Location /app>
        ProxyPass ajp://localhost:8109/WebApp
        ProxyPassReverse ajp://localhost:8109/WebApp
    </Location>
</VirtualHost>

【讨论】:

  • 不幸的是......它不起作用......我的POST请求仍然收到302重定向响应。我读到 [PT] 会将请求传递给某些 uri-to-file 映射器...在这种情况下,我没有使用虚拟主机或类似的东西...您认为这会影响规​​则吗?
  • 我一直使用 VirtualHost,即使它只是 localhost,但我认为这在这种情况下并不重要。您是否使用相对路径进行重写?我知道你的例子是,但我想我会问,因为 mod_rewrite 会在更改域的规则上强制执行 302 重定向。
  • 我使用的配置与我在问题中粘贴的相同...无论如何...也许JkMountmod_proxy 的工作方式不同,这就是[PT,L] 的原因为你工作?
  • 我添加了一个对我有用的配置 2 个基本的 JSP 页面,希望它有所帮助,我认为唯一真正的区别是你原来的 RewriteRule 上的 RewriteCond 以及我原来的建议。
  • 嗯...不幸的是,使用您完全相同的配置,一切都像魅力一样工作但是 POST 请求仍然不起作用:(。这些发布请求是针对操作而不是 JSP文件...所以也许那里有区别...谁知道...
【解决方案2】:

这是 webapp 设置的问题;可能有一种方法可以在 httpd 配置中解决它,但是修复原始的不一致而不是围绕它进行破解会更干净。

另外值得一提的是,Struts 正试图通过为您提供上下文感知的非相对 URL 来帮助您;如果您只是使路径匹配,则可以依赖它(而不是与之抗争......)。

因此,只需将 Struts webapp 部署到 /app 和 /other,而不是 /WebApp 和 /WebApp2。 (这可能是出于某种原因——比如你实际上并不控制其他服务器——但听起来这并不适用)。

【讨论】:

    【解决方案3】:

    我会避免 URL 重写。它只是打开像这样的蠕虫罐,让您查看 mod_proxy_html 等,当然这些只是更多的蠕虫。相反,只需将您的应用程序部署在 Tomcat 中,并使用您可以使用的真实 URL,使其在外部可见。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-25
      • 2012-07-01
      • 2014-09-30
      • 2016-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-14
      相关资源
      最近更新 更多