简单比较Apache+Tomcat的mod_jk和mod_proxy方法

这几天服务上线。由于80端口还需要blog和wiki两个服务,所以把80给了Apache管理,然后再通过apache连接后面8080的Tomcat。
Apache+Tomcat主要有三种办法实现: mod_jk, mod_proxy和ajp_proxy。mod_jk是比较专门针对Tomcat的方法,通过AJP协议连接Tomcat,mod_proxy不止可以连接Tomcat,只要是HTTP应用都可以进行反向代理。ajp_proxy不是很清楚,具体参见这里
我前后碰到过三种不同的配置环境。第一次是搭建试验服务的时候,服务搭建在一台内网机器上,通过外网机器的8080端口映射内网的80端口进行访问。由于可对外暴露的端口只有被映射的一个80端口,自然把Apache推了上去。使用mod_proxy进行反向代理配置。后来上面要求搭建两个运行实例,于是开了两份Tomcat,配了两份的proxy。一个在18080,一个在28080。

ProxyPass /app http://localhost:18080/app
ProxyPassReverse /app http://localhost:18080/app
ProxyPass /app2 http://localhost:28080/app2
ProxyPassReverse /app2 http://localhost:28080/app2
第二次的环境并不是Apache+Tomcat,而是IIS+Tomcat。对IIS的不熟悉让我一段时间之内挠破了头。IIS上我没有找到比较实用的mod_proxy组件,特别是使用ISAPI的mod_proxy。而另外一个重大变化在需求上,这次要求服务支持SaaS,而我们服务的SaaS通过访问的域名来区别不同的租户。比如通过abc.example.com和def.example.com访问的用户,虽然使用的是同一个应用,但是却在不同的租户空间内进行操作。
可行的办法是使用ISAPI Rewrite。ISAPI Rewrite事实上是提供Proxy功能的,但那是收费版本。免费的Lite版本只有URL Rewrite的功能。我只好彻底放弃了Proxy的打算,对用户做重定向。比如访问http://abc.example.com的用户将被重定向到http://abc.exmaple.com:8080/app。对于wiki和blog这些访问,在配置文件中当作例外处理。以下是配置文件:
RewriteCond %{HTTP:Host} example\.com$
RewriteCond %{HTTP:Host} !www\.example\.com$
RewriteCond %{HTTP:Host} !wiki\.example\.com$
RewriteCond %{HTTP:Host} !blog\.example\.com$
RewriteRule app/(.*) http://%{HTTP:Host}\:8080/app/$1 [NC,R=301]
RewriteCond %{HTTP:Host} example\.com$
RewriteCond %{HTTP:Host} !www\.example\.com$
RewriteCond %{HTTP:Host} !wiki\.example\.com$
RewriteCond %{HTTP:Host} !blog\.example\.com$
RewriteRule (.*) http://%{HTTP:Host}\:8080/app [NC,R=301]
RewriteCond %{HTTP:Host} www\.example\.com$
RewriteRule ^/$ http://%{HTTP:Host}/app/index.htm [NC,R=301]
RewriteCond %{HTTP:Host} wiki\.example\.com$
RewriteRule ^/(.*)$ http://www.example.com/wiki/$1
RewriteCond %{HTTP:Host} blog\.example\.com$
RewriteRule ^/(.*)$ http://www.example.com/blog/$1
第三次,经过争取,服务器的80端口让位于Apache。当我打算切回第一次的mod_proxy配置时,却发现一个致命的问题:Request里Host的内容已经被mod_proxy修改成了配置文件里的localhost,没有反映用户真实请求里的abc.example.com或者def.example.com。况且系统还要求支持实时添加租户,即在不重启系统的情况下增加新的*.example.com的访问。
mod_proxy虽然能对后台任何的HTTP服务做反向代理,却把泛域名访问给挡在了门边。另外我也终于明白了为什么试验服务器上的Tomcat访问日志里,来源都是127.0.0.1——因为来源都是Apache这个代理。
mod_jk的配置里,虽然仍然需要输入Tomcat的Host,但是似乎AJP协议的保留了前台访问的域名(后台程序通过request.getServerName()获得)。而客户端的IP地址也被成功的记录下来。有兴趣的同学们可以参见AJP 1.3的协议参考。mod_jk的配置就不贴出来了,具体可以看开头介绍proxy_ajp的那个链接

One thought on “简单比较Apache+Tomcat的mod_jk和mod_proxy方法”

Leave a Reply to goodtiger Cancel reply

Your email address will not be published. Required fields are marked *