天天看點

分布式系統中的“無狀态”和“有狀态”無狀态有狀态從單機服務到叢集化總結

無狀态

無狀态的好處?

用戶端請求不依賴服務端的資訊,任何多次請求不需要必須通路到同一台服務

服務端的叢集和狀态對用戶端透明 =-服務端可以任意的遷移和伸縮 =-減小服務端存儲壓力

什麼是有狀态?

有狀态服務,即服務端需要記錄每次會話的用戶端資訊,進而識别用戶端身份,根據使用者身份進行請求的處理,典型的設計如 tomcat 中的 session。

例如登入:使用者登入後,我們把登入者的資訊儲存在服務端 session 中,并且給使用者一個 cookie 值,記錄對應的 session。然後下次請求,使用者攜帶 cookie 值來,我們就能識别到對應 session,進而找到使用者的資訊。

有狀态

什麼是有狀态?

有狀态服務,即服務端需要記錄每次會話的用戶端資訊,進而識别用戶端身份,根據使用者身份進行請求的處理,典型的設計如 tomcat 中的 session。

例如登入:使用者登入後,我們把登入者的資訊儲存在服務端 session 中,并且給使用者一個 cookie 值,記錄對應的 session。然後下次請求,使用者攜帶 cookie 值來,我們就能識别到對應 session,進而找到使用者的資訊。

有狀态的缺點是什麼?

• 服務端儲存大量資料,增加服務端壓力

• 服務端儲存使用者狀态,無法進行水準擴充

• 用戶端請求依賴服務端,多次請求必須通路同一台伺服器

狀态化的判斷是指兩個來自相同發起者的請求在伺服器端是否具備上下文關系。

如果是狀态化請求,那麼伺服器端一般都要儲存請求的相關資訊,每個請求可以預設地使用以前的請求資訊。

而無狀态的請求,伺服器端的處理資訊必須全部來自于請求所攜帶的資訊以及可以被所有請求所使用的公共資訊。

無狀态的伺服器程式,最著名的就是WEB伺服器。

狀态化的伺服器有更廣闊的應用範圍,比如MSN、網絡遊戲等伺服器。他在服務端維護每個連接配接的狀态資訊,服務端在接收到每個連接配接的發送的請求時,可以從本地存儲的資訊來重制上下文關系。

純函數式程式設計,就是無狀态的。有狀态,也叫有副作用。

無狀态的服務易伸縮: 很容易的通過給後端添加伺服器和前端的負載均衡實作橫向的擴充。

當系統中存在着大量「有狀态」的業務處理過程時,伸縮擴充就會變得複雜起來。

從單機服務到叢集化

建構單機服務非常簡單,但如果單機服務可靠性或性能不足,就需要多機器共同承擔某項服務。叢集化包含以下三種情況:

無狀态主備叢集

僅有一台主機完成任務,且沒有本地狀态,其餘從機機器待命,一旦主機當機,從機選主成為主機。

有狀态主備叢集

僅有一台主機完成任務,有本地狀态,其餘從機機器待命,一旦主機當機,從機選主成為主機。

無狀态的主從叢集

所有機器沒有本地狀态,理論上機器可以無限疊加,共同向外界提供同一服務。解決方案就是dubbo+zookeeper。

有狀态的主從叢集:

所有機器都有本地狀态,共同向外界提供同一服務。一旦某台機器當機,需要主機協調其他從機代理其本地狀态的任務。Paxos、raft和ZAB等一衆分布式一緻性算法的終極目标就是解決該問題。

總結

有狀态服務需要維護大量的資訊和狀态,在性能方面要稍遜于無狀态伺服器;

無狀态服務在處理簡單服務方面有優勢,服務之間沒有聯系,易于擴充,但處理複雜任務需要額外的元件來協助(以有狀态服務的形式實作)。

微服務要盡量做到無狀态,這樣可以橫向擴充。

狀态服務原則并不是說在微服務架構裡就不允許存在狀态,表達的真實意思是要把有狀态的業務服務改變為無狀态的計算類服務,那麼狀态資料也就相應的遷移到對應的 “有狀态資料服務” 中。

簡單舉例

例如我們以前在本地記憶體中建立的資料緩存、Session 緩存,到現在的微服務架構中就應該把這些資料遷移到分布式緩存中存儲,讓業務服務變成一個無狀态的計算節點。遷移後,就可以做到按需動态伸縮,微服務應用在運作時動态增删節點,就不再需要考慮緩存資料如何同步的問題。

繼續閱讀