一、為何要集群單臺App Server再強勁,也有其瓶勁,先來看一下下面這個真實的場景。 當時這個工程是這樣的,tomcat這一段被稱為web zone,里面用spring+ws,還裝了一個jboss的規(guī)則引擎Guvnor5.x,全部是ws沒有service layer也沒有dao layer。 然后App Zone這邊是weblogic,傳輸用的是spring rmi,然后App Zone這塊全部是service layer, dao layer和數(shù)據(jù)庫打交道。 用戶這邊用的是.net,以ws和web zone連的。 時間一長,數(shù)據(jù)一多,就出問題了。 拿Loader Runner跑下來,發(fā)覺是Web Zone這塊,App Server已經(jīng)被用到極限了。因為客戶錢不多,所以當時的Web Zone是2臺服務(wù)器,且都是32位的,內(nèi)存不少,有8GB,測試下來后發(fā)覺cpu loader又不高,但是web server這邊的吞吐量始終上不去,且和.net客戶端那邊響應(yīng)越來越慢。 分析了一下原因:單臺tomcat能夠承受的最大負載已經(jīng)到頭了,單臺tomcat的吞吐量就這么點,還要負擔Guvnor的運行,Guvnor內(nèi)有數(shù)百條業(yè)務(wù)規(guī)則要執(zhí)行。 再看了一下其它方面的代碼、SQL調(diào)優(yōu)都已經(jīng)到了極限了,所以最后沒辦法,客戶又不肯拿錢投在內(nèi)存和新機器上或者是再買臺Weblogic,只能取舍一下,搞Tomcat集群了。 二、集群分類Tomcat作集群的邏輯架構(gòu)是上面這樣的一張圖,關(guān)鍵是我們的production環(huán)境還需要規(guī)劃好我們的物理架構(gòu)。 2.1 橫向集群比如說,有兩臺Tomcat,分別運行在2臺物理機上,好處是最大的即CPU擴展,內(nèi)存也擴展了,處理能力也擴展了。 2.2 縱向集群即,兩個Tomcat的實例運行在一臺物理器上,充分利用原有內(nèi)存,CPU未得到擴展。2.3 橫向還是縱向一般來說,廣為人們接受的是橫向擴展的集群,可做大規(guī)模集群布署。但是我們這個case受制于客戶即: ü 不會再投入新機器了 ü 不會增加內(nèi)存了 但是呢,通過壓力測試報告我們可知: ü 原有TomcatServer的CPU Loader不高,在23%左右 ü 原有TomcatServer上有8GB內(nèi)存,而且是32位的,單臺Tomcat只使用了1800MB左右的內(nèi)存 ü 網(wǎng)絡(luò)流量不高,單塊千兆以太網(wǎng)卡完全可以處理掉 因此,我們只能做熊掌與魚不能兼得的事,即采用了:縱向集群。 2.4 Load Balance與High Availableü Load Balance 簡稱LB即負載均衡,相當于1000根線程每個集群節(jié)點:Node負責(zé)處理500個,這樣的效率是最高的。 ü High Available 簡稱HA即高可用性,相當于1000根線程還是交給一臺機器去慢慢處理,如果這臺機器崩了,另一臺機器頂上。 三、集群架構(gòu)中需要解決的問題集群規(guī)劃好了怎么分,這不等于就可以開始實現(xiàn)集群了,一旦你的系統(tǒng)實現(xiàn)了集群,隨之而來的問題就會出現(xiàn)了。 我們原有系統(tǒng)中有這樣幾個問題,在集群環(huán)境中是需要解決的,來看: 3.1 解決上傳文件同步的問題集群后就是兩個Tomcat了,即和兩個線程讀同一個resource的問題是一樣的,還好,我們原有上傳文件是專門有一臺文件伺服器的,這個問題不大,兩個tomcat都往一臺file server里上傳,文件伺服器已經(jīng)幫我們解決了同名文件沖突的這個問題了,如果原先的做法是把文件上傳到Tomcat的目錄中,那問題就大了,來看: 集群環(huán)境中,對于用戶來說一切操作都是透明的,他也不知道我有幾個Tomcat的實例運行在那邊。 用戶一點上傳,可能上傳到了Tomcat2中,但是下次要顯示這個文件時,可能用到的是Tomcat1內(nèi)的jsp或者是class,對不對? 于是,因為你把圖片存在了Tomcat的目錄中,因此導(dǎo)致了Tomcat1在顯示圖片時,取不到Tomcat2目錄中存放的圖片。 因此我們在工程一開始就強調(diào)存圖片時要用一臺專門的文件服務(wù)器或者是FTP服務(wù)器來存,就是為了避免將來出現(xiàn)這樣的問題。 3.2 解決Quartz在集群環(huán)境中的同步問題我們的系統(tǒng)用到一個Quartz(一個定時服務(wù)組件)來定時觸發(fā)一些自動機制,現(xiàn)在有了兩個Tomcat,粗想想每個Tomcat里運行自己的Quartz不就行了? 但是問題來了,如果兩個Quartz在同一時間都觸發(fā)了處理同一條定單,即該條定單會被處理兩邊。。。這不是影響效率和增加出錯機率了嗎? 因為本身Quartz所承受的壓力幾乎可以忽略不計的,它只是定時會觸發(fā)腳本去運行,關(guān)鍵在于這個定時腳本的同步性,一致性的問題上。 我們曾想過的解決方法: 我們可以讓一個Tomcat布署Quartz,另一個Tomcat里不布署Quartz 但這樣做的結(jié)果就是如果布署Quartz的這個Tomcat崩潰掉了,這個Quartz是不是也崩啦? 最后解決的辦法: 所以我們還是必須在兩臺Tomcat里布署Quartz,然后使用HA的原則,即一個Quartz在運行時,另一臺Quartz在監(jiān)視著,并且不斷的和另一個Quartz之間保持勾通,一旦運行著的Quartz崩掉了,另一個Quartz在指定的秒數(shù)內(nèi)起來接替原有的Quartz繼續(xù)運行,對于Quartz,我們同樣也是面臨著一個熊掌與魚不能皆得的問題了,Quartz本身是支持集群的,而它支持的集群方式正是HA,和我們想的是一致的。 具體Quartz是如何在集群環(huán)境下作布署的,請見我的另一篇文章:quartz在集群環(huán)境下的最終解決方案 解決了上述的問題后基本我們可以開始布署Tomcat這個集群了。
四、布署Tomcat集群準備兩個版本一致的Tomcat,分別起名為tomcat1,tomcat2。 4.1 Apache中的配置2 worker.properties文件內(nèi)容的修改 打開Apache HttpServer中的apache安裝目錄/conf/work.properties文件,大家還記得這個文件嗎? 這是原有文件內(nèi)容:
現(xiàn)在開始改動成下面這樣的內(nèi)容(把原有的worker.properties中的內(nèi)容前面都加上#注釋掉):
上面的這些設(shè)置的意思用中文來表達就是: ü 兩個tomcat,都位于localhost ü 兩個tomcat,tomcat1用8009,tomcat2用9009與apache保持jk_mod的通訊 ü 不采用sticky_session的機制 sticky_session即:假設(shè)現(xiàn)在用戶正連著tomcat1,而tomcat1崩了,那么此時它的session應(yīng)該被復(fù)制到tomcat2上,由tomcat2繼續(xù)負責(zé)該用戶的操作,這就是load balance,此時這個用戶因該可以繼續(xù)操作。 如果你的sticky_session設(shè)成了1,那么當你連的這臺tomcat崩了后,你的操作因為是sticky(粘)住被指定的集群節(jié)點的,因此你的session是不會被復(fù)制和同步到另一個還存活著的tomcat節(jié)點上的。 ü 兩臺tomcat被分派到的任務(wù)的權(quán)重(lbfactor)為一致 你也可以設(shè)tomcat1 的worker.tomcat2.lbfactor=10,而tomcat2的worker.tomcat2.lbfactor=2,這個值越高,該tomcat節(jié)點被分派到的任務(wù)數(shù)就越多 2 httpd.conf文件內(nèi)容的修改 找到下面這一行:
我們將它注釋掉,因為我們在集群環(huán)境中不打算采用https,如果采用是https也一樣,只是為了減省開銷(很多人都是用自己的開發(fā)電腦在做實驗哦)。
找到原來的“<VirtualHost>”段 改成如下形式:
注意: 原來的JKMount *** 后的 ajp13變成了什么了? controller 4.2 tomcat中的配置可以拿原有的tomcat復(fù)制成另一個tomcat,分別為d:\tomcat, d:\tomcat2。 打開tomcat中的conf目錄中的server.xml,找到下面這行 1)
記得: 一定要把tomcat2中的這邊的”SHUTDOWN”的port改成另一個端口號,兩個tomcat如果是在集群環(huán)境中,此處的端口號絕不能一樣。 2)找到
確保tomcat2中此處的端口不能為8080,我們就使用9090這個端口吧 3)把兩個tomcat中原有的https的配置,整段去除 4)找到
確保tomcat2中這邊的redirectPort為9443 5)找到
改為:
確保tomcat2的server.xml中此處的8009被改成了9009且其它內(nèi)容與上述內(nèi)容一致(redirectPort不要忘了改成9443) 6)找到
改成
同時把tomcat2中此處內(nèi)容改成
7) 在剛才的
的下面與在
之上,在這之間加入如下一大陀的東西:
此處有一個Receiver port=”xxxx”,兩個tomcat中此處的端口號必須唯一,即tomcat中我們使用的是port=4001,那么我們在tomcat2中將使用port=4002 8)把系統(tǒng)環(huán)境變更中的CATALINA_HOME與TOMCAT_HOME這兩個變量去除掉 9)在每個tomcat的webapps目錄下布署同樣的一個工程,在布署工程前先確保你把工程中的WEB-INF\we b.xml文件做了如下的修改,在web.xml文件的最未尾即“</web-app>”這一行前加入如下的一行:
使該工程中的session可以被tomcat的集群節(jié)點進行輪循復(fù)制。 4.3 啟動集群好了,現(xiàn)在啟動tomcat1, 啟動tomcat2(其實無所謂順序的),來看效果: 分別訪問http://localhost:8080/cbbs與http://localhost:9090/cbbs 確保兩個tomcat節(jié)點都起來了,然后此時,我們啟動Apache 然后訪問直接用http://localhost/cbbs不加端口的形式訪問: 用sally/abcdefg登錄,瞧,應(yīng)用起來了。 然后我們拿另一臺物理客戶端,登錄這個web應(yīng)用,我們可以看到: 第一個tomcat正在負責(zé)處理我們第一次登錄的請求。 當有第二個HTTP請求時,另一個tomcat自動開始肩負起我們第二個HTTP請求了,這就是Load Balance。 |
|