我现在正犹豫是否要使用 mod_jk 还是 mod_proxy 来使用 Apache 2 和 Tomcat 7 设置负载平衡系统。我读到过常见的比较,比如 mod_jk 功能更强大但配置起来更难,等等,但我读到的都有些过时了(2007-2010),根据我目前的需求,我可以选择任意一种方式。
现在查看 Tomcat 7 文档连接器!我发现他们基本上弃用了除 mod_proxy 之外的所有内容:
其他支持 AJP 的本机连接器可能有效,但不再受支持。
那么这是否意味着新用途应该采用 mod_proxy?
答案1
mod_proxy 是 Apache HTTP 服务器模块,而不是 Apache Tomcat 模块。
该页面说明的是,Tomcat 支持 JK1.2 或 Apache HTTP 中的 mod_proxy 模块提供的 AJP 协议。
过去,您需要使用 mod_jk 为 Apache HTTP 服务器提供 AJP1.3 支持,从 Apache HTTP 2.2 开始,mod_proxy 模块中提供了此功能 - 请参阅http://httpd.apache.org/docs/2.2/mod/mod_proxy.html其中指出:
此模块为 Apache 实现代理/网关。它为 AJP13(Apache JServe 协议版本 1.3)、FTP、CONNECT(用于 SSL)、HTTP/0.9、HTTP/1.0 和 HTTP/1.1 实现代理功能。
这给你几个选择:
- 使用 Tomcat 中的 HTTP 连接器并让最终客户端直接连接到该连接器。
- 使用 Tomcat 中的 HTTP 连接器并通过 HTTP mod_proxy HTTP 代理功能进行代理。
- 使用 Tomcat 中的 AJP1.3 连接器并通过 HTTP mod_proxy AJP 代理功能代理它。
- 使用 Tomcat 中的 AJP1.2 连接器,并使用 Apache 中的 HTTP mod_jk AJP 模块连接到该连接器。
我的建议是选择选项 3。
有关在 Apache 中配置此功能的具体信息页面是http://httpd.apache.org/docs/2.2/mod/mod_proxy_ajp.html
答案2
多年来,已经开发了许多连接器,使 Apache httpd 能够与使用各种协议的 Tomcat 进行通信。在网络上搜索有关如何执行此操作的信息时,偶然发现一些非常糟糕且过时的建议并不罕见。因此,首先您应该考虑的唯一选项是:
- mod_jk
- mod_proxy_http
- mod_proxy_ajp
所有其他选项都已多年不受支持,因此您应该避免使用 mod_jk2、mod_jserv、mod_webapp 以及此处未讨论的任何其他模块。上述三个选项目前均受支持,并且都在积极开发中。
我为 $work 的客户提供支持的经验是,如今典型客户遇到 mod_proxy_ajp 中的错误的可能性并不比遇到 mod_jk 或 mod_proxy_http 中错误的可能性大。(几年前 mod_proxy_ajp 还不那么成熟,但现在我看不出有什么区别。)
这给我们带来了一个关键问题:HTTP(mod_proxy_http)还是 AJP(mod_proxy_ajp 或 mod_jk)?答案是什么?视情况而定!两种协议都有各自的优点和缺点。哪种协议适合您取决于您的情况。通常影响此选择的因素包括:
- 是否已有一个协议/模块被使用?
- httpd和Tomcat之间的通信需要加密吗?
- httpd 终端是否支持 SSL,但是需要将 SSL 信息传递给 Tomcat?
如果您已经在使用 mod_jk、mod_proxy_http 或 mod_proxy_ajp,并且它们满足您的所有要求,那么就没有必要更改它们。最好坚持使用您当前正在使用的方法,并在您的 httpd 实例之间保持一致。
如果您需要加密 httpd 和 Tomcat 之间的通信,那么使用 mod_proxy_http 会容易得多,因为您只需从 http 切换到 https 协议即可。mod_jk 和 mod_proxy_ajp 使用不支持加密的 AJP 协议,因此您必须通过 SSH 隧道、IPSec 或类似方式单独实现加密。这会给 httpd-Tomcat 通信通道增加显著的配置复杂性。
httpd 终止 SSL,只要 SSL 属性已公开(两个简单的指令),mod_jk 和 mod_proxy_ajp 就会自动将此信息传递给 Tomcat,Tomcat 无需任何额外配置即可将其提供给 Web 应用程序。要使用 mod_proxy_http 实现相同的结果,需要配置 httpd 以将 SSL 信息添加为 http 标头,并且需要在 Tomcat 中配置 Valve 以提取此信息并将其提供给 Web 应用程序。因此,使用 mod_proxy_http 向 Tomcat 提供 SSL 信息会稍微复杂一些。
mod_jk 和 mod_proxy_* 的配置风格也大不相同。mod_proxy_* 指令与其他 httpd 指令一致,而 mod_jk 使用外部属性文件。对于熟悉 httpd 的系统管理员来说,mod_jk 方法可能看起来有点奇怪。
总之:
- 如果需要加密 httpd 到 Tomcat 通道,请使用 mod_proxy_http
- 如果您需要向 Web 应用程序公开 SSL 信息,请使用 mod_jk 或 mod_proxy_ajp
- 如果你已经在使用其中一个模块,那么更换它可能会给你带来更多的麻烦
- 如果可以完全自由地选择,我会使用 mod_proxy_http,因为该配置与其他 httpd 模块更加一致,使用 Wireshark 进行调试稍微容易一些,并且它可以使用 Tomcat 中现有的 HTTP 连接器。
另请参阅我写的演示文稿(http://people.apache.org/~markt/presentations/2012-10-Apache-Tomcat-Reverse-proxies.pdf) 以及 Rainer Jung 对该演讲的补充评论(http://people.apache.org/~markt/presentations/2012-10-Apache-Tomcat-Reverse-proxies-notes-rjung.txt)