微服務下的分佈式session管理

享學課堂特邀做者:老顧web

轉載請聲明出處!redis

前言

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

session做用

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

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

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

session原理

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

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

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

單體架構

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

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

集羣/分佈式架構

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

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

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

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

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

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

四、但服務器B中是沒有存放用戶A的session的,因此此sessionId在服務器B中找不到對應的session,就會覺得用戶沒有登陸,就會引導用戶去登陸

五、這樣就致使session不一致的問題

session複製

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

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

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

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

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

三、服務器的內存是有限的,表明着session存放是有限的

session粘性

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

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

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

一、服務器的內存是有限的,表明着session存放是有限的

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

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

cookie方案

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

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

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

二、安全是頗有問題的,由於保存在本地,很容易被人拿到

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方案又會怎麼樣?留下二個問題,請小夥伴們仔細思考下。請持續關注老顧的文章,謝謝!!!

相關文章
相關標籤/搜索