1. 程式人生 > 其它 >有狀態 & 無狀態

有狀態 & 無狀態

1. 什麼是服務中的狀態

有狀態和無狀態服務是兩種不同的服務架構,兩者的不同之處在於對於服務狀態的處理。

服務狀態是服務請求所需的資料,它可以是一個變數或者一個資料結構。無狀態服務不會記錄服務狀態,不同請求之間也是沒有任何關係;
而有狀態服務則反之。

對伺服器程式來說,究竟是有狀態服務,還是無狀態服務,其判斷依據——兩個來自相同發起者的請求在伺服器端是否具備上下文關係。

2.無狀態服務(常見JWT)

無狀態請求,伺服器端所能夠處理的資料全部來自於請求所攜帶的資訊,無狀態服務對於客戶端的單次請求的處理,不依賴於其他請求,處理一次請求的資訊都包含在該請求裡。最典型的就是通過cookie儲存token的方式傳輸請求資料。也可以理解為Cookie是通過客戶端保持狀態的解決方案。

3. 有狀態服務(常見redis模擬session儲存資訊)

有狀態服務則相反,服務會儲存請求上下文相關的資料資訊,先後的請求是可以有關聯的。例如,在Web 應用中,經常會使用Session 來維繫登入使用者的上下文資訊。雖然http 協議是無狀態的,但是藉助Session,可以使http 服務轉換為有狀態服務

 

==========

一、比較

有狀態服務常常用於實現事務(並不是唯一辦法,下文有另外的方案)。舉一個常見的例子,在商城裡購買一件商品。需要經過放入購物車、確認訂單、付款等多個步驟。

由於HTTP協議本身是無狀態的,所以為了實現有狀態服務,就需要通過一些額外的方案。比如最常見的session,將使用者挑選的商品(購物車),儲存到session中,當付款的時候,再從購物車裡取出商品資訊

 

服務要設計為無狀態的,這主要是從可伸縮性來考慮的。

如果server是無狀態的,那麼對於客戶端來說,就可以將請求傳送到任意一臺server上,然後就可以通過負載均衡等手段,實現水平擴充套件。

如果server是有狀態的,那麼就無法很容易地實現了,因為客戶端需要始終把請求發到同一臺server才行,所謂“session遷移”等方案,也就是為了解決這個問題

 

三、session和cookie

基於session和cookie都可以實現事務,可以認為,session是有狀態的,而cookie是無狀態的

四、無狀態實現事務的方法

並不是一定要用有狀態服務才能實現事務,本文提供另外的幾種方案作為參考

舉一個多次提交的場景作為例子:使用者需要提交很多資料,分為2個頁面提交

 

這裡就涉及到2次http請求,第一次提交欄位1、2、3,第二次提交欄位4、5、6

用session很容易實現這個需求,server只需要將第一次提交的資料,儲存在session裡,然後返回第2個表單作為相應;然後取出第一次提交的資料,和第二次提交的資料匯聚以後,一起存入資料庫即可

不用session同樣也可以實現,server接收到第一次請求以後,將資料作為隱藏元素,放在第2個表單裡返回;這樣使用者第2次提交的時候,就隱含地再次提交了第一次的資料;server將所有資料存入資料庫

用HTML5,則還可以進一步優化,client可以將第一次提交的資料,儲存在sessionStorage裡

用cookie也是類似的道理,同樣可以實現,但是不太好

總的來說,3種替代方案(隱藏表單元素、sessionStorage、cookie)都避免了在server端暫存資料,從而實現了stateless service。本質上,這3種方案的請求裡,都包含了所有必須的資料,符合本文一開始的定義

五、將有狀態服務轉換成無狀態服務

根據本文一開始的定義,除了將所有資訊都放在請求裡之外,還有另外一種方法可以實現無狀態服務,即將資訊放在一個單獨可共享的地方,獨立於server存在

比如,同樣還是採取session的方式,在服務端儲存資料,減少每次client請求傳輸的資料量(節省流量),但是將session集中存放,比如放在單獨的session層裡。這種情況下,server同樣是無狀態的,可以做水平擴充套件

 

六、總結

有狀態服務可以比較容易地實現事務,在不需要考慮水平擴充套件時,是比較好的選擇

無狀態服務的優勢在於可以很方便地水平伸縮,但是在實現事務時,需要做一些額外的動作

可以通過剝離session等方法,將一個有狀態服務,轉換成無狀態服務

 

 

注:什麼是事務?

事務,就是把一堆事情綁在一起做,都成功了才算完成,否則就恢復之前的樣子。

舉例:銀行ATM取錢,扣款成功後突然大停電,吐錢的操作還沒做,這時候就要恢復沒取錢時候的狀態,否則錢扣了還沒拿到手,多冤枉。

 

 

參考:https://www.cnblogs.com/hxm-35-Simle/p/11186600.html