有狀態、無狀態

上一期從線程安全的角度聊了聊系統設計要注意的事情,這次換個角度繼續聊聊系統設計
這次主題圍繞系統設計:有狀態、無狀態

慣例,先看栗子

網站登錄校驗,很普通的一個功能
對於這個功能我們要如何實現?

先分析一下登錄校驗是個啥意思
舉個栗子,比如我們在登陸頁輸入用戶名密碼,登錄了社交網站
這時候想去看自己的新鮮事,卻告訴我請先輸入用戶名密碼進行驗證。。
這時候想去吐槽下這個2B體驗,發個新鮮事,點完發佈按鈕時,又彈出框說請輸入用戶名密碼進行驗證。。。這時候腦子裏上千個草泥馬奔騰而過

這樣的產品可以說拜拜了

對我們的用戶來說,登錄操作其實完成一次就夠了,後續的操作服務應該能夠自動識別出是這個合法用戶
因此,我們就需要對用戶的狀態進行記錄,後續直接在後臺裏自動幫用戶進行校驗

OK,需求分析完了,那該怎麼實現呢?

in the old time
我們直接通過session的方式,單機時代很方便,也夠用了


這裏寫圖片描述
用戶登錄後我們通過session來保存,簡單高效,done

隨着用戶量和訪問量的增大,單機似乎不夠用了,加一臺機器吧
這時候也引入了負載均衡服務,對應用服務器上的session也增加了同步的邏輯


這裏寫圖片描述
比以前稍稍複雜了些,但也還好。但是如果用戶量不斷增加,訪問量不斷變多
繼續加應用服務器,加一臺,兩臺。。十臺。。。?
這個session同步機制怎麼保證依然快速有效?
這麼大量的數據同步,帶寬資源的消耗很可觀啊
另外,N臺應用服務器都有相同的session副本,這是對內存資源的極大糟蹋啊

那麼有沒有更加優雅的方案呢?

這裏舉一個方案
採用cookie + session服務器的方案


這裏寫圖片描述
1.用戶在登錄頁完成登錄操作後,服務器會生成一個登錄session信息,保存起來,設置個失效時間,並設置到用戶的cookie裏
2.用戶後續的每次請求裏會帶着這個cookie信息,服務端會對這個cookie信息進行校驗,通過了就認爲是合法用戶,執行請求操作

這個方案的好處比較明顯
應用服務器變成無狀態了,對session的統一管理由專門的服務來處理

引出了今天的主題:有狀態和無狀態

什麼是有狀態和無狀態
這個話題結合系統設計,拿應用服務器來說會容易理解

像剛纔介紹的,應用服務器裏持有用戶的session,這時應用服務器是有狀態的
因爲保存了用戶會話這個上下文信息,後續的用戶請求都會需要訪問這個session信息
多個應用服務器之間是副本的關係,需要保持session數據的同步

無狀態的應用服務器,像剛纔把session挪出應用服務器,由專門的服務進行管理
此時應用服務器不保存上下文信息,只負責對用戶的每次請求提交數據進行處理然後返回處理結果
無狀態應用服務器之間是對等的關係,無依賴,請求到哪個服務器,處理結果都一樣的

有狀態的服務,會有比較明顯的缺點,服務間數據需要同步,成爲副本關係,邏輯複雜也浪費資源
相對來說,無狀態的服務,就會簡單多了
可以來做個比較


這裏寫圖片描述

對於高可用服務的構建要求來說,快速failover以及快速擴容是非常重要的
服務有狀態,服務當機就可能會存在數據丟失
關鍵是快速擴容,有狀態服務會有冷啓動的問題,還需要先加載數據才能對外提供服務,太麻煩了

所以大家在進行系統設計時,時刻要有這個意識,我們的應用服務器,要設計成無狀態
不保存任何上下文信息

拓展學習: CAP理論
其實有狀態服務也有其自身的好處,數據狀態在服務中保存,無需額外的調用,低延遲
不需要額外的存儲,服務本身已經存了

關於構建可伸縮的有狀態服務,可以看下這篇文章的介紹
http://www.infoq.com/cn/news/2015/12/scaling-stateful-services

如果要構建有狀態的服務,那就有必要了解CAP理論了
先看下維基百科對CAP的介紹:
In theoretical computer science, the CAP theorem also known as Brewer’s theorem, states that it is impossible for a distributed computer system to simultaneously provide all three of the following guarantees

    Consistency (all nodes see the same data at the same time)
    Availability (a guarantee that every request receives a response about whether it succeeded or failed)
    Partition tolerance (the system continues to operate despite arbitrary partitioning due to network failures)

大名鼎鼎的CAP理論的意思是說,一個分佈式系統無法同時滿足三個條件
一致性、可用性、分區容忍性

一致性,數據要保證一致,保證準確性
可用性,我們的服務要保證24小時可用
分區容忍性,訪問量太大了,要擴容,體現爲系統的可伸縮性了,部署多個實例或副本

但是呢,擴容了,保證了可用性,數據一致性怎麼保證?
副本這麼多,同步機制太難做好了。有個經典有趣的問題:拜占庭將軍問題,感謝可以去了解

互聯網公司一般會選擇保證AP,保證高可用,但是一致性呢,該怎麼辦
CAP理論並不完全適用於指導實際的工程開發,所以對於一致性,一般會這樣去考慮

強一致性,必須保證一致性,任意時刻都能讀到最新值。這個,呵呵
弱一致性,寫入新值後,在副本上可能讀出來,也可能讀不出來
最終一致性,在某個時間後,能夠讀到最新的值

CAP理論相關的知識涉及面比較廣,大家感興趣可以多看看,這裏就先介紹到這裏
左耳朵耗子有篇文章,對分佈式系統的理論進行了些介紹,感興趣可以看看
http://coolshell.cn/articles/10910.html

最後回到今天的主題,我們在系統設計上,遵循的原則還是簡單爲主
通過簡單的設計來滿足我們的業務需求
如何簡單?非特殊情況,都設計成無狀態的吧

最後再補充個題外話:
開頭所講的栗子裏提到使用cookie,這個可能會存在安全的問題
比如XSS,跨站腳本攻擊。可能會導致cookie信息被竊取,所以需要對XSS進行安全防護了
web安全又是一大塊知識啊,感興趣可以自己深入學習
————————————————
版權聲明:本文爲CSDN博主「zhoumingp」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/zhoumingp/article/details/50457203

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