談談業務中使用分佈式的場景.

1. 談談業務中使用分佈式的場景.

首先, 需要連接系統爲什麼使用分佈式.
隨着互聯網的發展, 傳統的單體項目的性能瓶頸越發凸顯, 性能瓶頸可能存在於一下幾個方面:

  • 應用服務層: 隨着用戶量的增加, 併發量增加, 單體項目難以承受如此之大的併發請求導致的性能瓶頸.
  • 底層數據庫層: 隨着業務的發展, 數據庫的壓力也越來越大, 導致的性能瓶頸.

場景1: 應用系統集羣的Session共享.

應用系統集羣最簡單的就是服務器集羣, 比如: Tomcat集羣. 應用系統集羣的時候, 比較凸顯問題的就是Session共享, Session共享我們一是可以通過服務器插件去解決, 另一種也可以通過Redis等中間件解決( 一般採用Redis中間件, 使用服務器插件複製的話 將Session實時同步到每一個服務器上, 這樣只能支持Session數量比較少的情況, 使用Redis中間件存儲的話, 性能比較高, 而且穩定性也更好. ).

場景2: 應用系統的服務拆分.

服務化拆分, 是目前比較火熱的一種方式. 現在都在說微服務. 通過對傳統項目進行服務化拆分, 達到服務獨立解耦, 單服務又可以橫向擴容. 服務化拆分遇到的經典問題就是分佈式事務問題. 目前, 比較常用的分佈式事務解決方案有幾種: 消息最終一致性, TCC補償性事務等.

場景3: 底層數據庫的壓力分攤

如果系統的性能壓力出現在數據庫我們就可以採用讀寫分離, 分庫分表等方案進行解決.

2. Session分佈式方案

這裏只介紹常用的兩種.

2.1 基於Cookie的Session共享

將用戶的session加密序列化之後, 以Cookie的方式保存在網站的根域名之下, 當用戶訪問所有二級域名的時候, 留戀其會傳遞所有匹配的根域名的Cookie信息, 這樣實現了用戶Cookie化Session的多服務共享. 此方案能夠節省大量的服務器資源, 缺點是存儲的信息長度將會受到http協議限制, 而且一個站點只能保存大約20條Cookie, 而且每次請求的時候都會帶上session, 這樣的話會造成一定的網絡帶寬浪費.

2.2 基於Redis的Session共享存儲

這些鍵值對非關係型數據庫有較高的性能, 可以輕鬆打到2000qps, 內置的過期機制正好滿足Session的時效性特徵.

在單獨的服務器或者是服務器集羣上使用緩存技術, 使用Redis存儲Session數據, 幾種管理所有的Session, Redis可以做高可用集羣, 所有的Web服務器都從這個存儲介質中讀取相應的Session, 實現Session共享.

  • 優點: 可靠性高, 在遇到性能瓶頸的時候可以橫向擴展.
  • 缺點: 實現略微複雜.
  • 適用場景: Web服務器比較多, 可用性要求很高的狀態.
  • 可用方案: 開源方案Spring Session, 也可以自己實現.

3. 分佈式鎖的場景和實現.

使用場景

首先, 我們看這樣一個場景, 客戶下單的時候, 我們調用庫存中心進行減庫存, 那麼我們的一般操作就是;

update store set num=${num} where id = ${id} 

這種通過設置庫存方式的修改, 我們知道在併發量比較高的時候回存在數據庫的丟失更新, 如果A,B兩個事物, 查詢出來的庫存都是5, a下了三個單子吧庫存改爲2, b下了一個單子將庫存改爲4, 這個時候出現了a回覆蓋b的更新. 最終結果出現錯誤, 剩餘庫存爲2.

這個時候我們需要採取CAS樂觀鎖去解決這個問題.
這裏的CAS不需要考慮ABA問題, 因爲即使這個時候加了庫存, 中間發生了變化, 但是對於最終結果是不會產生影響的.

update store set num = ${num} where id = ${id} and num = ${query_num}

這個是隻更新一個表, 如果牽扯到多個表呢, 我們希望和這個單子關聯的所有的表同一時間只能被一個線程來處理更新, 多個線程按照不同的順序去更新同一個單子關聯的不同數據的時候, 出現死鎖的概率比較大. 如果是分佈式項目的話, 我們需要保證多線程多進程同時只能有一個進行的一個線程去處理, 這個時候我們就需要用到分佈式鎖. 分佈式鎖的實現方式有很多種, 我們今天分別通過,Zookeeper, Redis以及Tair的實現邏輯.

Zookeeper實現

獲取鎖

  1. 現有一個鎖根節點, lockRootNode, 這可以是一個永久的根節點.
  2. 客戶端獲取鎖, 現在lockRootNode下面創建一個順序的瞬時節點, 保證客戶端斷開連接, 節點也自動刪除.
  3. 調用lockRootNode父節點的getChildren()方法, 獲取所有的根節點, 並從小到大排序, 如果創建的最小的節點是當前節點, 則返回true, 獲取鎖成功.
  4. 談談業務中使用分佈式的場景.

首先, 需要連接系統爲什麼使用分佈式.
隨着互聯網的發展, 傳統的單體項目的性能瓶頸越發凸顯, 性能瓶頸可能存在於一下幾個方面:

應用服務層: 隨着用戶量的增加, 併發量增加, 單體項目難以承受如此之大的併發請求導致的性能瓶頸.
底層數據庫層: 隨着業務的發展, 數據庫的壓力也越來越大, 導致的性能瓶頸.
場景1: 應用系統集羣的Session共享.

應用系統集羣最簡單的就是服務器集羣, 比如: Tomcat集羣. 應用系統集羣的時候, 比較凸顯問題的就是Session共享, Session共享我們一是可以通過服務器插件去解決, 另一種也可以通過Redis等中間件解決( 一般採用Redis中間件, 使用服務器插件複製的話 將Session實時同步到每一個服務器上, 這樣只能支持Session數量比較少的情況, 使用Redis中間件存儲的話, 性能比較高, 而且穩定性也更好. ).

場景2: 應用系統的服務拆分.

服務化拆分, 是目前比較火熱的一種方式. 現在都在說微服務. 通過對傳統項目進行服務化拆分, 達到服務獨立解耦, 單服務又可以橫向擴容. 服務化拆分遇到的經典問題就是分佈式事務問題. 目前, 比較常用的分佈式事務解決方案有幾種: 消息最終一致性, TCC補償性事務等.

場景3: 底層數據庫的壓力分攤

如果系統的性能壓力出現在數據庫我們就可以採用讀寫分離, 分庫分表等方案進行解決.

  1. Session分佈式方案

這裏只介紹常用的兩種.

2.1 基於Cookie的Session共享

將用戶的session加密序列化之後, 以Cookie的方式保存在網站的根域名之下, 當用戶訪問所有二級域名的時候, 留戀其會傳遞所有匹配的根域名的Cookie信息, 這樣實現了用戶Cookie化Session的多服務共享. 此方案能夠節省大量的服務器資源, 缺點是存儲的信息長度將會受到http協議限制, 而且一個站點只能保存大約20條Cookie, 而且每次請求的時候都會帶上session, 這樣的話會造成一定的網絡帶寬浪費.

2.2 基於Redis的Session共享存儲

這些鍵值對非關係型數據庫有較高的性能, 可以輕鬆打到2000qps, 內置的過期機制正好滿足Session的時效性特徵.

在單獨的服務器或者是服務器集羣上使用緩存技術, 使用Redis存儲Session數據, 幾種管理所有的Session, Redis可以做高可用集羣, 所有的Web服務器都從這個存儲介質中讀取相應的Session, 實現Session共享.

優點: 可靠性高, 在遇到性能瓶頸的時候可以橫向擴展.
缺點: 實現略微複雜.
適用場景: Web服務器比較多, 可用性要求很高的狀態.
可用方案: 開源方案Spring Session, 也可以自己實現.

  1. 分佈式鎖的場景和實現.

使用場景

首先, 我們看這樣一個場景, 客戶下單的時候, 我們調用庫存中心進行減庫存, 那麼我們的一般操作就是;

update store set num=${num} where id = ${id}
這種通過設置庫存方式的修改, 我們知道在併發量比較高的時候回存在數據庫的丟失更新, 如果A,B兩個事物, 查詢出來的庫存都是5, a下了三個單子吧庫存改爲2, b下了一個單子將庫存改爲4, 這個時候出現了a回覆蓋b的更新. 最終結果出現錯誤, 剩餘庫存爲2.

這個時候我們需要採取CAS樂觀鎖去解決這個問題.
這裏的CAS不需要考慮ABA問題, 因爲即使這個時候加了庫存, 中間發生了變化, 但是對於最終結果是不會產生影響的.

update store set num = ${num} where id = ${id} and num = ${query_num}
這個是隻更新一個表, 如果牽扯到多個表呢, 我們希望和這個單子關聯的所有的表同一時間只能被一個線程來處理更新, 多個線程按照不同的順序去更新同一個單子關聯的不同數據的時候, 出現死鎖的概率比較大. 如果是分佈式項目的話, 我們需要保證多線程多進程同時只能有一個進行的一個線程去處理, 這個時候我們就需要用到分佈式鎖. 分佈式鎖的實現方式有很多種, 我們今天分別通過,Zookeeper, Redis以及Tair的實現邏輯.

Zookeeper實現

獲取鎖

現有一個鎖根節點, lockRootNode, 這可以是一個永久的根節點.
客戶端獲取鎖, 現在lockRootNode下面創建一個順序的瞬時節點, 保證客戶端斷開連接, 節點也自動刪除.
調用lockRootNode父節點的getChildren()方法, 獲取所有的根節點, 並從小到大排序, 如果創建的最小的節點是當前節點, 則返回true, 獲取鎖成功.

搜索文件

  1. 談談業務中使用分佈式的場景.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章