1. 程式人生 > >微服務實戰之高可用性

微服務實戰之高可用性

高可用性指你提供的服務要始終可用, 不管天災(停電, 斷網, 磁碟空間滿, 伺服器硬體損壞等), 人禍(軟體bug, 黑客破壞, 誤操作等), 甚至地震, 洪水抑或戰爭.

高可性性的指標就是可用時間與總時間之比

availability = uptime/(uptime + downtime)

現在普遍要求可用性至少達到兩個九, 最好在四個九以上, 也就是說你的服務要達到如下要求
在這裡插入圖片描述
為了達到高可用性, 必須在設計, 實現, 運維等各個方面著手, 才到達到隨時可用的目標.
根據我的經驗, 分以下三個方面來談談

高可用性設計
高可用性實現
高可用性運維

高可用性和高擴充套件性相關, 另外再深談關於擴充套件性的話題
高可用性設計
高可用的不二法寶是冗餘, 也就是說, 為了避免單點失敗(Single Point Failure), 會增加一到多個點, 而且最好放在不同的物理位置, 降低多點失敗的概率.
具體來說, 伺服器之間的關係有主從(primary/slave)關係, 主主(active-active)關係.
再細分的話有一主多僕, 多主多僕, 對等自治等關係, 是一個伺服器集叢集還是多個伺服器叢集.
舉例來說, 我有一個聊天伺服器, 提供公司內部的機密對話聊天服務
通過 Web App 經 Web Socket 通過 TLS 和伺服器進行通訊.
這臺伺服器放在北京總部, 時而由於斷網和斷電造成伺服器不可用, 於是我又增加了一臺伺服器, 為避免總部大廈停電可能造成其他分公司的服務不可用, 後來又在上海分公司搭建了兩臺伺服器. 最終的拓撲結構如下:
資料儲存採用 Cassandra , LoadBalancer 用 HAProxy, ChatService 是自己寫的應用伺服器, 資料儲存採用Cassandra
在這裡插入圖片描述


這個架構符合了基本的高可用性要求, 沒有單點失敗, 資料通過Cassandra 進行儲存, 並且進行內部及跨區域的資料同步.
高可用性的關鍵難點在於狀態同步和一致性要求, 上例中採用的 Cassandra 只能保證最終一致性, 要是用於支付結算系統, 會有點問題.
Cassandra 看起來很美, 它不象MySQL, 結點之間沒有主從之分, 均為可讀可寫, 高度可擴充套件, 可是實際應用起來, 在大資料量, 高併發請求的場景下經常出現讀取資料超時的情況
避免單點失敗是基本要求,要達到兩個九以上,這還遠遠不夠。
當大量使用者請求峰值來臨時,極有可能由於壓力過大,造成整個系統不可用,這時候,要麼按需擴充套件增加伺服器,儲存器等資源,要麼讓服務降級或變慢,也要保持整個系統的可用。
要儘可能地自動化,在重大故障和緊急時刻也要能及時通知運維工程師進行快速反應和故障恢復。有道是,隱患險於明火,防範勝於勝於救災,責任重於泰山,在技術和非技術層面都要做好預案,做足功課,有備無患。
基本度量 metrics, 我們可以做如下的基本功課

分流
使用反向代理, 負載均衡器將負載均勻分配給多個微伺服器例項, 簡單場景下使用簡單的 round-robbin 策略就夠了.
複雜的情況下必須參照各個微服務例項上的負載情況做分流
限流
每個例項的負載是一定的, 如果負載過高, 超過了其處理能力, 可能會造成整個系統不可用的狀況.
對於特定使用者, IP和組織, 我們最好設定一個上限的閥值, 根據metrics 統計, 如果超過這個閥值可以返回錯誤碼(429)讓其過會兒重試(retry-after)
斷流
當某個例項持續出現問題, 與其超時, 失敗, 再不斷重試, 不如直接斷開, 過會兒再嘗試訪問它, 這個在斷路器模式再詳細討論
這個斷路器的開啟和關閉也是基於 metrics

高可用性實現
設計要為失敗而設計, 在實現時要處處考慮失敗的可能性, 比如異常關機, 記憶體耗盡了, 磁碟滿了, 網斷了, 以及安全性考慮, 防止可能的惡意攻擊和破壞.
安全方面的 AAA認證, 授權, 審計, 防止SQL 注入, 跨域攻擊, 在 [微服務實戰之安全性] 詳述.
我們在程式設計開發中要牢記三點

容錯
防錯
糾錯

容錯
所謂容錯性開發,是指在系統某些模組或外部依賴出錯的情況下,系統依然能保持基本可用
比如

網路連線斷開了或不可達,進行重試直至恢復
記憶體不夠用了, 就序列化到一部分到磁碟上後釋放一部分記憶體
某個外部服務不可用, 給予使用者友好提示並提供備選方案

防錯
而防錯性開發是指預先採取措施防止錯誤, 比如對於輸入引數的有效性及合法性檢查, 資料儲存總有冗餘和備份, 這是實現高用性的重點, 其中尤其要注意

防止資源耗盡.

在記憶體, CPU, 磁碟, 頻寬, 資料庫等外部資源的使用上, 必須牢記資源有借有還, 切勿任意無節制的使用.
常見的有錯誤有

  1. 記憶體洩漏
  2. 檔案控制代碼洩漏
  3. 內部集合增長過快, 刪除過慢
  4. 網路或資料庫連線洩漏
  5. 棧空間溢位
  6. 無節制的建立執行緒
  7. 不當的迴圈造成的CPU繁忙
  8. 某些異常導致的 log過多且沒有 rotate ,從而把磁碟寫滿

對請求頻率加以限制 Rate Limit

對於超過規定的頻率和數量的請求, 伺服器會對特定的客戶端暫停或降級服務,防止區域性問題影響整個系統的穩定。

加強欺詐檢測和保護 Fraud detection and protection

對於可疑的請求和客戶端定義按既有策略進行檢測和保護, 比如對於單位時間內來自某個IP地址或者某個帳號的超量請求, 異常密碼嘗試, 異常越權嘗試進行暫時鎖定
糾錯
糾錯性開發是指預先設定錯誤處理預案,制訂應急響應, 比如在上線新版本出現重大bug時,在至多幾分鐘內就能迅速回滾至上個版本, 或者可以迅速關掉引起錯誤某個功能開關
在系統中定義了一些告警閥值,並設定回撥,一旦觸發警報,即進入緊急狀態,採取緊急措施
如磁碟剩餘空間預警,則自動清理一週之前的日誌資料,並呼叫值班人員緊急待命,或者增加磁碟空間或掛接新磁碟
如發現下游所依賴的服務響應太慢或如發現日誌中某一類錯誤超過閥值,則立即觸發告警和自動分析程式, 提醒值班人員排查原因並給予解決
並且要支援自動和手動故障恢復 Auto fallback and manual fallback, 對於單點失敗零容忍

單個伺服器掛掉無所謂
單個機房掛掉無所謂
單個數據中心掛掉無所謂
單個地區中的服務掛掉無所謂

具體來說就是提供足夠的冗餘備份.
基於HTTP Restful 的無狀態服務可以充分利用dns, load balance 的相應的功能
而一些基於長連線的有狀態服務,dns不管用,LB的支援也有缺陷,可能需要應用程式自己來設計實現服務的 Failover
高可用性運維
基本要求是按需求快速恢復故障,快速部署或回滾服務,從容應對各種突發事件,快速解決各種軟硬體故障,一句話,又快又穩,安全第一.
基本手段有:

  1. 實時監控和度量 Monitor and metrics

每臺伺服器和重特性都有足夠的監控和度量, 比如常規的健康檢查 Health Check , 可以每分鐘做一次, 比較簡單的做法是服務提供health check 和介面或API, 通過呼叫這些API並檢查其結果來判斷服務是否可用, 是否需要做服務切換.

實時產線自動化測試

有一些基於TCP或UDP的心跳檢查, 基於SNMP 事件的監控機制, 個人覺得 TaP( Test Against Production) 產線自動化功能測試最有針對性, 檢查的粒度最細, 也最能發現一些深層次的問題
比如挑出一些比較重要和穩定的自動化測試用命, 在系統的某個閒時, 直接在產品線上執行一系列有針對性的測試

定時進行常規化維護

比如定期對日誌檔案進行歸檔, 清理無用檔案和資料庫記錄, 定時重啟伺服器以防止細微的記憶體洩漏和記憶體碎片等等

災難 Disaster Recover

在遇到突發的重大軟硬體故障時, 及時進行災難恢復, 將服務切換到備份伺服器, 叢集或資料中心上

感興趣可以加Java架構師群獲取Java工程化、高效能及分散式、高效能、深入淺出。高架構。效能調優、Spring,MyBatis,Netty原始碼分析和大資料等多個知識點高階進階乾貨的直播免費學習許可權 都是大牛帶飛 讓你少走很多的彎路的 群…號是:855801563 對了 小白勿進 最好是有開發經驗

注:加群要求

1、具有工作經驗的,面對目前流行的技術不知從何下手,需要突破技術瓶頸的可以加。

2、在公司待久了,過得很安逸,但跳槽時面試碰壁。需要在短時間內進修、跳槽拿高薪的可以加。

3、如果沒有工作經驗,但基礎非常紮實,對java工作機制,常用設計思想,常用java開發框架掌握熟練的,可以加。

4、覺得自己很牛B,一般需求都能搞定。但是所學的知識點沒有系統化,很難在技術領域繼續突破的可以加。

5.阿里Java高階大牛直播講解知識點,分享知識,多年工作經驗的梳理和總結,帶著大家全面、科學地建立自己的技術體系和技術認知!