1. 為何要做負載均衡?
一般是對性能和價格比的需要,為了能夠共享應用服務器的計算能力,用戶會采購多個CPU的金蝶阿帕斯應用服務器(Kingdee Apusic Application Server,KAAS)中間件產品,并且安裝到多臺計算機中,然后將多個應用統一部署在這些KAAS之上。
還有就是保護KAAS安全,現在網絡攻擊太嚴重了,因此用戶想把服務器放在防火墻后面,前端放一個Apache服務器或者硬件的負載均衡器,哪怕前端被攻擊,至少可以保證主頁內容不會被篡改。
2. 如何用Apache+Apusic實現LB?
實現前我們需要了解一個概念,LB到底由哪些部分組成,相互之間的關系如何?配置負載均衡需要兩個部分組成:負載均衡器和應用服務器集群。負載均衡器不了解具體業務,只知道有哪些KAAS,然后依據一種分配機制將客戶請求分配給相應的KAAS。而KAAS接到用戶請求,處理完成后就將結果返回給負載均衡器,再返回到客戶端。但是HTTP請求都是無狀態的,如果用戶使用Session機制保存了狀態,那么下次再訪問時可以通過兩種方法處理:
⑴ 利用負載均衡器的會話保持(Session Stick)技術,負載均衡器會記錄SessionID和服務器IP,然后將下次請求仍然轉發到上次處理的服務器上,但是這種方式如果服務器宕機了,就會使客戶丟失信息;
⑵ 利用KAAS的集群功能,將一起工作的服務器配置成集群,相互之間利用會話復制(Session Copy)技術,所有服務器上的會話內容完全相同,請求不需要轉發給相同的服務器就可以得到正確響應,但是這種方式會給網絡帶來較大的負載壓力,甚至引起網絡風暴。
下面分別是這兩種方法的配置過程:
⑴ 配置均衡均衡的會話保持
#httpd.conf(Apache的配置文檔,如果想了解Apache相關配置參數,請看參考文獻)
#載入重要的模塊
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
#設置負載均衡分配用的服務器
<Proxy balancer://apusicBalance>
??? BalancerMember http://1.2.3.4:6888/
??? BalancerMember http://1.2.3.5:6888/
</Proxy>
#設置代理服務器轉發方式,stickysession就是會話保持,JSESSIONID就是Apusic的會話ID,nofailover就是說服務器沒有做集群
ProxyPass / balancer://apusicBalance stickysession=JSESSIONID nofailover=On
ProxyPassReverse / balancer://apusicBalance
⑵ 利用KAAS的集群功能,只提供了WEB模塊Session復制的例子,其它例子請參考Apusic集群管理文檔,在apusic.conf增加的配置如下
<!-- 將應用服務器增加到集群中 -->
<SERVICE
??? CLASS="com.apusic.cluster.ClusterService"
??? >
??? <ATTRIBUTE NAME="ClusterName" VALUE="ApusicCluster"/>
??? <ATTRIBUTE NAME="LoadWeight" VALUE="100"/>
</SERVICE>
<!-- 使WEB容器的Session支持復制 -->
<SERVICE CLASS="com.apusic.servlet.http.session.SessionService">
??? <ATTRIBUTE NAME="DefaultSessionTimeout" VALUE="3600"/>
??? <ATTRIBUTE NAME="MaxSessionsInCache" VALUE="1024"/>
??? <ATTRIBUTE NAME="SessionInvalidateCheckInterval" VALUE="60"/>
??? <ATTRIBUTE NAME="SessionSwapCheckInterval" VALUE="30"/>
??? <ATTRIBUTE NAME="Distributable" VALUE="True"/>
??? <ATTRIBUTE NAME="Replicable" VALUE="True"/>
</SERVICE>
3. 使用Apache實現LB還有哪些功能?
⑴ 支持緩沖。mod_cache模塊。
Sample httpd.conf
#
# Cache配置的例子
# 下面的Cache默認采用disk作為緩存,如果想調整成mem,必須先將disk用#注釋,然后刪除mem的#注釋。
LoadModule cache_module modules/mod_cache.so
LoadModule disk_cache_module modules/mod_disk_cache.so
#LoadModule mem_cache_module modules/mod_mem_cache.so
<IfModule mod_cache.c>
?<IfModule mod_disk_cache.c>
??CacheRoot c:/cacheroot
??CacheEnable disk /
??CacheDirLevels 5
??CacheDirLength 3
?</IfModule>
?<IfModule mod_mem_cache.c>
??CacheEnable mem /
??MCacheSize 4096
??MCacheMaxObjectCount 100
??MCacheMinObjectSize 1
??MCacheMaxObjectSize 2048
?</IfModule>
# 當Apache作為Proxy時,不緩存安全部分的代碼。下面的例子實際使用時請改成應用自身的情況
CacheDisable http://security.update.server/update-list/
</IfModule>
⑵ 不同的分配機制。
除了已經知道的循環分配機制,將請求依次派發給每個應用服務器;還可以通過loadfactor來進行權重分配,事先依據每個應用服務器的計算能力,將請求依據權重分發給服務器;還可以通過lbmethod流量的壓力進行統計,然后將請求分發給服務器。
⑶ 分別在不同的網絡層進行代理,一般可以在四層和七層。
這種方法我沒有進行實驗,待以后補充。
4. 在應用開發階段要注意哪些事情來滿足LB需要?
開發階段需要注意的內容其實很多,主要就是Session復制和資源死鎖的問題。以前項目開發,能夠把功能實現就算是完工了,但是用戶的需求也在增加,特別是J2EE為分布式計算提供了很好的模型,為開發符合LB標準的程序提供了有利的條件,但是在開發階段仍然有些工作必須要做,例如:
⑴ 所有保存在Sesion中的類必須要實現Serialable接口,當然還要把Object實現的方法重載,保證你的類被正確序列化了,但是如果沒有實現,至少保證系統進行Session復制時不會報錯;
⑵ 盡量不要進行長事務操作,盡量不要對數據庫進行表級鎖,盡量把申請得到的資源進行歸還,盡量使用finally保證資源被正確釋放,等等…
⑶ 以后繼續補充
參考文獻:
1. mod_proxy - Apache 2.2 中文版參考手冊,
http://doc.chinahtml.com/Manual/ApacheManual/mod/mod_proxy.html
2. mod_cache - Apache 2.2 中文版參考手冊
http://doc.chinahtml.com/Manual/ApacheManual/mod/mod_cache.html
3. Apusic集群管理文檔
http://infocenter.apusic.com/help/index.jsp?topic=/com.apusic.studio.doc.server/output/eclipse/cluster_management.html