大型網站系統架構實踐(六)深入探討web應用集群Session保持


原理

       在第三,四篇文章中講到了會話保持的問題,而且還遺留了一個問題,就是會話保持存在單點故障,

當時的方案是cookie插入后綴,即haproxy指負責分發請求,應用服務自行保持用戶會話,如果應

用服務器宕機,則session會丟失。

現在來溫習下解決方案

方案1:session復制

原理

就是將1台服務器的session復制到其它所有的服務器上,這樣無論訪問哪台服務器,都會得到用戶 的session

優點

不存在單點故障問題

缺點

當服務器的數量比較大時,session同步將會變得相當耗時

 方案2:session粘滯

原理

就是用戶請求一個服務器之后,同一個會話的其它請求,都會被分配到這台服務器,session粘滯的 功能由負載均衡中間件完成

優點

解決了session復制的性能問題

缺點

由於用戶的會話被保存到單一的服務器,就容易出現單點故障

      

 

 

 

 

方案3:session服務器

原理

部署一個專門的服務,保存用戶session,同時在web服務器本地也保存一份,當本地沒有或者失效時, 去訪問session服務器,當然session服務器就成了單點,當用戶量大的時候也容易宕機,這時可以做一 個session服務器集群,做主備同步備份,這樣就達到了較好的效果,具體實現可以用redies,memcached 等緩存中間件。

優點

解決了單點故障和性能問題

缺點

實現復雜

      

 

 

 

       

      

 

redis保存session方案

      上篇文章講到的就是session粘滯的方案,既然前2種方案都有各自的缺點,那么就采用第三中方案     

可以用redis做session緩存,保存用戶session,做成主備模式,采用同步備份或者異步備份。

同步備份:在主機宕機時,備機接管之后session數據不丟失。

異步備份:在主機宕機時,備機接管主機,但是如果有一部分session還沒來得及同步到備機,session將丟失。

可以根據實際情況來決定采用同步備份還是異步備份。

系統架構圖如下:

image

如果用戶量比較大,單服務器訪問和存儲session將會成為瓶頸,可以考慮用session服務器集群,架構圖如下:

image

redis集群特點

1)將數據分散到集群中的多個節點,每個節點存儲的數據量就會變少,這樣存儲和訪問

的效率會得到提升。

2)每個節點都有主備,如果節點的主存儲掛了,備份存儲會接管主存儲,提高可用性。

Redis+Tomcat實現

session流程

1.客戶端首次請求服務端

2.服務端產生session並set cookie響應給客戶端

3.客戶端再次請求服務端,會帶上cookie

4.服務端根據cookie找到對應的session

實現思路

如果我們要編寫程序實現這個方案,需要解決以下問題:

1.session的安全性,即不容易被仿造。

2.session的唯一性,如果用tomcat產生session的策略,多台tomcat會產生的session會存在重復的可能。

3.session的有效期維護,session會有個有效期,用戶在這個時間內不訪問系統,session將會失效,如果

用戶一直訪問,則要自動延長session有效期。

4.在集群session服務器中,要考慮負載均衡,這也是需要編寫客戶端代碼的,在分布式session緩存中,

需要根據sessionId哈希分布,那么就和服務器個數進行了耦合,在添加和移除服務器的時候,將出現數

據不一致的問題 。

5.如何實現才能讓應用程序改動最小,或者是不改動。

我們可以選擇自己寫程序來實現以上功能,不過在這里我使用一個現成的框架,即tomcat-redis-session-manager

有時間並感興趣的朋友,可以在這個基礎上自行實現一個,這樣更適合自己的項目。

服務器部署分布:

ha主機 192.168.1.227:80

ha備機 192.168.1.246:80

keepalived 主機 192.168.1.227

keepalived備機 192.168.1.246

web1 http://192.168.1.226:8888/login

web2 http://192.168.1.246:8888/login

redis主 192.168.1.245 6380

redis備

安裝redis

主機和備機都安裝redis

wget http://download.redis.io/releases/redis-2.8.5.tar.gz

解壓:

tar xzf redis-2.8.5.tar.gz

cd redis-2.8.5

make

啟動

src/redis-server redis.conf --port 6380 &

客戶端登錄

src/redis-cli -p 6380

備機配置復制:

redis.conf文件中

添加

slaveof 192.168.1.245 6380

Tomcat配置

tomcat版本:7.0.61

相關jar包:

注意這里的jar包最好是按下面的版本,否則會出現jar包沖突的問題。

tomcat-redis-session-manager-1.1.jar

commons-pool-1.6.jar

jedis-2.1.0.jar

下載tomcat redis session manager

https://github.com/jcoleman/tomcat-redis-session-manager/downloads

下載 apache common pool

http://commons.apache.org/proper/commons-pool/download_pool.cgi

下載版本:tomcat-redis-session-manager-1.1

redis的jar包可以從maven中央倉庫下載

將以上3個jar包放入tomcat/lib目錄中

在tomcat context.xml中加入如下內容

<!-- host: optional: defaults to "localhost" -->
<!-- port: defaults to "6379" -->
<!-- database: optional: defaults to "0" -->
<!-- maxInactiveInterval: optional: defaults to "60" (in seconds) -->
<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" />
<Manager className="com.radiadesign.catalina.session.RedisSessionManager"
    host="192.168.1.245" port="6380" database="0" maxInactiveInterval="60" />

啟動tomcat,瀏覽器請求tomcat

http://192.168.1.226:8888/login/

  image

登錄redis客戶端,查看session

image

session已經被保存到redis

下面,我們進行一項測試

測試流程:

1.先訪問虛擬ip1.99的應用,得到sessionId

image

web服務器是226

2.然后將對應的tomcat停掉

3.刷新該應用,若sessionId未變,則表示redis保存session成功。

image

我們發現web服務器變成了246,但是sessionId未發生變化

該方案將session集中保存在了redis服務器,並做了主備容災,從一定程度上提高了系統的高可用,由於

redis是內存存儲,訪問效率較高,在性能上也是比較好的,但是本例中session不是分布式存儲,因此當用戶量

非常大,並發訪問量非常高的時候,session服務器會成為性能瓶頸。

 

上篇 大型網站系統架構實踐(五)深入探討web應用高可用方案

目錄 大型網站系統架構的演進目錄


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM