每一個不曾起舞的日子,都是對人生的辜負。
無狀態服務(Stateless Service): 是指該服務執行的例項不會在本地儲存需要持久化的資料,並且多個例項對於同一個請求響應的結果是完全一致的。 有狀態服務(Stateful Service): 是指該服務的例項可以將一部分資料隨時進行備份,並且在建立一個新的有狀態服務時,可以通過備份恢復這些資料,以達到資料持久化的目的。
無狀態服務可以有一個或多個例項,因此支援兩種服務容量調節模式;有狀態服務只能有一個例項,不允許建立多個例項,因此也不支援服務容量調節模式。
儘管有很多辦法可以同步和管理狀態,但是最好的方法是是避免它。會話和狀態破壞網際網路(SaaS、電子商務等)多租戶應用承諾的終極價值。在任何給定時間內,保留使用者互動的資料越多,系統能服務的使用者數量就越少。
在多使用者領域,目標是單個系統要服務儘可能多的使用者,同時仍然保持完美的使用者體驗。因此,我們力求解除系統對使用者數量的任何限制。狀態和會話耗費記憶體和處理能力,因此它們是以成本效益方式擴充套件時必須去除的部分。
有時狀態對業務很重要,如果狀態是必要的,我們需要以容錯、高可用和成本效益的方式實施,如把狀態分發到終端使用者或定位在基礎設施的某個特殊服務上。
力求無狀態
儘可能選擇無狀態實施方案,有狀態會限制可擴充套件性、降低可用性並增加成本。始終拒絕任何系統中對狀態的需求。採用業務指標和對比(A/B)測試來確定應用中的狀態是否真的會帶來可預見的使用者行為和業務價值。
如果確實需要狀態,可以採用狀態分佈,即把狀態移到瀏覽器或分散式狀態伺服器或快取中。
在瀏覽器中儲存會話資料
徹底避免會話資料,但需要時,在使用者的瀏覽器中使用cookie來儲存會話資料。這樣做的第一個好處是系統不需要儲存資料。第二個好處是來自瀏覽器的請求可以由池中的任何伺服器處理。
但是儲存會話狀態的一個缺點就是,資料必須在瀏覽器和需要此資料的伺服器之間來回傳輸。瀏覽器支援的cookie每塊最多是4KB,同一域名中最多有20塊cookie。但是cookie越多越大,頁面載入速度越慢,因為對每個請求該資料必須來回傳輸。另一個缺點就是cookie會洩露使用者的資訊HTTPS的SSL協議要求對所有的通訊加解密,可以使用兩個cookie,一個是授權cookie,要求對每個使用如下JavaScript呼叫的HTTP頁面都需要通過HTTPS來傳輸。這將允許大量頁面(內容、CSS、指令碼等)通過不安全的HTTP傳輸,而單一授權cookie通過HTTPS傳輸。
在實施時,控制cookie資料的大小至關重要。資料過多會降低頁面載入以及系統Web伺服器的效能。
用分散式快取處理狀態
當需要儲存會話資料但又不能在使用者的瀏覽器上儲存時,可以使用分散式快取在系統中儲存會話資料。
首先,遠離需要應用或Web伺服器黏性的有狀態系統。
其次,不要使用狀態或會話複製服務,例如那些執行在應用伺服器或第三方“叢集”伺服器上的服務。因為會話修改需要傳播到多個節點,所以這樣的系統根本無法擴充套件。
最後,在選擇會話快取或永續性引擎時,不要把快取放在執行實際工作的伺服器上。這有助於提高可用性,當某個伺服器宕機時,至少可以保證伺服器上於此關聯的快取和執行在上面的服務有一個倖存。建立快取層(或持久層)也使我們僅根據訪問快取去擴充套件,而不必同時考慮應用服務和內部及遠端的快取服務。
可以選擇分散式物件快取(Memcached)或第三方資料庫,作為會話資訊的快取解決方案。