session一致性架構的四種設計實施方案

一、緣起

1。1 什麼是session?

伺服器為每個使用者建立一個會話,儲存使用者的相關資訊,以便多次請求能夠定位到同一個上下文。Web開發中,web-server可以自動為同一個瀏覽器的訪問使用者自動建立session,提供資料儲存功能。最常見的,會把使用者的登入資訊、使用者資訊儲存在session中,以保持登入狀態。

1。2 什麼是session一致性問題?

只要使用者不重啟瀏覽器,每次http短連線請求,理論上服務端都能定位到session,保持會話

1。3 通常情況下的應用部署

單個應用當只有一臺web-server提供服務時,每次http短連線請求,都能夠正確路由到儲存session的對應web-server(廢話,因為只有一臺),這種情況在實際中很少使用,只有少出的網站或者服務提供單個節點應用提供服務。單個應用

多個應用,負載使用為了能夠保證應用的高可用,採用“冗餘+故障轉移”的多臺web-server來保證高可用時,每次http短連線請求就不一定能路由到正確的session了。多個應用,負載使用

如上圖所示,假設使用者在第一個web-server上登入,登入資訊的session都記錄在第一臺web-server上,nginx反向代理如果將請求路由到另一臺web-server上,會出現找不到session的情況,而使用者需要重新登入。

在web-server高可用時,如何保證session路由的一致性,是今天將要討論的問題。

二、session同步法

當存在多個應用時,一臺應用機器上存在session,而另一臺應用機器上不存在session,我們最先想到的是將session同步到另外一臺機器上,如下圖所示:

session一致性架構的四種設計實施方案

session同步

解決方案:多個web-server之間相互同步session,這樣每個web-server之間都包含全部的session。

那不同機器間的session需要我們自己應用去同步資訊嗎?

答案是不用!session是在應用的jvm裡,web-server之間的session同步需要較大的工作量,web-server已經幫我們做好了一切

如有我們自己編寫相應的程式同步session,我們自己有能力設計一個完美的程式嗎?

三、客戶端儲存法

服務端儲存所有使用者的session,記憶體佔用較大,可以將session儲存到瀏覽器cookie中,每個客戶端只要儲存一個使用者的資料,既節省了服務端記憶體,同時也避免了多個不同web-server記憶體可能存在不一致的問題

session一致性架構的四種設計實施方案

cookies儲存session

四、反向代理hash一致性

反向代理hash一致性,通常也是我們說的會話保持,將相同使用者的請求分發到同一臺web-server上,這樣使用者在web-server上登陸後,該使用者的所有請求都會分發到這一臺機器上,這樣保證了session一致性

session一致性架構的四種設計實施方案

反向代理hash一致性

hash一致性,通常有兩種做法:

方案1:四層代理hash

使用使用者IP來進行hash,以保證同一個IP的請求落在同一個web-server上

方案2:七層代理hash

使用http協議中的某些業務屬性進行hash,比如:使用者id,能夠更加靈活的實施hash策略,以保證相同使用者的的請求落到同一個web-server上

那對於這兩種方案如何選擇呢?

個人推薦前者:讓專業的軟體做專業的事情,反向代理就負責轉發,儘量不要引入應用層業務屬性。

五、後端統一儲存

session分散到不同的機器上,必然會存在session不一致的問題,那可不可以把session存放到相同的位置(db、快取或者檔案等),不同web-server訪問相同的儲存位置,也可以避免session不一致的問題

session一致性架構的四種設計實施方案

後端統一儲存

對於 db、快取或者檔案等方式,推薦使用快取的方式,比如redis等快取資料庫,使用者每一次請求都需要訪問session,使用db或者檔案的訪問速度都比較低,可以使用

spring-session

簡化相關工作

六、四種方法的比較

對四種方案的優點和不足進行比較

解決方案優點不足

session同步方案web-server支援的功能,應用程式不需要修改程式碼1。session的同步需要資料傳輸,佔

內網頻寬

,有時延

2。所有web-server都包含所有session資料,資料量受記憶體限制,無法水平擴充套件

3。有更多web-server時要歇菜客戶端儲存方案1。服務端不需要儲存session,節省記憶體

2。不需要考慮session一致性問題1。每次http請求都攜帶session,佔

外網頻寬

2。資料儲存在端上,並在網路傳輸,存在洩漏、篡改、竊取等安全隱患

3。session儲存的資料大小受cookie限制反向代理hash一致性1。只需要改nginx配置,不需要修改應用程式碼

2。負載均衡,只要hash屬性是均勻的,多臺web-server的負載是均衡的

3。可以支援web-server水平擴充套件(session同步法是不行的,受記憶體限制)1。如果web-server重啟,一部分session會丟失,產生業務影響,例如部分使用者重新登入

2。如果web-server水平擴充套件,rehash後session重新分佈,也會有一部分使用者路由不到正確的session

3。如果有某臺web-server上的使用者頻繁請求,會出現負載不均衡的情況後端統一儲存1。不存在安全隱患

2。可以水平擴充套件,資料庫/快取水平切分即可

3。web-server重啟或者擴容都不會有session丟失1。增加了一次網路呼叫,並且需要修改應用程式碼

2。可能會增加額外的裝置,比如redis伺服器等

七、總結

保證session一致性的架構設計常見方法:

session同步法:多臺web-server相互同步資料

客戶端儲存法:一個使用者只儲存自己的資料

反向代理hash一致性:四層hash和七層hash都可以做,保證一個使用者的請求落在一臺web-server上

後端統一儲存:web-server重啟和擴容,session也不會丟失

對於方案3和方案4,個人建議推薦後者:•web層、service層無狀態是大規模分散式系統設計原則之一,session屬於狀態,不宜放在web層•讓專業的軟體做專業的事情,web-server存session?還是讓cache去做這樣的事情吧

八、參考文獻

1。架構師之路-session一致性架構設計實踐