狀態服務

一、定義

無狀態服務(stateless service)對單次請求的處理,不依賴其他請求,也就是說,處理一次請求所需的全部信息,要麼都包含在這個請求裏,要麼可以從外部獲取到(比如說數據庫),服務器本身不存儲任何信息

有狀態服務(stateful service)則相反,它會在自身保存一些數據,先後的請求是有關聯的

二、優劣

有狀態服務常常用於實現事務(並不是唯一辦法,下文有另外的方案)。舉一個常見的例子,在商城裏購買一件商品。需要經過放入購物車、確認訂單、付款等多個步驟。由於HTTP協議本身是無狀態的,所以爲了實現有狀態服務,就需要通過一些額外的方案。比如最常見的session,將用戶挑選的商品(購物車),保存到session中,當付款的時候,再從購物車裏取出商品信息

有狀態服務可以很容易地實現事務,所以也是有價值的。但是經常聽到一種說法,即server要設計爲無狀態的,這主要是從可伸縮性來考慮的。如果server是無狀態的,那麼對於客戶端來說,就可以將請求發送到任意一臺server上,然後就可以通過負載均衡等手段,實現水平擴展。如果server是有狀態的,那麼就無法很容易地實現了,因爲客戶端需要始終把請求發到同一臺server纔行,所謂“session遷移”等方案,也就是爲了解決這個問題

img

三、session和cookie

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

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

並不是一定要用有狀態服務才能實現事務,本文提供另外的幾種方案作爲參考
舉一個多次提交的場景作爲例子:用戶需要提交很多數據,分爲2個頁面提交

img

這裏就涉及到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同樣是無狀態的,可以做水平擴展

img

六、無狀態類

引申一下,JAVA裏有一種類的設計,可以稱爲無狀態類。這種類的特徵是隻有方法沒有字段,在三層架構(展現層、邏輯層、持久層)裏,邏輯層經常可以看到這種類
我覺得無狀態類和stateless server在思想上是一樣的,這個類本身是沒有狀態的,所以當外部要調用它的方法時,需要在方法參數中傳來所需的所有信息,不依賴該類自身的狀態(字段值),在併發環境下,可以避免多線程帶來的副作用

七、總結

有狀態服務可以比較容易地實現事務,在不需要考慮水平擴展時,是比較好的選擇
無狀態服務的優勢在於可以很方便地水平伸縮,但是在實現事務時,需要做一些額外的動作
比較好的選擇
無狀態服務的優勢在於可以很方便地水平伸縮,但是在實現事務時,需要做一些額外的動作
可以通過剝離session等方法,將一個有狀態服務,轉換成無狀態

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