“高可用性”(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,從而做出相對準確的限流。