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

本文已經收錄自筆者開源的 JavaGuide: github.com/Snailclimb (69k+Star【Java學習+面試指南】 一份涵蓋大部分Java程序員所須要掌握的核心知識)若是以爲不錯的還,不妨去點個Star,鼓勵一下!git

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

  1. 高可用的定義
  2. 哪些狀況可能會致使系統不可用?
  3. 有些提升系統可用性的方法?只是簡單的提一嘴,更具體內容在後續的文章中介紹,就拿限流來講,你須要搞懂:何爲限流?如何限流?爲何要限流?如何作呢?說一下原理?。

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

高可用描述的是一個系統在大部分時間都是可用的,能夠爲咱們提供服務的。高可用表明系統即便在發生硬件故障或者系統升級的時候,服務仍然是可用的。github

通常狀況下,咱們使用多少個 9 來評判一個系統的可用性,好比 99.9999% 就是表明該系統在全部的運行時間中只有 0.0001% 的時間都是可用的,這樣的系統就是很是很是高可用的了!固然,也會有系統若是可用性不太好的話,可能連 9 都上不了。面試

哪些狀況會致使系統不可用?

  1. 黑客攻擊;
  2. 硬件故障,好比服務器壞掉。
  3. 併發量/用戶請求量激增致使整個服務宕掉或者部分服務不可用。
  4. 代碼中的壞味道致使內存泄漏或者其餘問題致使程序掛掉。
  5. 網站架構某個重要的角色好比 Nginx 或者數據庫忽然不可用。
  6. 天然災害或者人爲破壞。
  7. ......

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

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

我以爲這個是最最最重要的,代碼質量有問題好比比較常見的內存泄漏、循環依賴都是對系統可用性極大的損害。你們都喜歡談限流、降級、熔斷,可是我以爲從代碼質量這個源頭把關是首先要作好的一件很重要的事情。如何提升代碼質量?比較實際可用的就是 CodeReview,不要在意天天多花的那 1 個小時左右的時間,做用可大着呢!spring

另外,安利這個對提升代碼質量有實際效果的寶貝:數據庫

  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。springboot

6.異步調用

異步調用的話咱們不須要關心最後的結果,這樣咱們就能夠用戶請求完成以後就當即返回結果,具體處理咱們能夠後續再作,秒殺場景用這個仍是蠻多的。可是,使用異步以後咱們可能須要 適當修改業務流程進行配合,好比用戶在提交訂單以後,不能當即返回用戶訂單提交成功,須要在消息隊列的訂單消費者進程真正處理完該訂單以後,甚至出庫後,再經過電子郵件或短信通知用戶訂單成功。除了能夠在程序中實現異步以外,咱們經常還使用消息隊列,消息隊列能夠經過異步處理提升系統性能(削峯、減小響應所需時間)而且能夠下降系統耦合性。

7.使用緩存

若是咱們的系統屬於併發量比較高的話,若是咱們單純使用數據庫的話,當大量請求直接落到數據庫可能數據庫就會直接掛掉。使用緩存緩存熱點數據,由於緩存存儲在內存中,因此速度至關地快!

8.其餘

  1. 核心應用和服務優先使用更好的硬件
  2. 監控系統資源使用狀況增長報警設置。
  3. 注意備份,必要時候回滾。
  4. 灰度發佈: 將服務器集羣分紅若干部分,天天只發布一部分機器,觀察運行穩定沒有故障,次日繼續發佈一部分機器,持續幾天才把整個集羣所有發佈完畢,期間若是發現問題,只須要回滾已發佈的一部分服務器便可
  5. 按期檢查/更換硬件: 若是不是購買的雲服務的話,按期仍是須要對硬件進行一波檢查的,對於一些須要更換或者升級的硬件,要及時更換或者升級。
  6. .....(想起來再補充!也歡迎各位歡迎補充!)

總結

如何設計高可用系統?

開源項目推薦

做者的其餘開源項目推薦:

  1. JavaGuide:【Java學習+面試指南】 一份涵蓋大部分Java程序員所須要掌握的核心知識。
  2. springboot-guide : 適合新手入門以及有經驗的開發人員查閱的 Spring Boot 教程(業餘時間維護中,歡迎一塊兒維護)。
  3. programmer-advancement : 我以爲技術人員應該有的一些好習慣!
  4. spring-security-jwt-guide :從零入門 !Spring Security With JWT(含權限驗證)後端部分代碼。

公衆號

相關文章
相關標籤/搜索