網(wǎng)上關(guān)于 Apache + JK + Tomcat 的集群配置例子很多,按著例子配置下來,基本都能運行,不過,在一些重要的地方卻沒有進一步的說明。這次公司一個產(chǎn)品就是采用 Apache+JK+Tomcat 集群,在整個配置、測試過程中,遇到了許多的問題,經(jīng)過不斷測試、摸索,最后總算是搞定了,性能也達到了預(yù)期的目標。針對網(wǎng)上的例子,感覺有必要再詳細的介紹一下我的配置過程,對一些要特別注意的地方進行補充。

集群有別于分布式的解決方案,它采用的是每臺服務(wù)器運行相同應(yīng)用的策略,由負責(zé)平衡的服務(wù)器進行分流,這對提高整個系統(tǒng)的并發(fā)量及吞吐量是更有效的辦法。而集群對請求的處理又有兩種不同的方式:負載平衡、狀態(tài)復(fù)制 ( 即集群 ) ,狀態(tài)復(fù)制需要在各服務(wù)器間復(fù)制應(yīng)用狀態(tài),而負載平衡則不用,每臺服務(wù)器都是獨立的。實踐證明,在各應(yīng)用服務(wù)器之間不需要狀態(tài)復(fù)制的情況下,負載平衡可以達到性能的線性增長及更高的并發(fā)需求。

對于集群的其它基礎(chǔ)知識,在此就不再做累贅。以下就這次 Apache + JK + Tomcat 的負載平衡配置進行總結(jié),重點關(guān)注整個配置及注意事項。

準備軟件

1、? Tomcat JBoss(本文檔中采用的是JBoss4.0.2/SPAN>);

2、? apache2.0.54/SPAN>是開源的Web服務(wù)器,下載地址為: http://www.apache.org/dist/httpd/binaries/;

3、? mod_jk-1.2.14apache-2.0.54.so 模塊,jkmod_jserv的替代者,它是Tomcat-Apache插件,為ApacheTomcat的連接器,處理TomcatApache之間的通信,在集群配置中充當負載均衡器的作用,當前的最新版本為1.2.15,不過不同JK版本與不同的Apache版本之間的搭配有一些差異,有的甚至配不起來。JK2是符合apache2.x系列的新品,但由于其配置太過麻煩,使用的人很少,所以目前已停止開發(fā),所以我們采用了jk連接器,下載地址:http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/

集群與負載平衡

使用 mod_jk 默認的以輪循方式進行平衡負載,假設(shè)有四個服務(wù)器節(jié)點,有 10 個請求,則四個節(jié)點分別接受請求編號如下:

節(jié)點 1

節(jié)點 2

節(jié)點 3

節(jié)點 4

1

2

3

4

5

6

7

8

9

10

?

?

而集群方式也是使用這種方法進行平衡。 Tomcat 中的集群原理是通過組播的方式進行節(jié)點的查找并使用 TCP 連接進行會話的復(fù)制。

???? 集群不同于負載平衡的是,由于集群服務(wù)需要在處理請求之間不斷地進行會話復(fù)制,復(fù)制后的會話將會慢慢變得龐大,因此它的資源占用率是非常高的,如果在并發(fā)量大的應(yīng)用中,復(fù)制的會話大小會變得相當大,而使用的總內(nèi)存更是會迅速升高。

???? 但集群的會話復(fù)制,增加了系統(tǒng)的高可用性。由于在每臺服務(wù)器都保存有用戶的 Session 信息,如果服務(wù)器群中某臺當機,應(yīng)用可以自動切換到其它服務(wù)器上繼續(xù)運行,而用戶的信息不會丟失,這提高了應(yīng)用的冗錯性。

具體采用負載平衡還是集群,這要看應(yīng)用的需求了。

安裝配置 Apache

1 、下載 Apache 的安裝程序 apache_2.0.54win32-x86-no_ssl.exe 后,安裝很簡單,一路回車,就此略過。

2 、安裝完畢后,將下載的 mod_jk-1.2.14apache-2.0.54.so 復(fù)制到 Apache 安裝目錄下的 modules 子目錄中。

3 、然后進入 Apache 安裝目錄下的 conf 子目錄中,打開 httpd.conf 配置文件,在最后插入以下一行:

Include conf/mod_jk.conf

4、? conf 子目錄下,建立一個新的配置文件: mod_jk.conf ,此文件為 Apache 加載連接器的配置文件,文件名可修改,但要與 httpd.conf Include 的文件名一致,內(nèi)容如下:

# Load mod_jk module. Specify the filename

# of the mod_jk lib you’ve downloaded and

# installed in the previous section

# 加載 mod_jk 模塊

LoadModule jk_module modules/mod_jk-1.2.14apache-2.0.54.so

# Where to find workers.properties

JkWorkersFile conf/workers2.properties

# Where to put jk logs

JkLogFile logs/mod_jk.log

# Set the jk log level [debug/error/info]

JkLogLevel info

# Select the log format

JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

# JkOptions indicate to send SSL KEY SIZE,

JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories

# JkRequestLogFormat set the request format

JkRequestLogFormat "%w %V %T"

# 請求分發(fā)配置,可以配置多項

JkMount /* loadbalancer

# 關(guān)掉主機 Lookup ,如果為 on ,很影響性能,可以有 10 多秒鐘的延遲。
HostnameLookups?Off

注: 藍色加粗的兩行是重點,第一句是 Apache 加載 JK 模塊用的;第二句為配置哪些 URL 請求將由負載平衡器來處理。

5、? conf 子目錄下,建立一個新的配置文件: workers2.properties ,此文件為負載平衡的配置文件,文件名不能修改,這是 JK 默認的名字,內(nèi)容如下:

worker.list=loadbalancer

# Define the first node...

worker.server99.port=8009

worker.server99.host=192.168.11.99

worker.server99.type=ajp13

worker.server99.lbfactor=1

worker.server99.local_worker=1

worker.server99.cachesize=1000

worker.server99.cache_timeout=600

worker.server99.socket_keepalive=1

worker.server99.socket_timeout=0

worker.server99.reclycle_timeout=300

worker.server99.retries=3

# Define the second node...

worker.server202.port=8009

worker.server202.host=192.168.11.202

worker.server202.type=ajp13

worker.server202.lbfactor=1

worker.server202.local_worker=1

worker.server202.cachesize=1000

worker.server202.cache_timeout=600

worker.server202.socket_keepalive=1

worker.server202.socket_timeout=0

worker.server202.reclycle_timeout=300

worker.server202.retries=3

# Now we define the load-balancing behaviour

worker.loadbalancer.type=lb

worker.retries=3

worker.loadbalancer.balance_workers=server99 ,server202

worker.loadbalancer.sticky_session=true

worker.loadbalancer.sticky_session_force=true

注: 以上定義了兩個 worker ,一個為 server99 ,另一個為 server202 ,定義了一個負載平衡服務(wù)器 loadbalancer ,其中標藍色的為重點配置項,相關(guān)的詳細說明可以看官方的網(wǎng)站文檔: http://tomcat.apache.org/connectors-doc/ ,其它節(jié)點的定義可以直接 Copy ,修改一下節(jié)點名及 IP 就好了。
A
、 worker.list=loadbalancer

設(shè)定工作的負載平衡器,各 Tomcat 節(jié)點不能加入此列表。

??? B worker.server99.lbfactor

負載平衡的權(quán)重比,如果此權(quán)重比越大,則分配到此節(jié)點的請求越多,如以上兩個節(jié)點的權(quán)重比為 1:1 ,則為平均分配。

C worker.loadbalancer.balance_workers=server99,server202

?? 指定此負載平衡器負責(zé)的 Tomcat 應(yīng)用節(jié)點。

D 、 worker.loadbalancer.sticky_session=true

?? 此處指定集群是否需要會話復(fù)制,如果設(shè)為 true ,則表明為會話粘性,不進行會話復(fù)制,當某用戶的請求第一次分發(fā)到哪臺 Tomcat 后,后繼的請求會一直分發(fā)到此 Tomcat 服務(wù)器上處理;如果設(shè)為 false ,則表明需求會話復(fù)制。

E 、 worker.loadbalancer.sticky_session_force=true

?? 如果上面的 sticky_session 設(shè)為 true 時,建議此處也設(shè)為 true ,此參數(shù)表明如果集群中某臺 Tomcat 服務(wù)器在多次請求沒有響應(yīng)后,是否將當前的請求,轉(zhuǎn)發(fā)到其它 Tomcat 服務(wù)器上處理;此參數(shù)在 sticky_session=true 時,影響比較大,會導(dǎo)致轉(zhuǎn)發(fā)到其它 Tomcat 服務(wù)器上的請求,找不到原來的 session ,所以如果此時請求中有讀取 session 中某些信息的話,就會導(dǎo)致應(yīng)用的 null 異常。

6 、 Apache 服務(wù)器的配置文件 httpd.conf 中,默認有三個參數(shù)對性能的影響比較大,但根據(jù)不同的性能要求,參數(shù)的表現(xiàn)又不一樣,太小并發(fā)提不上去,太大性能反而不好,建議根據(jù)項目的需要,實際做個測試,如并發(fā)要求 800 的話,可以設(shè)定為:

# 一個連接的最大請求數(shù)量

MaxKeepAliveRequests   1000 (值為 0 ,則不限制數(shù)量)

# 每個進程的線程數(shù),最大 1920 NT 只啟動父子兩個進程,不能設(shè)置啟動多個進程

ThreadsPerChild      1000 (最大為 1920

# 每個子進程能夠處理的最大請求數(shù)

MaxRequestsPerChild?? 1000 (值為 0 ,則不限制數(shù)量)

這三個參數(shù)要根據(jù)不同的需求,不同的服務(wù)器進行調(diào)整。

安裝配置 Tomcat JBoss

1 、對于 Tomcat JBoss 的安裝,這里不做說明,目前我們是采用 Apache+JBoss ,不過, JBoss 也是用的 Tomcat ,所以這里的配置也是適合 Tomcat 的;

2 、對于 JBoss 的配置,很簡單,只需要改兩個地方就可以了:

第一個地方:進入 jboss-4.0.2server\default\deploy\jbossweb-tomcat55.sar ,打開 server.xml ,大約在第 32 行左右,有 ,在其中加入一個參數(shù),變?yōu)椋?/span>

第二個地方:進入 jboss-4.0.2server\default\deploy\jbossweb-tomcat55.sar\META-INF 目錄,打開 jboss-service.xml ,大約在 110 行,有 false/SPAN>,將其改為:

true/SPAN>

這里有一個需要特別注意的地方, JBoss Tomcat 中,關(guān)于 AJP 連接協(xié)議的默認配置,對于大并發(fā)量是不夠用的,要做一些修改,進入 jboss-4.0.2server\default\deploy\jbossweb-tomcat55.sar ,打開 server.xml ,找到 的地方,這里是定義 AJP 連接器的地方,它的配置中沒有 maxThreads 項,默認為 200 ,我們可以做修改:

<="" address="${jboss.bind.address}" port="8009" />

???????? emptySessionPath="true" enableLookups="false" redirectPort="8443"

???????? protocol="AJP/1.3" maxThreads="3000"/>

maxThreads 的值要看你的并發(fā)量多大,設(shè)置太大也不好。

運行

至此,整個配置全部完成,注意一點是,在各 JBoss 節(jié)點,重啟或新增加一個 JBoss 節(jié)點時,需要重新啟動 Apache ,而對于服務(wù)器群中某個 JBoss 節(jié)點 shutdown Apache 會自動偵測,不用重新啟動。

如果在運行過程中,群中的某個 JBoss 節(jié)點 shutdown ,則已登錄到此服務(wù)器上的用戶的請求將出錯,此服務(wù)器負責(zé)的 session 將丟失,但 Apache 會自動偵測到此服務(wù)器已 shutdown ,后繼的新請求將不會再引導(dǎo)到此節(jié)點。

對于負責(zé)請求分發(fā)的 Apache 服務(wù)器,需要消耗大量的 CPU 資源,因此如果在測試過程中出現(xiàn)一些 Service?Temporarily?Unavailable Server??has?shut?down?the?connection?prematurely 這樣的錯誤,這一般都是服務(wù)器配置不夠好引起的,或者是 Apache Tomcat 、及應(yīng)用中的某些配置不夠使用,這時候就要考慮換更好的機器或優(yōu)化應(yīng)用中的配置。

常見問題

一、 cannot?connect?to?server :無法連接到服務(wù)器。這種情況是服務(wù)器的配置有問題,服務(wù)器無法承受過多的并發(fā)連接了,需要優(yōu)化服務(wù)器的配置:

如操作系統(tǒng)采用更高版本,如 windows?2003?server ,

優(yōu)化 tomcat 配置: maxThreads="500"?minSpareThreads="400"?maxSpareThreads="450"

但是 tomcat? 最多支持 500 個并發(fā)訪問

優(yōu)化 apache 配置:

ThreadsPerChild?1900

MaxRequestsPerChild??10000

二、 ?Action.c(10):?Error?-27791:?Server??has?shut?down?the?connection?prematurely

HTTP?Status-Code=503?(Service?Temporarily?Unavailable)
一般都是由于服務(wù)器配置不夠好引起的,需要優(yōu)化硬件和調(diào)整程序了。

三、無法處理請求:

當我們輸入 ?***.do? 命令后, apache 卻返回錯誤信息,而連接 tomcat 卻沒有問題。原因是沒有把 .do 命令轉(zhuǎn)發(fā)給 tomcat 處理。解決方法如下:

apache 配置文件中配置如下內(nèi)容:

JkMount?/*.jsp?loadbalancer

JkMount?/*.do?loadbalancer