淺談web應用的負載均衡、集羣、高可用(HA)解決方案

  

      聲明:以下僅爲個人的一些總結和隨寫,如有不對之處,還請看到的網友指出,以免誤導。 (詳細的配置方案請google,這裏只說解決方案。)

 

1、熟悉幾個組件

1.1、apache

     —— 它是Apache軟件基金會的一個開放源代碼的跨平臺的網頁服務器,屬於老牌的web服務器了,支持基於Ip或者域名的虛擬主機,支持代理服務器,支持安全Socket層(SSL)等等,目前互聯網主要使用它做靜態資源服務器,也可以做代理服務器轉發請求(如:圖片鏈等),結合tomcat等servlet容器處理jsp。
1.2、ngnix
     —— 俄羅斯人開發的一個高性能的 HTTP和反向代理服務器。由於Nginx 超越 Apache 的高性能和穩定性,使得國內使用 Nginx 作爲 Web 服務器的網站也越來越多,其中包括新浪博客、新浪播客、網易新聞、騰訊網、搜狐博客等門戶網站頻道等,在3w以上的高併發環境下,ngnix處理能力相當於apache的10倍。
     參考:apache和tomcat的性能分析和對比(http://blog.s135.com/nginx_php_v6/)
1.3、lvs
     —— Linux Virtual Server的簡寫,意即Linux虛擬服務器,是一個虛擬的服務器集羣系統。由畢業於國防科技大學的章文嵩博士於1998年5月創立,可以實現LINUX平臺下的簡單負載均衡。瞭解更多,訪問官網:http://zh.linuxvirtualserver.org/。

1.4、HAProxy

     —— HAProxy提供高可用性負載均衡以及基於TCP和HTTP應用的代理,支持虛擬主機,它是免費、快速並且可靠的一種解決方案。HAProxy特別適用於那些負載特大的web站點, 這些站點通常又需要會話保持或七層處理。HAProxy運行在當前的硬件上,完全可以支持數以萬計的併發連接。並且它的運行模式使得它可以很簡單安全的整合進您當前的架構中, 同時可以保護你的web服務器不被暴露到網絡上.
1.5、keepalived
     —— 這裏說的keepalived不是apache或者tomcat等某個組件上的屬性字段,它也是一個組件,可以實現web服務器的高可用(HA high availably)。它可以檢測web服務器的工作狀態,如果該服務器出現故障被檢測到,將其剔除服務器羣中,直至正常工作後,keepalive會自動檢測到並加入到服務器羣裏面。實現主備服務器發生故障時ip瞬時無縫交接。它是LVS集羣節點健康檢測的一個用戶空間守護進程,也是LVS的引導故障轉移模塊(director failover)。Keepalived守護進程可以檢查LVS池的狀態。如果LVS服務器池當中的某一個服務器宕機了。keepalived會通過一 個setsockopt呼叫通知內核將這個節點從LVS拓撲圖中移除。

Keepalived詳解:https://my.oschina.net/piorcn/blog/404644
1.6、memcached
     —— 它是一個高性能分佈式內存對象緩存系統。當初是Danga Interactive爲了LiveJournal快速發展開發的系統,用於對業務查詢數據緩存,減輕數據庫的負載。其守護進程(daemon)是用C寫的,但是客戶端支持幾乎所有語言(客戶端基本上有3種版本[memcache client for java;spymemcached;xMecache]),服務端和客戶端通過簡單的協議通信;在memcached裏面緩存的數據必須序列化。
1.7、terracotta
     —— 是一款由美國Terracotta公司開發的著名開源Java集羣平臺。它在JVM與Java應用之間實現了一個專門處理集羣功能的抽象層,允許用戶在不改變系統代碼的情況下實現java應用的集羣。支持數據的持久化、session的複製以及高可用(HA)。詳細參考:http://topmanopensource.iteye.com/blog/1911679

2、關鍵術語
2.1、負載均衡(load balance)

 
在互聯網高速發展的時代,大數據量、高併發等是互聯網網站提及最多的。如何處理高併發帶來的系統性能問題,最終大家都會使用負載均衡機制。它是根據某種負載策略把請求分發到集羣中的每一臺服務器上,讓整個服務器羣來處理網站的請求。
公司比較有錢的,可以購買專門負責負載均衡的硬件(如:F5),效果肯定會很好。對於大部分公司,會選擇廉價有效的方法擴展整個系統的架構,來增加服務器的吞吐量和處理能力,以及承載能力。

2.2、集羣(Cluster)

 用N臺服務器構成一個鬆耦合的多處理器系統(對外來說,他們就是一個服務器),它們之間通過網絡實現通信。讓N臺服務器之間相互協作,共同承載一個網站的請求壓力。

2.3、高可用(HA)

 在集羣服務器架構中,當主服務器故障時,備份服務器能夠自動接管主服務器的工作,並及時切換過去,以實現對用戶的不間斷服務。ps:這裏我感覺它跟故障轉移(failover)是一個意思,看到的網友給個解釋,謝謝?

2.4、session複製/共享

 在訪問系統的會話過程中,用戶登錄系統後,不管訪問系統的任何資源地址都不需要重複登錄,這裏面servlet容易保存了該用戶的會話(session)。如果兩個tomcat(A、B)提供集羣服務時候,用戶在A-tomcat上登錄,接下來的請求web服務器根據策略分發到B-tomcat,因爲B-tomcat沒有保存用戶的會話(session)信息,不知道其登錄,會跳轉到登錄界面。
這時候我們需要讓B-tomcat也保存有A-tomcat的會話,我們可以使用tomcat的session複製實現或者通過其他手段讓session共享。

3、常用web集羣

3.1、tomcat集羣方案

 apache+tomcat;ngnix+tomcat;lvs+ngnix+tomcat;大家比較熟悉的是前兩種。(lvs負責集羣調度,nginx負責靜態文件處理,tomcat負責動態文件處理[最優選擇])。 以apache+tomcat集羣爲例,簡單說一下:
  1、他們之間的通信有三種方式:ajp_proxy、mod_jk鏈接器、http_proxy。具體參考:http://www.ibm.com/developerworks/cn/opensource/os-lo-apache-tomcat/
  2、apache的分發策略有4種。權重(默認)、流量(bytraffic)、請求次數(byRequests)、繁忙程度(byBusyness根據活躍請求數的多少)
  3、apache支持stickysession(粘性session),即爲:訪問用戶訪問了A-tomcat,那麼他的所有請求都會轉發到A-tomcat,而不會到B-tomcat。[這樣的負載均衡效果不好,適用於小型網站,下面說非粘性session]
  4、它們之間的架構如圖1:


問題1:只有一個web服務器,明顯的單點故障。如果該apache出現問題,整個網站就會癱瘓。

 

3.2、session複製


  如果不採用stickysession(粘性session),那麼我們可以採用tomcat的session複製使所有節點tomcat的會話相同,tomcat使用組播技術,只要集羣中一個tomcat節點的session發生改變,會廣播通知所有tomcat節點發生改變。

問題2:據網友測試,當tomcat節點數達到4個以上時候,集羣性能呈線性下滑;另外當用戶訪問量大到一定程度,會話內容隨之增多,tomcat節點相互之間通信產生大量的網絡消耗,產生網絡阻塞,整個集羣的吞吐量不能再上升。


4、高可用(HA)和session共享(解決上面提到的兩個問題)


4.1、使用lvs+keepalive實現集羣高可用,達到更健壯的LB
 我們可以做前端使用lvs來做負載均衡,根據lvs的8種調度算法(可設置),分發請求到對應的web服務器集羣上。lvs做雙機熱備,通過keepalived模塊能夠達到故障自動轉移到備份服務器,不間斷提供服務,結構如圖2:


 
 說明:據查詢瞭解,一般在WEB端使用的負載均衡比較多的是HAProxy+keepalived+nginx;數據庫mysql集羣使用Lvs+keepalived+mysql實現。因爲HAProxy和nginx一樣是工作在網絡7層之上,並且前者彌補了nginx的一些缺點如session的保持,cookie的引導等,且它本身是個負責均衡軟件,處理負載均衡上面必然優於nginx;lvs比較笨重,對於比較龐大的網絡應用實施比較複雜,雖然它運行在網絡4層之上,僅做分發沒有流量產生,但是它不能做正則處理也不能也不能做動靜分離,所以一般用lvs+keepalived或heatbeat做數據庫層的負載均衡。

LVS、HAProxy、Nginx做負載均衡的比較
4.2、使用terracotta或者memcached使session共享
 

 4.2.1、terracotta是jvm級別的session共享

 它基本原理是對於集羣間共享的數據,當在一個節點發生變化的時候,Terracotta只把變化的部分發送給Terracotta服務器,然後由服務器把它轉發給真正需要這個數據的節點,並且共享的數據對象不需要序列化。

 

4.2.2、通過memcached實現內存級session共享

通過memcached-session-manager(msm)插件,通過tomcat上一定的配置,即可實現把session存儲到memcached服務器上。注意:tomcat支持tomcat6+,並且memcached可以支持分佈式內存,msm同時支持黏性session(sticky sessions)或者非黏性session(non-sticky sessions)兩種模式,在memcached內存中共享的對象需要序列化。結構如圖3:




 

  通過一定的配置,可以實現故障轉移(只支持對非粘性session)。如:

Xml代碼  收藏代碼
  1. <Context>    
  2.       ...    
  3.       <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"    
  4.         memcachedNodes="n1:host1.yourdomain.com:11211,n2:host2.yourdomain.com:11211"    
  5.         failoverNodes="n1"    
  6.         requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"    
  7.         transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"    
  8.         />    
  9. </Context>  

 說明:failoverNodes:故障轉移節點,對非粘性session不可用。屬性failoverNodes="n1"的作用是告訴msm最好是把session保存在memcached "n2"節點上,只有在n2節點不可用的情況下才把session保存在n1節點。這樣即使host2上的tomcat宕機,仍然可以通過host1上的tomcat訪問存放在memcached "n1" 節點中的session。
 
4.2.3、其他方案
通過cookie保存用戶信息(一般是登錄信息),每一個請求到達web應用的時候,web應用從cookie中取出數據進行處理(這裏儘量對cookie做加密處理);
另外一種是把用戶信息的關鍵屬性保存到數據庫,這樣就不需要session了。請求過來從數據庫查詢關鍵屬性數據,做相應處理。缺點:加大了數據庫的負載,使數據庫成爲集羣的瓶頸。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章