1. 程式人生 > >session原理演變 微服務架構下分散式Session管理

session原理演變 微服務架構下分散式Session管理

一、應用架構變遷下的Session管理

1.1 單體架構

1.2 分散式架構

1.3 微服務架構

二、微服務架構下分散式Session管理

2.1 Session儲存介質

2.2 管理方案實現

三、微服務架構下分散式Session管理方案

四、總結

 

應用架構變遷下的Session管理

 

Session一詞直譯為“會話”,意指有始有終的一系列動作/訊息。Session是Web應用蓬勃發展的產物之一,隱含有“面向連線”和“保持狀態”兩個含義,同時也指代Web伺服器與客戶端之間進行狀態保持的解決方案。

 

Web伺服器與客戶端基於HTTP協議進行通訊,HTTP協議本身是無狀態的,即每一次請求之間都相互獨立。但是隨著Web應用的發展,Web伺服器需要按照使用者的一系列業務操作向客戶端提供某些特定的、按需的內容,這就需要想辦法將原本相對獨立的HTTP請求進行關聯。Session管理正是上述問題的解決方案,把使用者的資訊與狀態儲存在Session中,彌補了Web應用中HTTP協議的不足。

 

Session管理作為Web應用的重要解決方案之一,隨著Web應用架構的不斷變遷,對Session管理方案的要求也變得越來越高。對於不同應用架構,Session管理方案也有所不同。

 

1.1 單體架構

單體架構即是指把一個使用了分層架構的Web應用部署在單節點Web伺服器上的架構型別。

 


圖1  單體架構應用示意圖

 

在這種架構中,雖然採用了分層架構,將整個應用分為表現層、業務邏輯層和資料訪問層,每一層各司其職,讓Web應用的各方面能力有所改善。但是因為應用是單體的,所有程式碼都部署在一個Web伺服器上,隨著應用的不斷迭代,將會變得臃腫不堪,難以進行維護。

 

單體架構中,Session管理方案是在使用者進行登入的時候將Session存放在應用伺服器的記憶體中,由於只有一個應用伺服器節點,使用者的所有請求都是這個唯一節點進行響應處理,所以能夠輕鬆的達到保持使用者狀態的目的。

 

1.2 分散式架構

隨著Web應用的迭代開發,應用程式碼的維護難度成為了單體應用的一大瓶頸,為了突破這一瓶頸,出現了分散式架構的概念,企業開始使用分散式架構來代替原有的單體架構。

 

 

 

圖2  分散式架構應用示意圖

 

在分散式架構中,把原來的單體架構應用,按照不同的功能模組,拆分成若干個較小的應用,分別部署到若干個伺服器上。這些伺服器上的應用模組,各自提供相應的分散式服務,共同協作,為使用者提供服務。

 

此時的伺服器架構中,不再是單一的應用伺服器節點,而是有多個伺服器節點同時為使用者提供服務。單體架構中的Session管理方案已經無法滿足分散式架構的需要,使用者的登入請求是由分散式架構中的一個伺服器節點進行響應處理,當用戶操作向其他伺服器節點發送請求的時候,就會因為接受請求的節點上沒有使用者Session而導致操作失敗,讓使用者重新登入。

 

所以,在分散式架構中,必須保證使用者在一個伺服器節點進行登陸後,不僅該節點需要在記憶體中儲存使用者Session,還需要讓其他應用伺服器節點也能共享到使用者Session。分散式架構進行Session共享的常用方案有如下幾種。

 

(1)存放在Cookie中

當用戶Session中需要存放的資料很小的時候,可以選擇將Session物件存放在瀏覽器的Cookie中來實現Session共享。該方案實現方便,但是由於Cookie的儲存容量不大,所以只適用於Session資料量小的場景。

 

(2)Session複製

部分Web伺服器能夠支援Session複製功能,例如Tomcat。使用者可以通過修改Web伺服器的配置檔案,讓Web伺服器進行Session複製,保持每一個伺服器節點的Session資料都能達到一致。

 

但是這種方案的實現依賴於Web伺服器,需要Web伺服器有Session複製功能。當Web應用中Session數量較多的時候,每個伺服器節點都需要有一部分記憶體用來存放Session,將會佔用大量記憶體資源。同時大量的Session物件通過網路傳輸進行復制,不但佔用了網路資源,還會因為複製同步出現延遲,導致程式執行錯誤。

 

(3)Session粘滯

Session粘滯是通過負載均衡器,將同一使用者的請求都分發到固定的一個伺服器節點上,讓固定伺服器進行響應處理,如此一來,只需要這個節點上儲存了使用者Session,即可保持使用者的狀態一致性。

 

但是Session粘滯方案依賴於負載均衡器,而且只能滿足水平擴充套件的叢集場景,無法滿足進行應用分割後的分散式場景。

 

1.3微服務架構

Web應用持續發展,雖然進行了一定的拆分,把過去單體架構的巨石應用切割成了由若干個模組組成的分散式應用,但隨著不斷的迭代開發,這些模組應用依然會變成巨石應用,程式碼維護成本直線上升。

 

儘管可以再次進行應用拆分,但是隨著拆分的應用增多,這些應用的編譯、打包、部署和整合也成為了新的難題。在這樣的一個環境之下,微服務架構開始受到廣泛關注。

 

微服務架構即將一個應用拆分成一套小而相互關聯的微服務,微服務之間通過暴露出來的API被其他微服務或系統所呼叫,在執行時,每個微服務例項通常是一個雲虛擬機器或一個Docker。眾多微服務綜合起來,構成了一個完整的微服務架構應用。

 

微服務架構中的微服務一般可以分為兩類:無狀態服務和有狀態服務。無狀態服務比如應用伺服器,它們通常是不儲存資料的,方便進行橫向擴充套件;有狀態服務需要進行資料儲存,比如資料庫服務和快取服務。在Web應用中,Session用來儲存使用者的狀態資訊,所以Session管理也是有狀態伺服器的一種。

 

在實際情況中,一些企業在對原有應用進行微服務改造,實現應用向雲平臺遷移的時候,並不是一個單純的微服務架構,而是一個使用微服務框架的微應用架構。

 

所謂的微應用架構,是由一個門戶應用和多個微應用組成的架構體系。每個微應用都是基於微服務框架的Web應用,擁有自己的Web頁面和邏輯程式碼。門戶應用通過Web頁面將所有微應用的頁面整合到一起,然後展現給使用者,為使用者提供服務。

 

因為每一個微應用都具有自己的Web頁面,這些Web頁面都會通過瀏覽器客戶端展現給使用者,整個微應用架構可以近似地看作是一個大型的分散式應用,所以每個微應用都需要有Session物件,同時整個微應用架構中,同一使用者的Session資料應該是一致的。

 


圖3  單體架構VS微應用

 

與上文所述的分散式架構相比,微服務微應用架構讓應用模組劃分更精細,每個微應用的大小合適,方便進行維護和管理。通過使用Devops平臺,可以讓模組的迭代開發和版本更新變得極為便捷。

 

微服務框架在降低企業應用開發運維成本的同時,也為微應用之間的Session共享帶來了挑戰,單體應用被拆分成了十幾個不同功能的微應用,分散式架構中的Session管理方案已經無法滿足於架構需求。那什麼樣的Session管理方案才是適合微服務架構的呢,這將是後文中需要思考和探討的。

 

 

微服務架構下分散式Session管理

 

在分散式架構中,Session管理方案是將使用者Session存放在Web伺服器記憶體中,然後通過Web伺服器的複製能力或者負載均衡器的請求分發能力來實現Session共享。但是在微服務架構的實踐中,企業對大型應用進行微服務改造,讓應用向雲環境遷移,通常會將應用拆分成十幾個甚至數十個微應用,如果仍然使用Session複製、粘滯,不但會帶來很多的不必要資源開銷,還會降低整個企業應用的可用性和安全性。

 

因此,在微服務架構下,對Session的管理應該另闢蹊徑,不再將Session物件儲存在Web伺服器記憶體中,而是在應用伺服器架構中引入獨立的中間儲存介質,將企業應用中的Session物件進行統一管理。

 


圖4  Session集中管理方案示意圖

 

一個好的Session集中管理方案應該具備以下特點。

A、中間儲存介質的讀寫速度要快。之前的Session管理方案將Session物件存放在伺服器記憶體中,有著很高的讀寫速度,進行Session集中管理後將會在Session讀寫中引入網路傳輸,速度會有所降低,所以必須保證中間儲存介質的讀寫速度。
B、中間儲存介質要保證高可用。進行Session集中管理後,整個企業應用的Session都會存放在中間儲存介質中,如果儲存介質是不穩定的,那整個企業應用都將不穩定。
C、對Session的使用者來說,Session管理方案應該是透明的,切換成集中管理方案後用戶無感知。

 

D、Session管理方案不該和某一Web伺服器耦合,應該適用於所有常規Web伺服器。

 

根據上述標準可以看出,Session集中管理方案的技術選型應該從Session儲存介質和管理方案實現兩方面考慮。

 

2.1 Session儲存介質

作為Session物件的儲存介質,對讀寫效能要求較高,所以應該擇快取伺服器作為Session的儲存介質。目前常用的快取伺服器有Memcache和Redis兩種,因此筆者對這兩種快取伺服器進行了比較。


由表中資料可以看出,雖然Redis的讀寫效能稍弱與Memcache,但是Redis支援的資料型別較多,而且支援資料持久化。

 

除此之外,Memcache使用Slab Allocation機制進行記憶體管理,其主要思想是按照預先規定的大小,將分配的記憶體分割成特定長度的塊以儲存相應長度的Key-Value資料記錄,以完全解決記憶體碎片問題。同時MemCached使用最近最少使用(LRU)演算法進行快取回收,並且Memcached的LRU演算法只是針對每個slab類執行,而不是針對整體。

 

這就意味著,如果所有Session的大小都大致相同,那麼他們將會被分成兩到三個slab類。所有其他大小差不多的資料也會被放入同一些slab中,將會與Session爭用儲存空間。一旦slab存滿了,即使還有著更大空間的slab,這些存放在已滿的slab中的資料還是會被回收,而不是放入更大的slab中。並且在特定slab中,相對而言最老的Session資料將會被Memcached清除,造成使用者掉線。

 

Redis在儲存回收策略上要比Memcache更適用於Session管理。Redis3.0版本之後,提供了良好的主從複製和叢集能力,能夠很好的保障Session資料的高可用。除此之外,Redis還有資料定期失效和訂閱通知的能力,可以為Session共享共很多有力的支撐。

 

2.2 管理方案實現

目前常用的Session集中管理方案有兩種,一種是Memcache-Tomcat-Session,另一種是Spring Session。

 

Memcache-Tomcat-Session是一個基於Memcache和Tomcat實現Session集中管理的開源方案。通過擴充套件Tomcat的SessionManager,並且在配置檔案中替換Tomcat預設的SessionManager來實現Session管理。雖然實現起來比較簡單,但是與Tomcat耦合,不適用於其他Web伺服器。

 

Spring Session是Spring提供的一套Session管理方案,通過一個SessionFilter將所有請求進行攔截,然後使用Request包裝類來接管Session管理。Spring Session不與Web伺服器耦合,能夠適用於常規的伺服器。同時還提供了統一瀏覽器多Session等功能。

 

Spring Session雖然優點頗多,但是實現Session管理功能的程式碼量也比較大,還需要配合Spring-data-redis使用,學習成本比較大,遇到問題不好維護。

 

 

三、微服務架構下分散式Session管理方案

 

經過上文的分析,在微服務架構中,使用Session集中管理的方式維護微應用的Session是比較好的選擇。因為在Session儲存介質上,Redis要比Memcache合適,所以使用Redis來集中存放微應用Session更為合適。在Session管理實現方案上,Spring Session的實現思路適用性較高,但是程式碼量大,學習和維護成本高,所以筆者認為參照Spring Session的思路,自己開發一套輕量級的程式碼是比較好的選擇。

 

經過設計,微服務架構中的Session集中管理示意圖如下。

 

圖5  Session集中管理方案示意圖

 

1、參照SpringSession的實現,使用SessionFilter進行請求攔截,然後通過Request包裝類接管Web伺服器的Session管理。在Request包裝類中,重寫getSession方法,Session使用方法和過去一樣,對使用者透明。

 

2、基於jedis開發一個分散式快取SDK模組,用於Session共享模組和Redis中間進行通訊,能夠增加Session集中管理的可擴充套件性,如果需要支援其他的快取伺服器,對快取SDK進行擴充套件開發即可。

 

3、搭建Redis叢集用於存放微應用Session,以保證Session資料的高可用。Redis叢集示意圖如下。

 

叢集中包含兩個Master和兩個Slave,兩個Master對Session資料進行分片儲存,而Slave可用於進行資料備份和讀寫分離。

 

 

 

 

總結

 

本文的主要目的在於對微服務架構下分散式Session管理方案進行探索與實踐。目前正處於微服務的時代,將會有越來越多的企業開始著手於企業應用的微服務改造,Session管理作為Web應用的基石之一,必然會是企業進行微服務改造時候首先需要考慮的問題之一。隨著應用架構的變遷,過去的Session管理方案,已經不能滿足於微服務架構的需求,必須尋求新的可行方案。

 

微服務架構下,整個應用被分割成了大量的小而相互關聯的微服務,Session管理需要另闢蹊徑,使用集中管理方案來代替原來將Session存放在Web伺服器本地快取的方案。通過向架構中引入高效能的快取伺服器,將整個微服務架構下的Session進行統一管理。

 

本文中對目前常用的兩個快取伺服器進行了對比,認為使用Redis進行Session的統一儲存較為合適。同時文中還對常用的兩種Session集中管理實現進行了比較,認為雖然Spring Session的實現方案比較好,但是學習成本較高,不便於維護,所以筆者決定參照Spring Session的實現原理,開發一套輕量級的Session管理方案。通過這套輕量級的Session管理方案,能夠很好地實現微服務架構下分散式Session的集中管理,並且對於Session的使用者來說,這套方案是完全透明的。