微服務下的分佈式session管理

享學課堂特邀作者:老顧

轉載請聲明出處!

前言

今天老顧帶着大家瞭解一下session會話在微服務架構中採用的技術方案,以及 企業應用中需要注意的問題。

session作用

我們知道在web應用中,web服務器和瀏覽器之間是用http協議進行通信的,而http協議是無狀態的,也就是每個請求都是獨立的。如:用戶看一條A新聞,不管是誰看到的都是一模一樣的新聞。也就是跟用戶是誰沒有任何關係

但業務自身的發展,需要把不同的內容展示給不同的用戶,即信息和用戶狀態關聯起來。如:歷史閱讀列表---列出用戶之前看的新聞。這個需求就是跟用戶相關,每個用戶看到的歷史閱讀列表都是不一樣的。

Session的產生就是爲了解決這個問題,把服務器和客戶端之間進行狀態保持的解決方案。

session原理

瀏覽器在第一次訪問web服務器,服務器端會響應一個sessionId,並且把這個sessionId傳輸給瀏覽器,並以cookie保存sessionId到瀏覽器本地

以後的訪問會把這個cookie的sessionId以請求頭的方式傳給服務器,這樣服務器就可以拿着這個sessionId進行查找,服務器中有沒有此sessionId對應的用戶,這樣就能標識出哪個用戶,如果有用戶相關的業務,就是利用這個sessionId返回用戶相關的業務

本質就是瀏覽器客戶端本地保存了sessionId服務器端保存了sessionId和用戶信息映射,這樣就實現了web應用有狀態化。

單體架構

在早期的單體架構中,也就是只有一臺web服務器,雖然在web應用中也進行的分層設計,但其實本質是在代碼邏輯級別,本身還是一個應用而已(或者說就是一個war/jar包)。

這個時期的session都是保存在本地的web服務器內存中,非常簡單就能保持用戶狀態。

集羣/分佈式架構

隨着業務的複雜度升高,和對應用性能、高可用的需求,系統演變成了集羣和分佈式架構

集羣架構可以看服務器A和服務器B,部署同一個應用A,就是爲了提升性能和高可用目的;服務器C是部署了另一個應用B,代表系統不是單一業務,而是多個應用集合的,即分佈式架構。

這個架構中,我們之前的session方案就會有問題,因爲服務器端的session是存放在本地內存中的。請看下面的流程

1、用戶A第一次訪問系統,由負載均衡器映射到服務器A中

2、會在服務器A的本地內存中,存放着session

3、用戶A第二次訪問系統,又被隨機分配到了服務器B中

4、但服務器B中是沒有存放用戶A的session的,所以此sessionId在服務器B中找不到對應的session,就會以爲用戶沒有登錄,就會引導用戶去登錄

5、這樣就導致session不一致的問題

session複製

session複製方案是一個服務器端的方案,對客戶端是透明的,客戶端不需要改變什麼。看架構圖

這個方案本質是利用了應用服務器自身的特性,如:tomcat。修改一下tomcat的配置文件,就是讓應用服務器之間進行session複製,這樣就可以達到每個服務器都有一樣的session。

這個方案2-3個服務器還行,但服務器一旦多起來,就會有問題。

1、session之間的複製就會佔用很大的網絡帶寬

2、session複製是有時間延遲的

3、服務器的內存是有限的,代表着session存放是有限的

session粘性

這個方案就利用負載均衡器的特性,把同一個瀏覽器的同一個用戶都定向發送到同一個服務器上。看架構圖

上圖的核心思路,用戶甲訪問系統被負載均衡器一直分配到服務器A上,這樣也就保證了用戶一直在同一個服務器中進行查找session,保證了用戶session一致性

不過此方案也存在一些問題:

1、服務器的內存是有限的,代表着session存放是有限的

2、這個方案適用集羣架構,但不適用分佈式架構

3、一旦服務器拓展數量,session就會出現混亂

cookie方案

之前的方案都是在服務器端進行改造的,cookie方案是客戶端的方案,就是把session信息保存到cookie中,即用戶信息保存到cookie中,這樣就不需要服務器保存session(用戶信息)了。每次請求時,把此cookie傳給服務器端,這樣服務器端就知道是哪個用戶了

此方案比較實現比較簡單,而且還不佔用服務器端的內存資源。但是此方案的問題很大哦。

1、cookie在客戶端是有限的,存儲容量也是很小的

2、安全是很有問題的,因爲保存在本地,很容易被人拿到

session外部存儲

之前的服務器端改造的方案,session都是存儲到本地內存中的,導致一些問題。 此外部存儲就是把思路進行改變,讓session的存儲與應用服務器隔離出來,看架構圖

這個方案的核心就是把session的存儲的地方改造到一個獨立的媒介中,這樣就不需要和應用服務器耦合了,客戶端傳入sessionId時,用戶信息的映射關係直接到這個獨立媒介中去查找。

數據庫存儲

存儲媒介的選擇之一就是數據庫,就是把session信息存儲到數據庫中。

好處就是session持久化到數據庫中,不會丟失。但性能比較差,因爲session的訪問是非常頻繁的,會對數據庫造成很大壓力,

Memcache存儲

此方案就是把session存儲到memcache中,Memcache-Tomcat-Session就是利用tomcat實現session的集中化管理的開源方案,修改tomcat配置就行了,使用擴展的sessionManager替換tomcat默認的Session管理器。

memcache性能比較高,但此方案和tomcat強耦合了,不適合其他的應用服務器,如:jetty。而且memcache無持久化,一旦重啓,session就丟失了

Redis存儲

redis存儲方案一般結合spring session方式,把session存儲到redis中。

這個方案是spring提供的一套Session管理方案,通過一個SessionFilter將所有請求攔截下來,對session進行管理,此方案的好處就是不與應用服務器耦合,可以部署到任何web應用服務器中。redis也是高性能的緩存服務器,且可持久化。這個方案也是官方推薦的。

總結

到這裏老顧已經介紹了常用的session管理方案,最終推薦的是spring session方式進行session管理,存儲在redis中。小夥伴們看到這裏是不是感覺蠻好了,可以在企業中進行應用了?

如果企業小,項目不復雜,是可以應用了。

但如果系統很複雜,有很多業務系統都是有session的,那麼如何對session從業務角度進行管理呢?上面我們介紹cookie方案,小夥伴們有沒有考慮到JWT Token方案,jwt方案又會怎麼樣?留下二個問題,請小夥伴們仔細思考下。請持續關注老顧的文章,謝謝!!!

轉載於:https://juejin.im/post/5d08b4185188250a8b1fd66f

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章