淺談高可用和設計的一些原則(JAVA)

ohcomeyes發表於2018-10-30

前言

上文說到了關於高併發的一些原則及設計,這篇主要是講講關於高可用這一塊,畢竟都是難兄難弟,誰也離不開誰。

關於高可用? 高可用的本質就是對系統的不確定性做預期準備,來保證服務的健康,包括經常聽到的資料丟失、容災、故障等除了不可抗因素外,要達到所謂衡量標準的N個9。 關於N個9的計算方式,例如3個9:(1-99.9%) * 365 * 24=8.76小時,表示該軟體系統在連續執行1年時間裡最多可能的業務中斷時間是8.76小時。

設計高可用原則

  1. **降級:**總的來說就是保障資料最終一致性,分散流量,提前預處理或分散處理,前面文章裡面說到的Hystrix熔斷就是實現服務降級與依賴隔離,對訪問down服務進行隔離丟給降級後的服務處理,防止影響到其它服務。這裡說的是服務/業務方面的降級,當然還有很多其它方面。例如:

    降級

    • 超時降級:類似推薦或者評論啊,暫時不展示或者暫未更新對整體不會有太大的影響。
    • 依賴降級:針對的是一些外部服務,一些不穩定的API。
    • 故障降級:網路、RPC服務等掛掉了,處理方案可以通過快取、預設值、兜底資料來保障。
    • 限流降級:針對一些超大流量做友好處理。
  2. **隔離:**將系統或資源分開,服務之間都是有依賴的,很容易因一方面服務故障導致滾雪球,隔離能夠保障其它服務不會受影響,把問題控制並降低。

    • 執行緒隔離:請求分類,不影響其它分類執行緒池的正常執行。
      執行緒隔離
    • 程式隔離:物理分離,部署多個例項,通過負載均衡路由轉發,但是更好的解決方案是將系統拆分為多個子系統來實現隔離。
    • 讀寫隔離:類似Redis就可用通過主從複製模式將讀和寫進行叢集分離。
    • 動靜隔離:前面說的高併發也提到過,都是相輔相成的,把動態內容和靜態資源分離,靜態資源可用提前做快取。
    • 爬蟲隔離:主要是為了防止惡意請求流量,會導致正常流量不可用,所以一方面可用通過限流解決,一方面可用將爬蟲單獨路由到單獨服務上,或者讓爬蟲只能訪問到cache。
    • 熱點隔離:熱點一般都是能夠提前預知的,比如秒殺、搶購、大降價等,最好是做成獨立系統或者服務進行隔離,也可用通過快取和佇列來進行削峰。
  3. **限流:**限流主要是防止流量超出系統峰值,是限制流量穿透到後端薄弱的應用層,這個可用從多個方面考慮;最終做到有損服務而不是不服務。常用的限流演算法有令牌桶、漏桶等。

    • 限制併發/連線/請求數:系統都是由閥值(TPS/QPS)的,超過了要麼非常慢,要麼直接被擊垮。
    • 時間內/平滑限流:限制時間內的請求次數,或者每隔多長時間處理一個請求。
    • 接入層限流:接入層也就是請求流量的入口,像Nginx自帶的兩個模組就可以,連線數限流模組和請求限流模組。
  4. **分流:**引流就是當某個服務掛了或者某個地方故障了需要把流量引向其他好的服務或者備用服務上去。

    • 負載均衡與反向代理
  5. **超時與重試機制:**設定超時能夠避免慢請求累積導致系統雪崩,需要設定合理的重試機制,並且應該和熔斷、快速失敗機制配合。

  6. **回滾:**當程式或者資料出錯,可用通過回滾恢復到最近的一個正確版本上,比如事務回滾、程式碼庫回滾、更新版本回滾、資料庫回滾、靜態資源回滾等等。

  7. **壓測與預案:**評估系統的穩定性和效能,提前做好應急預案。

總結來說通過降級保證服務有損而不是不可用,通過限流保護服務健康避免雪崩,通過分流與隔離保障服務正常並能夠對故障實行隔離,設定合理的超時與重試機制避免請求堆積,通過回滾能夠快速修復。做到這些往往能實現系統的高可用。

附上設計例圖:

高可用

結語

關於例圖裡面的一些詳細示例以後再慢慢補充吧!
推薦:淺談高併發和設計的一些原則(JAVA)
個人部落格~
簡書~

相關文章