原帖地址:http://www.ibm.com/developerworks/cn/opensource/os-lo-apache-tomcat/

關(guān)于作者

 

劉冬,一直使用 J2EE/J2ME 從事移動(dòng)互聯(lián)網(wǎng)方面的開(kāi)發(fā)。您可以通過(guò) Java 自由人網(wǎng)站來(lái)跟他聯(lián)系,網(wǎng)址是:http://www.dlog.cn/javayou ,另外他的郵件地址是javayou@gmail.com



首先我們先介紹一下為什么要讓 Apache 與 Tomcat 之間進(jìn)行連接。事實(shí)上 Tomcat 本身已經(jīng)提供了 HTTP 服務(wù),該服務(wù)默認(rèn)的端口是 8080,裝好 tomcat 后通過(guò) 8080 端口可以直接使用 Tomcat 所運(yùn)行的應(yīng)用程序,你也可以將該端口改為 80。

既然 Tomcat 本身已經(jīng)可以提供這樣的服務(wù),我們?yōu)槭裁催€要引入 Apache 或者其他的一些專門(mén)的 HTTP 服務(wù)器呢?原因有下面幾個(gè):

1. 提升對(duì)靜態(tài)文件的處理性能

2. 利用 Web 服務(wù)器來(lái)做負(fù)載均衡以及容錯(cuò)

3. 無(wú)縫的升級(jí)應(yīng)用程序

這三點(diǎn)對(duì)一個(gè) web 網(wǎng)站來(lái)說(shuō)是非常之重要的,我們希望我們的網(wǎng)站不僅是速度快,而且要穩(wěn)定,不能因?yàn)槟硞€(gè) Tomcat 宕機(jī)或者是升級(jí)程序?qū)е掠脩粼L問(wèn)不了,而能完成這幾個(gè)功能的、最好的 HTTP 服務(wù)器也就只有 apache 的 http server 了,它跟 tomcat 的結(jié)合是最緊密和可靠的。

接下來(lái)我們介紹三種方法將 apache 和 tomcat 整合在一起。

JK

這是最常見(jiàn)的方式,你可以在網(wǎng)上找到很多關(guān)于配置JK的網(wǎng)頁(yè),當(dāng)然最全的還是其官方所提供的文檔。JK 本身有兩個(gè)版本分別是 1 和 2,目前 1 最新的版本是 1.2.19,而版本 2 早已經(jīng)廢棄了,以后不再有新版本的推出了,所以建議你采用版本 1。

JK 是通過(guò) AJP 協(xié)議與 Tomcat 服務(wù)器進(jìn)行通訊的,Tomcat 默認(rèn)的 AJP Connector 的端口是 8009。JK 本身提供了一個(gè)監(jiān)控以及管理的頁(yè)面 jkstatus,通過(guò) jkstatus 可以監(jiān)控 JK 目前的工作狀態(tài)以及對(duì)到 tomcat 的連接進(jìn)行設(shè)置,如下圖所示:


圖 1:監(jiān)控以及管理的頁(yè)面 jkstatus
圖 1:監(jiān)控以及管理的頁(yè)面 jkstatus

在這個(gè)圖中我們可以看到當(dāng)前JK配了兩個(gè)連接分別到 8109 和 8209 端口上,目前 s2 這個(gè)連接是停止?fàn)顟B(tài),而 s1 這個(gè)連接自上次重啟后已經(jīng)處理了 47 萬(wàn)多個(gè)請(qǐng)求,流量達(dá)到 6.2 個(gè) G,最大的并發(fā)數(shù)有 13 等等。我們也可以利用 jkstatus 的管理功能來(lái)切換 JK 到不同的 Tomcat 上,例如將 s2 啟用,并停用 s1,這個(gè)在更新應(yīng)用程序的時(shí)候非常有用,而且整個(gè)切換過(guò)程對(duì)用戶來(lái)說(shuō)是透明的,也就達(dá)到了無(wú)縫升級(jí)的目的。關(guān)于 JK 的配置文章網(wǎng)上已經(jīng)非常多了,這里我們不再詳細(xì)的介紹整個(gè)配置過(guò)程,但我要講一下配置的思路,只要明白了配置的思路,JK 就是一個(gè)非常靈活的組件。

JK 的配置最關(guān)鍵的有三個(gè)文件,分別是

httpd.conf
Apache 服務(wù)器的配置文件,用來(lái)加載 JK 模塊以及指定 JK 配置文件信息

workers.properties
到 Tomcat 服務(wù)器的連接定義文件

uriworkermap.properties
URI 映射文件,用來(lái)指定哪些 URL 由 Tomcat 處理,你也可以直接在 httpd.conf 中配置這些 URI,但是獨(dú)立這些配置的好處是 JK 模塊會(huì)定期更新該文件的內(nèi)容,使得我們修改配置的時(shí)候無(wú)需重新啟動(dòng) Apache 服務(wù)器。

其中第二、三個(gè)配置文件名都可以自定義。下面是一個(gè)典型的 httpd.conf 對(duì) JK 的配置


# (httpd.conf)
            # 加載 mod_jk 模塊
            LoadModule jk_module modules/mod_jk.so
            #
            # Configure mod_jk
            #
            JkWorkersFile conf/workers.properties
            JkMountFile conf/uriworkermap.properties
            JkLogFile logs/mod_jk.log
            JkLogLevel warn
            

接下來(lái)我們?cè)?Apache 的 conf 目錄下新建兩個(gè)文件分別是 workers.properties、uriworkermap.properties。這兩個(gè)文件的內(nèi)容大概如下


#
            # workers.properties
            #
            # list the workers by name
            worker.list=DLOG4J, status
            # localhost server 1
            # ------------------------
            worker.s1.port=8109
            worker.s1.host=localhost
            worker.s1.type=ajp13
            # localhost server 2
            # ------------------------
            worker.s2.port=8209
            worker.s2.host=localhost
            worker.s2.type=ajp13
            worker.s2.stopped=1
            worker.DLOG4J.type=lb
            worker.retries=3
            worker.DLOG4J.balanced_workers=s1, s2
            worker.DLOG4J.sticky_session=1
            worker.status.type=status
            

以上的 workers.properties 配置就是我們前面那個(gè)屏幕抓圖的頁(yè)面所用的配置。首先我們配置了兩個(gè)類型為 ajp13 的 worker 分別是 s1 和 s2,它們指向同一臺(tái)服務(wù)器上運(yùn)行在兩個(gè)不同端口 8109 和 8209 的 Tomcat 上。接下來(lái)我們配置了一個(gè)類型為 lb(也就是負(fù)載均衡的意思)的 worker,它的名字是 DLOG4J,這是一個(gè)邏輯的 worker,它用來(lái)管理前面配置的兩個(gè)物理連接 s1 和 s2。最后還配置了一個(gè)類型為 status 的 worker,這是用來(lái)監(jiān)控 JK 本身的模塊。有了這三個(gè) worker 還不夠,我們還需要告訴 JK,哪些 worker 是可用的,所以就有 worker.list = DLOG4J, status 這行配置。

接下來(lái)便是 URI 的映射配置了,我們需要指定哪些鏈接是由 Tomcat 處理的,哪些是由 Apache 直接處理的,看看下面這個(gè)文件你就能明白其中配置的意義


/*=DLOG4J
            /jkstatus=status
            !/*.gif=DLOG4J
            !/*.jpg=DLOG4J
            !/*.png=DLOG4J
            !/*.css=DLOG4J
            !/*.js=DLOG4J
            !/*.htm=DLOG4J
            !/*.html=DLOG4J
            

相信你已經(jīng)明白了一大半了:所有的請(qǐng)求都由 DLOG4J 這個(gè) worker 進(jìn)行處理,但是有幾個(gè)例外,/jkstatus 請(qǐng)求由 status 這個(gè) worker 處理。另外這個(gè)配置中每一行數(shù)據(jù)前面的感嘆號(hào)是什么意思呢?感嘆號(hào)表示接下來(lái)的 URI 不要由 JK 進(jìn)行處理,也就是 Apache 直接處理所有的圖片、css 文件、js 文件以及靜態(tài) html 文本文件。

通過(guò)對(duì) workers.properties 和 uriworkermap.properties 的配置,可以有各種各樣的組合來(lái)滿足我們前面提出對(duì)一個(gè) web 網(wǎng)站的要求。您不妨動(dòng)手試試!






http_proxy

這是利用 Apache 自帶的 mod_proxy 模塊使用代理技術(shù)來(lái)連接 Tomcat。在配置之前請(qǐng)確保是否使用的是 2.2.x 版本的 Apache 服務(wù)器。因?yàn)?2.2.x 版本對(duì)這個(gè)模塊進(jìn)行了重寫(xiě),大大的增強(qiáng)了其功能和穩(wěn)定性。

http_proxy 模式是基于 HTTP 協(xié)議的代理,因此它要求 Tomcat 必須提供 HTTP 服務(wù),也就是說(shuō)必須啟用 Tomcat 的 HTTP Connector。一個(gè)最簡(jiǎn)單的配置如下


ProxyPass /images !
            ProxyPass /css !
            ProxyPass /js !
            ProxyPass / http://localhost:8080/
            

在這個(gè)配置中,我們把所有 http://localhost 的請(qǐng)求代理到 http://localhost:8080/ ,這也就是 Tomcat 的訪問(wèn)地址,除了 images、css、js 幾個(gè)目錄除外。我們同樣可以利用 mod_proxy 來(lái)做負(fù)載均衡,再看看下面這個(gè)配置


ProxyPass /images !
            ProxyPass /css !
            ProxyPass /js !
            ProxyPass / balancer://example/
            <Proxy balancer://example/>
            BalancerMember http://server1:8080/
            BalancerMember http://server2:8080/
            BalancerMember http://server3:8080/
            </Proxy>
            

配置比 JK 簡(jiǎn)單多了,而且它也可以通過(guò)一個(gè)頁(yè)面來(lái)監(jiān)控集群運(yùn)行的狀態(tài),并做一些簡(jiǎn)單的維護(hù)設(shè)置。


圖 2:監(jiān)控集群運(yùn)行狀態(tài)
圖 2:監(jiān)控集群運(yùn)行狀態(tài)





ajp_proxy

ajp_proxy 連接方式其實(shí)跟 http_proxy 方式一樣,都是由 mod_proxy 所提供的功能。配置也是一樣,只需要把 http:// 換成 ajp:// ,同時(shí)連接的是 Tomcat 的 AJP Connector 所在的端口。上面例子的配置可以改為:


ProxyPass /images !
            ProxyPass /css !
            ProxyPass /js !
            ProxyPass / balancer://example/
            <Proxy balancer://example/>
            BalancerMember ajp://server1:8080/
            BalancerMember ajp://server2:8080/
            BalancerMember ajp://server3:8080/
            </Proxy>
            

采用 proxy 的連接方式,需要在 Apache 上加載所需的模塊,mod_proxy 相關(guān)的模塊有 mod_proxy.so、mod_proxy_connect.so、mod_proxy_http.so、mod_proxy_ftp.so、mod_proxy_ajp.so, 其中 mod_proxy_ajp.so 只在 Apache 2.2.x 中才有。如果是采用 http_proxy 方式則需要加載 mod_proxy.so 和 mod_proxy_http.so;如果是 ajp_proxy 則需要加載 mod_proxy.so 和 mod_proxy_ajp.so這兩個(gè)模塊。





三者比較

相對(duì)于 JK 的連接方式,后兩種在配置上是比較簡(jiǎn)單的,靈活性方面也一點(diǎn)都不遜色。但就穩(wěn)定性而言就不像 JK 這樣久經(jīng)考驗(yàn),畢竟 Apache 2.2.3 推出的時(shí)間并不長(zhǎng),采用這種連接方式的網(wǎng)站還不多,因此,如果是應(yīng)用于關(guān)鍵的互聯(lián)網(wǎng)網(wǎng)站,還是建議采用 JK 的連接方式。