天天看點

如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援

在公司做了一次高可用的分享,由于keynote的内容為大綱,特此加點注釋說明,分享給大家,水準有限,歡迎拍磚~~

如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援

分布式服務要素

如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援

分布式服務主要考慮如下幾點:

  • 性能

主要考慮名額: 響應時間,并發數,吞吐量

常用的手段

  • 壓縮,對傳輸資料進行壓縮(類似合并js,壓縮圖檔,減少cookie傳輸等前端手段),服務間傳遞序列化的算法
  • CDN,内容分發網絡,本質為緩存,将資料緩存在離使用者最近的地方,該服務一般由第三方供應商提供,應盡量避免回源
  • 分布式緩存,memcached,redis
  • 異步解耦,消息隊列
  • 資源複用,連接配接池,線程池
  • 叢集,避免單機負載過大
  • 存儲,ssd,ssd與機械硬碟的差別
  • 查詢優化,sql優化,搜尋引擎
  • 高可用

減少系統不可用的時間,作為基礎服務組需要優先考慮系統的高可用,本次主題,稍後詳解

  • 伸縮

可以通過添加/減少伺服器提高/降低服務的處理能力,無狀态的服務便于實作,主要靠各層次的負載均衡

  • 可拓展

在對現有系統影響較小的情況下,系統功能可持續拓展、提升的能力

  • 對業務進行拆分,遵循開閉原則,明确各業務邊界,例如将消息網管拆分為push,sms,email,如果揉合在一塊對功能拓展時影響較大
  • 服務間使用Restapi,各api引入版本的概念,高版本api相容低版本api,在拓展時不影響老業務
  • 消息隊列,消息解耦,不同業務按需訂閱對應消息,例如usercenter釋出使用者注冊消息,積分服務訂閱消息給新使用者贈送積分,郵件服務訂閱消息給使用者發送郵件,如新增一個為新使用者贈送還款金的服務,隻需要訂閱消息即可
  • 安全
  • 參數加簽,例如使用阿裡聚安全
  • 加密算法,消息摘要,對稱加密,非對稱加密
  • https,CA
  • 服務調用鑒權,openid,jwt

大綱

如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援

高可用

高可用的目标一般以n個9來表示,如4個9表示99.99% ,一年365*24*(1-99.99%) = 8.76 ,表示系統一年不可用時間不超過8.76個小時

一般通過服務備援加上故障轉移來實作應用的高可用,規避單點

一個使用者請求流程一般由圖(不是所有的應用都這樣,不同的公司架構存在差異)

如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援

用戶端到反向代理

如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援
  • 通過硬體F5實作硬負載,一台費用大概幾十萬,穩定可靠
  • nginx實作軟負載,nginx是高性能的HTTP和反向代理伺服器,

    nginx.conf,可以配置權重等額外參數

如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援

一般采用keepalived+vip實作nginx的高可用

域名通過dns解析得到ip,通過ARP(Address Resolution Protocol,位址解析協定,根據IP位址擷取實體位址的一個TCP/IP協定)清單擷取對應服務的mac位址,進而通路對應服務,通過vip對外提供服務,vip對應的mac位址為主節點的mac位址,備節點通過keepalived來檢測主節點是否可用,如不可用會廣播消息,使得vip對應的mac位址替換為備節點的mac位址

同城雙活

通過nginx也可以實作針對域名通路的接口實作同城多活,如果采用服務發現的方式需要存在多資料中心,能跨資料中心實作服務發現

如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援
upstream test {
server 10.0.40.126:80 max_fails=1 fail_timeout=30s;
server 10.0.40.124:80 backup;
}
           

Gateway & Services

如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援

Gateway也可以了解為一個微服務,是以統一讨論

負載均衡

實作軟負載均衡,核心有三點:

  • 服務發現,發現依賴服務的清單
  • 服務選擇規則,在多個服務中如何選擇一個有效服務
  • 服務檢測,檢測失效的服務,高效剔除失效服務

ribbon為典型的案例

服務發現與注冊

consul,zk,dubbo

  • consul是一個集服務發現與注冊、配置、健康檢查、多資料中心的工具
  • zookeeper是分布式應用程式協調服務,類Unix檔案系統路徑的層級結構,通過臨時節點+監聽可以實作豐富的功能
  • dubbo是功能豐富分布式服務架構,服務治理,國内應用廣泛

服務發現是采用推還是拉?

當有節點在服務注冊中心加入/移除時,注冊中心需要主動将消息推給該節點對應的Client端

優點:

服務端的請求壓力小,隻有在服務變更時需要推送消息

缺點:

該模式下每個服務需要和注冊中心維護一個長連接配接,定時心跳,fd預設為1024,最大65535,需要使用nio多路複用,實作技術上比較複雜 

各服務節點主動去注冊中心輪詢,通過定時任務去實作

優點:

實作簡單,适合服務數量較少的情況

缺點:

每個服務都在定時的輪詢,注冊中心壓力大,為降低注冊中心的壓力,可以考慮若幹服務通過一個agent去請求注冊中心,整個叢集中由若幹個agent去注冊中心請求,consul就可以實作類似的方式

服務選擇

在擷取調用服務清單以後最終調用哪個服務呢? 這就需要進行服務的選擇,常見的做法有如下幾種:

  • 輪詢
  • 權重輪詢
  • 随機
  • 最少連接配接
  • ip進行hash
  • 動态權重

在我所在公司實際應用中各服務機器性能都差不多,一般采用輪詢的方式,輪詢實作起來簡單,但不适合各機器性能不一緻的情況

動态權重用的也比較頻繁

在Client端記錄各服務的權重,初始服務權重為100,每成功請求一次後權重加1,但不超過100,每失敗一次權重減10,權重最小為0,在連續失敗幾次以後為防止用戶端的請求壓垮服務端,可考慮間隔若幹時間不配置設定請求到該服務,如果權重為0,可以考慮間隔一定時間釋放一個請求過去看看服務是否恢複

服務檢測

服務檢測一般為定時的異步任務,可以簡單采用ping、pong的方式檢測服務是否存活,如果服務失效,則從服務清單中剔除

服務檢測一般有以下集中方式:

  • 向注冊中心發起請求檢測
  • Client直連服務端檢測

在spring-boot預設暴露health的endpoint,采用spring-boot的工程都可以利用這一點

為了能正确的檢測到服務端的狀态,可以考慮采用自定義的健康檢查,因為通常健康檢查都采用判斷服務的程序以及端口是否存活,這種判斷是粗糙的;例如Client強依賴後端的資料庫,如果資料庫當機,Client對應的服務都無效,此時服務端如果程序和端口存活但資料庫挂了,健康檢查還判斷服務存活顯然是不合理

服務保護

如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援

服務熔斷和降級

  • 熔斷 不應信任其所有的依賴服務,采用線程池或信号量來實作服務的熔斷 hystrix典型,也可以參考我實作的一個熔斷小元件

   https://github.com/liaokailin/circuit-breaker

  • 降級 服務層面,存留核心服務,降級非核心服務 ;方法層面,實作降級方法,在服務不可用或被熔斷後進入降級方法; 業務層面,存留核心業務

服務過載保護

  • 動态權限
  • 限流 令牌桶、漏桶、計數 令牌桶可以允許小型的波峰,漏桶是固定的流速,計數比較簡單,可以參考我實作的一個限流小組元件

    https://github.com/liaokailin/rate-limiter

  • 節流

Cache

如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援
  • redis與memcached的差別
redis
    string list hash set sorted set
    分布式鎖 setnx
memcached 
   string
   slat_class slat chunk
           
  • 分布式

redis叢集+master/slave,采用16384slot,通過Client去定位slot; memcached靠一緻性hash算法 

  • 緩存一緻性

消息隊列

如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援
  • Kafka與Rabbitmq

異步解耦的神器

  • kafka 具有高的吞吐量,consumer根據消費的offset,從broker上批量pull資料;無消息确認機制

topic -> partition->segement

  • RabbitMQ在吞吐量方面稍遜于kafka,他們的出發點不一樣,rabbitMQ支援對消息的可靠的傳遞,支援事務,不支援批量的操作

 vhost exchange binding queue

     fanout 廣播

     direct 按照routing key比對

     topic 模糊比對

     header

  • 分布式

Rabbitmq 鏡像隊列,主queue失效,miror queue接管 kafka的broker支援主備模式,采用zookeeper對叢集中的broker、consumer進行管理

Database

如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援
  • 高可用

    MHA(Master High Availability)目前在MySQL高可用方面是一個相對成熟的解決方案

  • 多主備+vip
  • 複制政策

半同步複制,全同步複制,異步複制

  • 讀寫分離 主寫從讀,冷熱隔離,分表政策

讀寫一緻性,不一緻是因為寫完成後,主從同步存在時間差,解決方案: 

  1. 半同步複制 ,原生功能,簡單;寫請求時延會增長,吞吐量會降低
  2. 讀主庫,不建議的操作,如果非要用需盡量減少讀操作,例如cache 
  3. 緩存寫key 
  4. 中間件

監控

  • 日志分析 elk接入
  • metrics prometheus
  • 應用監控 cat health endpoint 分布式定時任務排程(重試,幂等)
  • 鍊路監控 zipkin
  • 伺服器監控 zabbix

無損釋出

保證節點無流量後進行發版更新

分布式一緻性

這屬于額外的話題 cap理論,反acid模型的base理論,

兩階段送出協定(2PC),基于微服務的應用一般都使用SQL和NoSQL結合的模式,這些非關系型資料大多數并不支援2PC,分布式大部分追求最終一緻性

實作最終一緻性:

  • 可靠事件模式
  • 業務補償模式
  • TCC模式
  • 對賬
如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援

轉載請注明

http://blog.csdn.net/liaokailin/article/details/66049607

歡迎關注,您的肯定是對我最大的支援

如何建構高可用的分布式系統歡迎關注,您的肯定是對我最大的支援

繼續閱讀