天天看點

如何設計一個高可用系統?要考慮哪些地方?

一篇短小的文章,面試經常遇到的這個問題。本文主要包括下面這些内容:

  1. 高可用的定義
  2. 哪些情況可能會導緻系統不可用?
  3. 有些提高系統可用性的方法?隻是簡單的提一嘴,更具體内容在後續的文章中介紹,就拿限流來說,你需要搞懂:何為限流?如何限流?為什麼要限流?如何做呢?說一下原理?。

什麼是高可用?可用性的判斷标準是啥?

高可用描述的是一個系統在大部分時間都是可用的,可以為我們提供服務的。高可用代表系統即使在發生硬體故障或者系統更新的時候,服務仍然是可用的。

一般情況下,我們使用多少個 9 來評判一個系統的可用性,比如 99.9999% 就是代表該系統在所有的運作時間中隻有 0.0001% 的時間都是可用的,這樣的系統就是非常非常高可用的了!當然,也會有系統如果可用性不太好的話,可能連 9 都上不了。

哪些情況會導緻系統不可用?

  1. 黑客攻擊;
  2. 硬體故障,比如伺服器壞掉。
  3. 并發量/使用者請求量激增導緻整個服務宕掉或者部分服務不可用。
  4. 代碼中的壞味道導緻記憶體洩漏或者其他問題導緻程式挂掉。
  5. 網站架構某個重要的角色比如 Nginx或者資料庫突然不可用。
  6. 自然災害或者人為破壞。
  7. ......

有哪些提高系統可用性的方法?

1. 注重代碼品質,測試嚴格把關

我覺得這個是最最最重要的,代碼品質有問題比如比較常見的記憶體洩漏、循環依賴都是對系統可用性極大的損害。大家都喜歡談限流、降級、熔斷,但是我覺得從代碼品質這個源頭把關是首先要做好的一件很重要的事情。如何提高代碼品質?比較實際可用的就是 CodeReview,不要在乎每天多花的那 1 個小時左右的時間,作用可大着呢!

另外,安利這個對提高代碼品質有實際效果的寶貝:

  1. sonarqube :保證你寫出更安全更幹淨的代碼!(ps: 目前所在的項目基本都會用到這個插件)。
  2. Alibaba 開源的 Java 診斷工具 Arthas 也是很不錯的選擇。
  3. IDEA 自帶的代碼分析等工具進行代碼掃描也是非常非常棒的。

2.使用叢集,減少單點故障

先拿常用的 Redis 舉個例子!我們如何保證我們的 Redis 緩存高可用呢?答案就是使用叢集,避免單點故障。當我們使用一個 Redis 執行個體作為緩存的時候,這個 Redis 執行個體挂了之後,整個緩存服務可能就挂了。使用了叢集之後,即使一台 Redis 執行個體,不到一秒就會有另外一台 Redis 執行個體頂上。

3.限流

流量控制(flow control),其原理是監控應用流量的 QPS 或并發線程數等名額,當達到指定的門檻值時對流量進行控制,以避免被瞬時的流量高峰沖垮,進而保障應用的高可用性。——來自alibaba-Sentinel 的wiki。

4.逾時和重試機制設定

一旦使用者請求超過某個時間的得不到響應,就抛出異常。這個是非常重要的,很多線上系統故障都是因為沒有進行逾時設定或者逾時設定的方式不對導緻的。我們在讀取第三方服務的時候,尤其适合設定逾時和重試機制。一般我們使用一些 RPC  架構的時候,這些架構都自帶的逾時重試的配置。如果不進行逾時設定可能會導緻請求響應速度慢,甚至導緻請求堆積進而讓系統無法在處理請求。重試的次數一般設為3次,再多次的重試沒有好處,反而會加重伺服器壓力(部分場景使用失敗重試機制會不太适合)。

5.熔斷機制

逾時和重試機制設定之外,熔斷機制也是很重要的。熔斷機制說的是系統自動收集所依賴服務的資源使用情況和性能名額,當所依賴的服務惡化或者調用失敗次數達到某個門檻值的時候就迅速失敗,讓目前系統立即切換依賴其他備用服務。比較常用的是流量控制和熔斷降級架構是 Netflix 的 Hystrix 和 alibaba 的 Sentinel。

6.異步調用

異步調用的話我們不需要關心最後的結果,這樣我們就可以使用者請求完成之後就立即傳回結果,具體處理我們可以後續再做,秒殺場景用這個還是蠻多的。但是,使用異步之後我們可能需要 适當修改業務流程進行配合,比如使用者在送出訂單之後,不能立即傳回使用者訂單送出成功,需要在消息隊列的訂單消費者程序真正處理完該訂單之後,甚至出庫後,再通過電子郵件或短信通知使用者訂單成功。除了可以在程式中實作異步之外,我們常常還使用消息隊列,消息隊列可以通過異步處理提高系統性能(削峰、減少響應所需時間)并且可以降低系統耦合性。

7.使用緩存

8.其他

  1. 核心應用和服務優先使用更好的硬體
  2. 監控系統資源使用情況增加報警設定。
  3. 注意備份,必要時候復原。
  4. 灰階釋出: 将伺服器叢集分成若幹部分,每天隻釋出一部分機器,觀察運作穩定沒有故障,第二天繼續釋出一部分機器,持續幾天才把整個叢集全部釋出完畢,期間如果發現問題,隻需要復原已釋出的一部分伺服器即可
  5. 定期檢查/更換硬體: 如果不是購買的雲服務的話,定期還是需要對硬體進行一波檢查的,對于一些需要更換或者更新的硬體,要及時更換或者更新。
  6. .....(想起來再補充!也歡迎各位歡迎補充!)

總結