一文讀懂分佈式Session常見解決方案

前言

我們知道HTTP協議本身是無狀態的,因此在使用HTTP協議進行通信的過程中,需要藉助Session機制進行狀態的保持。然而在大型網站中,我們的服務器數量通常不止一臺,可能是幾十臺甚至幾百臺之多,用戶發起的HTTP請求通常要經過像Ngnix之類的負載均衡器之後,再路由到具體的服務器上,由於Session默認是存儲在單機服務器內存中的,因此在分佈式環境下同一個用戶發送的多次HTTP請求可能會先後落到不同的服務器上,導致後面發起的HTTP請求無法拿到之前的HTTP請求存儲在服務器中的Session數據,從而使得Session機制在分佈式環境下失效。

因此在分佈式環境下,要使用Session機制進行狀態保持,需要採取額外的手段,在這裏介紹常見的4種解決方案:Session集中式存儲、Session複製、Session Sticky、Cookie Based。

Session集中式存儲

Session集中式存儲是指將原先存儲在單機服務器內存中的Session數據集中存儲起來,比如說存儲在分佈式緩存Redis集羣中。其原理是以SessionId作爲Key,序列化後的HttpSession對象作爲Value存儲在Redis中,然後將SessionId返回給客戶端,當下一次客戶端發送HTTP請求到服務器的時候,會帶上這個SessionId,服務器再根據SessionId從Redis拿到相應的Session數據並反序列化成HttpSession對象。由於對HttpSession對象進行了集中存儲,而不是存儲在服務器本地內存,所以即使同個用戶的多次HTTP請求落到不同的服務器上,也能將SessionId與相應的HttpSession對象關聯起來,從而實現分佈式環境下的Session共享。

Session複製

ession複製從另一個角度解決分佈式Session問題。前文說到,Session機制在分佈式環境下失效的原因是每臺服務器上只存儲了部分客戶端的Session信息,那麼我們只要保證每臺服務器上都存儲了所有客戶端的Session信息不就解決問題了嗎?Session複製就是基於這個思路實現的,當客戶端在某臺服務器上存儲了Session數據的時候,我們可以手動地將該Session信息同步到集羣中的其他服務器上面去,這樣一來所有服務器就都存儲了所有客戶端的Session信息了,因此即使同個客戶端的多次HTTP請求落到不同的服務器上面去,也還是能夠拿到相應的Session信息,故而也解決了Session分佈式問題。實際上,一些開源的Web容器可以支持Session複製,如:Tomcat,因此實施起來難度不大。同樣地,這

Session Sticky

從另一個角度來說,分佈式環境下Session失效也可以說是因爲同個客戶端在多次請求之間落到不同的服務器上導致的。因此,如果能夠保證同個客戶端發起的HTTP請求都由相同的服務器進行處理,那麼也可以避免Session失效的問題。比如說,Nginx有一種稱爲IP Hash的負載均衡策略,其可以實現相同IP發送的HTTP請求都路由到同一臺服務器上面去,故而也能解決Session分佈式問題。同樣地,在評論區討論這種方案的利弊吧。

前面所講的方案都是將Session數據存儲在服務器中,其實要實現會話保持,還可以將Session數據存儲在客戶端,常見的方案是存儲在Cookie中,這樣一來服務器就無需維護客戶端的狀態,即服務器“無狀態化”,無狀態化的好處是利於服務器水平擴展。比如:JWT就是基於Cookie實現用戶認證功能的,有興趣的朋友可以去了解下。那麼這種方案有何優缺點呢?評論區見。

發佈了121 篇原創文章 · 獲贊 574 · 訪問量 66萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章