服務器集羣session共享

假設網站部署在N臺服務器上,多是tomcat集羣或者nginx集羣,在集羣以前有一個負載均衡服務器,使得用戶對網站的訪問會均衡地訪問到服務器集羣的各個節點上。html

如今A用戶開始訪問網站,假設分配到b服務器上,那麼若是A用戶在session生命週期內,再次訪問網站(用戶在訪問的過程當中是隨機切換到其餘服務器),如何得到他的session呢?(由於可能會分配到其餘服務器上,或者如何記得以前分配在哪一個服務器上?)node

這就是服務器集羣session共享問題。nginx

解決方案:redis

1. tomcat session複製

tomcat自己自帶session複製功能,開啓server.xml中的`cluster`節點,作相應的配置便可。參見Apache Tomcat 8 (8.0.26)。tomcat自己的session複製功能並很差用,官方文檔也說方式只適合小集羣:apache

This works great for smaller cluster but we don't recommend it for larger clusters(a lot of Tomcat nodes).segmentfault

而且tomcat自己併發性能也並不太好。這種方式更加適合於對併發要求不高的小規模集羣。瀏覽器

2. redis存儲session

這種方案多是用得最多的一種tomcat

直接配置tomcat的session管理,session直接讓redis管理安全

主要的配置是在服務器

修改tomcat的context.xml

<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" />
<Manager className="com.radiadesign.catalina.session.RedisSessionManager"
         host="localhost"
         port="6379"
         database="0"
         maxInactiveInterval="120"/>

全部session都存在redis(redis集羣)中,不管訪問哪臺服務器最終都會把session保存在redis中,然而redis集羣是如何保證各個結點的數據一致性,對於這個需求是黑匣子,沒必要關心。

3. session cookie化

把原來存儲在服務器磁盤上的session數據存儲到客戶端的cookie中去。

這樣子,就不須要涉及到數據共享了。a客戶端請求的時候,原來生成在服務器的數據生成到瀏覽器的cookie中,根據cookie中的數據識別用戶。

這樣子,在多臺服務器負載均衡的狀況下,即使第一秒請求是a服務器,第二秒請求是b服務器,都不須要管哪臺服務器了。反正都是讀取客戶端上的cookie數據。

通常是把session數據按照本身定義的加密規則,加密後後存在cookie中。

數據保存在cookie中這種作法有好處,也有壞處。

好處是服務器的壓力減少了,由於session數據不存在服務器磁盤上。根本就不會出現session讀取不到的問題。

帶來的弊端是:

網絡請求佔用不少。每次請求時,客戶端都要經過cookie發送session數據給服務器。

另外,瀏覽器對cookie的大小存在限制。每一個瀏覽器限制是不一樣的。

  • Firefox和Safari容許cookie多達4097個字節,包括名(name)、值(value)和等號。
  • Opera容許cookie多達4096個字節,包括:名(name)、值(value)和等號。
  • Internet Explorer容許cookie多達4095個字節,包括:名(name)、值(value)和等號。

因此這種方案不適合高訪問量的狀況下,由於高訪問量的狀況下,每次請求瀏覽器都要發送session數據給服務器。通常一個cookie大小2k的樣子。

要佔用不少帶寬了(服務器購買帶寬是一個很大費用),成本增高。概括爲帶寬性能,速度問題。

存儲到cookie中去,第二方面是安全問題:把session數據放到客戶端,通常session中存的都是重要性數據(賬號、暱稱、用戶id等),會存在安全問題。

瞭解到,淘寶之前用過這種方式,把session數據存儲到cookie中,根據cookie來識別用戶。

4. 粘性session

該種方式下,當用戶發出第一個request後,被分配到某個節點,並記錄該節點的jvm路由,之後該用戶的全部request都會被綁定到這個jvm路由,用戶只會與該server發生交互,這種策略稱爲粘性session。

優勢是響應速度快,多個節點之間無須通訊。

缺點是某個節點down掉後,用戶就丟失了session。

5. 不使用session

這就是另一種思路了,其實差很少,也提一下吧。

HTTP自己就是無狀態的,應用服務器爲了跟蹤用戶狀態而強行加入了session。服務器爲了保存用戶狀態就須要作額外的工做。

因而乎,Token-based的身份校驗因其伸縮性而廣受歡迎。在用戶登陸後,服務器返回一個token給用戶,用戶後續的請求都須要附帶此token,服務器會校驗該token來判斷用戶身份,進而完成具體業務(這裏掠過不談token的安全防禦問題)。

 

Reference:

1. https://segmentfault.com/q/1010000003988125

2. https://www.zhihu.com/question/27085849

3. http://www.imooc.com/article/5087

4. http://www.cnblogs.com/wangtao_20/p/3395518.html

5. http://www.360doc.com/content/12/0302/10/7472437_191040410.shtml

相關文章
相關標籤/搜索