什麼是session?nginx
因爲HTTP協議是無狀態的協議,所以它不會去記住上一次瀏覽器訪問服務器時的信息。同一個用戶的兩次操做,與兩個不一樣用戶的操做,對它來講是同樣的。 這樣雖然知足了互聯網web應用的海量訪問的需求,可是對於現今相似電商的應用來講,是須要實現登陸以及身份驗證需求的,可是無狀態的HTTP顯然是作不到的,這樣纔出現了session。web
Web服務器爲每一個用戶建立一個會話,存儲用戶的相關信息,以便屢次請求可以定位到同一個上下文。數據庫
web-server能夠自動爲每個瀏覽器訪問的用戶自動建立session,提供數據存儲功能。最多見的,會把用戶的登陸信息、用戶信息存儲在session中,以保持持續登陸狀態。後端
什麼是session一致性問題?瀏覽器
每次http短鏈接請求,理論上服務端都能定位到session,保持會話狀態。緩存
當應用只有一臺web-server提供服務時,每次瀏覽器發送http請求,都可以正確路由到存儲session的對應web-server(由於只有一臺)。安全
此時的web-server是沒法保證高可用的,所以若是咱們採用Nginx反向代理,而後加上web-server 「冗餘+故障轉移」的方案,用多臺web-server來保證高可用時,每次http短鏈接請求就不必定能路由到正確的session了。服務器
好比第一次用戶登陸的時候,Nginx路由到 web-server1,且在web-server1上建立了session,當第二次訪問時,Nginx路由到了web-server2上。此時web-server2上是沒有用戶的登陸信息的,那麼就會致使用戶須要從新登陸,這樣用戶體驗確定是很差的。cookie
那麼如何保證分佈式系統的session路由一致性呢?網絡
1、session同步法
這個方案的思路就是,多個web-server之間相互同步session,這樣每一個web-server之間都包含所有的session。
優勢:應用程序不須要修改代碼。
不足:
session的同步須要數據傳輸,佔內網帶寬,有時延
全部web-server都包含全部session數據,數據量受內存限制,沒法水平擴展。
2、客戶端存儲法
這個方案的思路就是,服務端存儲全部用戶的session的話內存佔用較大,能夠將session存儲到瀏覽器cookie中,每一個端只要存儲一個用戶的數據了。
優勢:服務端不須要存儲。
缺點:
每次http請求都攜帶session,佔外網帶寬
數據存儲在端上,並在網絡傳輸,存在泄漏、篡改、竊取等安全隱患
session存儲的數據大小受cookie限制
「端存儲」的方案雖然不經常使用,但確實是一種思路。
3、反向代理hash一致性
這個方案的思路就是,在反向代理層作點文章,讓同一個用戶的請求保證落在一臺web-server上。
咱們能夠在反向代理層使用用戶ip來作hash,以保證同一個ip的請求落在同一個web-server上。
優勢:
只須要改nginx配置,不須要修改應用代碼
負載均衡,只要hash屬性是均勻的,多臺web-server的負載是均衡的
能夠支持web-server水平擴展
不足:
若是web-server重啓,一部分session會丟失,例如部分用戶從新登陸
若是web-server水平擴展,rehash後session從新分佈,也會有一部分用戶路由不到正確的session
4、後端統一存儲法
思路就是,將session存儲在web-server後端的存儲層,數據庫或者緩存。
優勢:
沒有安全隱患
能夠水平擴展,數據庫/緩存水平切分便可
web-server重啓或者擴容都不會有session丟失
不足:增長了一次網絡調用,而且須要修改應用代碼。
對於db存儲仍是cache,我的推薦後者:session讀取的頻率會很高,數據庫壓力會比較大。若是有session高可用需求,cache能夠作高可用,但大部分狀況下session能夠丟失,通常也不須要考慮高可用。
總結
保證session一致性的架構設計常見方法:
session同步法:多臺web-server相互同步數據
客戶端存儲法:一個用戶只存儲本身的數據在cookie中。
反向代理hash一致性:保證一個用戶的請求落在一臺web-server上
後端統一存儲:web-server重啓和擴容,session也不會丟失
對於方案3和方案4,我的建議推薦後者:
web層、service層無狀態是大規模分佈式系統設計原則之一,session屬於狀態,不宜放在web層。