【轉】如何建設高可用系統

weixin_34391854發表於2018-09-17

“高可用性”(High Availability)通常來描述一個系統經過專門的設計,從而減少停工時間,而保持其服務的高度可用性。以下是高可用系統的設計建議:

 

減少單點

去單點首先要識別整個系統所有主鏈路的單點,如機房(同城異地雙機房),應用伺服器,DNS伺服器,SFTP伺服器,LBS,快取伺服器,資料庫,訊息伺服器,代理伺服器和專線等,如系統通過專線呼叫對方服務,需要考慮同時拉聯通和電信的專線,聯通或電信的專線還是有一定概率會出現問題的,但是同時出問題的概率會小非常多。優先使用軟負載,使用硬負載兜底。

 

減少依賴

減少DNS依賴,減少遠端服務依賴,DNS依賴可以嘗試設定本地host,用工具給所有伺服器推送最新的域名對映關係,通過本地快取或近端服務減少RPC呼叫。

 

限制迴圈

避免無限死迴圈,導致CPU利用率百分百,可以設定for迴圈的最大迴圈次數,如最大迴圈1000次。

 

控制流量

避免異常流量對應用伺服器產生影響,可以對指定服務設定流量限制,如QPS,TPS,QPH(每小時總請求量)和QPD(每天總請求量)。

 

精準監控

對CPU利用率,load,記憶體,頻寬,系統呼叫量,應用錯誤量,PV,UV和業務量進行監控,避免記憶體洩露和異常程式碼對系統產生影響,配置監控一定要精準,如平時記憶體利用率是50%,監控可以配置成60%進行報警,這樣可以提前感知記憶體洩露問題,避免應用無響應。

 

無狀態

伺服器不能儲存使用者狀態資料,如在叢集環境下不能用static變數儲存使用者資料,不能長時間把使用者檔案存放在伺服器本地。伺服器有狀態會難以擴容,且出現單點問題。

 

容量規劃

定期對容量進行評估。如大促前進行壓測和容量預估,根據需要進行擴容。

 

功能開關

開啟和關閉某些功能,比如訊息量過大,系統處理不了,把開關開啟後直接丟棄訊息不處理。上線新功能增加開關,如果有問題關閉新功能。

 

設定超時

設定連線超時和讀超時設定,不應該太大,如果是內部呼叫連線超時可以設定成1秒,讀超時3秒,外部系統呼叫連線超時可以設定成3秒,讀超時設定成20秒。

 

重試策略

當呼叫外部服務異常時可以設定重試策略,每次重試時間遞增,但是需要設定最大重試次數和重試開關,避免對下游系統產生影響。

 

隔離

應用隔離,模組隔離,機房隔離和執行緒池隔離。可以按照優先順序,不變和變幾個維度來隔離應用和模組,如抽象和不變的程式碼放在一個模組,這個模組的程式碼幾乎不會修改,可用性高,經常變的業務邏輯放在一個模組裡,這樣就算有問題,也只會影響到某一個業務。不同的業務使用不同的執行緒池,避免低優先順序任務阻塞高優先順序,或高優先順序任務過多時影響低優先順序任務永遠不會執行。

 

非同步呼叫

同步呼叫改成非同步呼叫,解決遠端呼叫故障或呼叫超時對系統的影響。

 

熱點快取

對熱點資料進行快取,降低RPC呼叫。如B系統提供名單服務,B系統可以提供一個client SDK提供近端快取服務,定期去伺服器端取資料,減少RPC呼叫。
快取容災 – 當資料庫不可用時可以使用快取的資料。並設定分級快取,如優先讀本地快取,其次讀分散式快取。

 

分級快取

優先讀本地快取,其次讀分散式快取。通過推模式更新本地快取。

 

系統分級

對系統進行分級,如ABC三個等級,高階別系統不依賴於低階別系統,並且高階別系統比底級別系統高可用率要高。

 

服務降級

如果系統出現響應緩慢等狀況,可以關閉部分功能,從而釋放系統資源,保證核心服務的正常執行。需要識別哪些服務可以降級,比如突然有大量訊息流入,導致服務不可用,我們會把訊息直接丟棄掉。或通過設定流控,拒絕為低階別系統提供服務。

 

流量蓄洪

當流量陡增時,可以將請求進行蓄洪,如把請求儲存在資料庫中,再按照指定的QPS進行洩洪,有效的保護下游系統,也保證了服務的可用性。當呼叫對方系統,對方系統響應緩慢或無響應時,可採取自動蓄洪。

 

服務權重

在叢集環境中,可自動識別高效能服務,拒絕呼叫效能低的服務。如在叢集環境中,對呼叫超時的伺服器進行權重降低,優先呼叫權重高的伺服器。

 

依賴簡化

減少系統之間的依賴,比如使用訊息驅動,A和B系統通過訊息伺服器傳遞資料,A和B系統使用資料庫進行讀寫分離,A系統負責往資料庫中寫資料,B系統負責讀資料,因為資料存放在資料庫中,當A不可用時,短時間內不影響B系統提供服務。

 

彈性擴容

根據資源的使用率自動或手動進行擴容。如頻寬不夠用時,快速增加頻寬。

 

灰度和回滾

釋出新功能只讓部分伺服器生效,且觀察幾天逐漸切流,如果出現問題隻影響部分客戶。出現問題快速回滾,或者直接下線灰度的機器。

 

減少遠端呼叫

優先呼叫本地JVM內服務,其次是同機房服務,然後是同城服務,最後是跨城服務。如A呼叫B,B呼叫網際網路的C系統獲取資料,B系統可以把資料快取起來,並設定資料的保鮮度,減少B對C的依賴。配置中心把註冊服務的地址推送到呼叫服務的系統本地。引數中心把引數配置資訊推送到系統的本地記憶體,而不是讓系統去遠端伺服器獲取引數資訊。

 

熔斷機制

增加熔斷機制,當監控出線上資料出現大幅跌漲時,及時中斷,避免對業務產生更大影響。如我們做指標計算時,指標可以計算慢,但是不能算錯,如果發現某個使用者的指標環比或同比增長一倍或跌零,會考慮儲存所有訊息,並中止該使用者的指標計算。

 

執行時載入模組

我們會把經常變的業務程式碼變成一個個業務模組,使用Java的ClassLoader在執行時動態載入和解除安裝模組,當某個模組有問題時候,可以快速修復。

 

程式碼掃描

使用IDEA程式碼分析等工具進行程式碼掃描,識別出程式中的BUG,如空指標異常,迴圈依賴等。

 

自動備份

程式,系統配置和資料定期進行備份。可使用linux命令和shell指令碼定時執行備份策略,自動進行本地或異地。出現問題時能快速重新部署。

 

線上壓測

系統的對外服務需要進行壓測,知道該服務能承受的QPS和TPS,從而做出相對準確的限流。

相關文章