隨著網站的功能越來越多,用戶量越來越龐大,單節點模式已經嚴重不能支撐整個系統的正常運作,輕則用戶頁面訪問時間越來越慢,重則就會導致整個系統癱瘓。這時候
就需要優化或調整目前的架構,大部分人就會采用各種負載均衡軟件例如nginx、hproxy、LVS等,也有的采用分布式的方式把系統根據功能拆分成很多系統,也有的根據地域
和網絡不同來實現訪問不同節點部署的系統,也有的大型高流量、高負載的系統把負載均衡、分布式及根據地域、網絡等這些方式都整合在一起來實現系統的正常運行。
采用負載均衡軟件是目前大家采取的比較多的方式。但是在采用負載均衡軟件時將會面臨session同步的問題。以下是解決問題的幾種方式。
### 1. 客戶端cookie加密的方式
把session數據存放在cookie中,當請求過來時,從cookie中獲取session數據。這種方式不需要任何的存儲系統,也不會出現讀寫session數據帶來的網絡操作延時和不穩定性。
但是有以下缺點:
* Cookie有長度限制,這會影響session數據的長度。
* 安全性。session數據本來存儲在服務端的,而這個方案是讓session數據轉到外部網絡或客戶端中,所以會有安全性問題。不過可以對寫入Cookie的session 數據做加密。
* 帶寬消耗。由于加了session數據,帶寬當然也會增加一點。
* 性能消耗。每次Http請求和響應都帶有Session數據,對于Web服務器來說,在同樣的處理情況下,響應的結果輸出越少,支持的并發請求越。
### 2. web server的session復制方式
大部分應用服務器都提供了session復制的功能來實現集群,tomcat、jboss、was都提供了這樣的功能。session復制就是每臺應用服務,都保存會話session數據。
優點:
靠應用容器來完成session共享,并不依賴應用,如果應用服務數量并不是很多,可以考慮;
缺點:
同步session數據帶來都網絡開銷。只要session數據變化,就需要同步到所有機器上,機器越多,網絡開銷越大。
由于每臺服務器都保存session數據,如果集群的session數據很多,比如90萬人在訪問網站,每臺機器用于保存session數據的內容占用很嚴重。
### 3. 使用關系數據庫保存session
用mysql、sqlserver等數據庫保存session,就算服務器宕機了也沒事,session照樣在。
缺點:
程序需要定制;
每次請求都進行數據庫讀寫開銷不小(使用內存數據庫可以提高性能,宕機就會丟失數據。可供選擇的內存數據庫有BerkeleyDB,Mysql的內存表);
### 4.使用nosql數據庫保存session
采用redis、mongodb、memcached等非關系數據庫來實現session的共享。這些非關系數據庫響應數據非常的快,而且支持的訪問量也比較大。系統資源消耗也比較少。這也是很多系統所采用的方式。
但是也有缺點:
讀寫session引入了網絡操作,相對于本機讀寫session,帶來了延時和不穩定性。
如Session集中服務有問題,會影響應用。
### 5.采用Session Stick
在單機情況,session保存在單機上,請求也是到這臺單機上,不會有問題。變成多臺后,如果能保障每次請求都到同一臺服務,那就和單機一樣了。 這需要在負載均衡設備上修改。這就是Session Stick,這種方式也會有問題:
如果某一臺服務器宕機或重啟,那么這臺服務器上的session數據就丟失了。如果session數據中還有登錄狀態信息,那么用戶需要重現登錄。
負載均衡要處理具體的session到服務器的映射。
### 6.使用terracotta來保存session
跟memcached類似,但是數據不需要序列化,并且是Find-Grained Changes,性能更好。配置對原來的應用完全透明,原有程序幾乎不用做任何修改。而且terracotta本身支持HA。
綜上所述,我個人推薦使用第4、6種方式來解決session共享的問題。