今天中午知乎又一次宕機,訪問返回502錯誤,以下圖所示:nginx
那服務既然掛了,咱們來聊聊如何在微服務中如何保障他可以不掛呢?首先咱們來看看業界的高可用標準,通常常見的歸納以下:redis
5個9的SLA在一年內只能是5分鐘的不可用時間,5分鐘啊,若是按一年只出1次故障,你也得在五分鐘內恢復故障,感受仍是有點厲害。算法
那咱們在作高可用以前,先經過維基百科瞭解一下到底什麼是真正的高可用呢?sql
系統無中斷地執行其功能的能力,表明系統的可用性程度,是進行系統設計時的準則之一。
這個難點或是重點在於「無中斷」,要作到 7 x 24 小時無中斷無異常的服務提供。docker
一套對外提供服務的系統是須要硬件,軟件相結合,可是咱們的硬件老是會出故障,軟件會有 Bug,硬件會慢慢老化,網絡老是不穩定,軟件會愈來愈複雜和龐大。數據庫
除了硬件軟件在本質上沒法作到「無中斷」,外部環境也可能致使服務的中斷,例如斷電,地震,火災,光纖被挖掘機挖斷,這些影響的程度可能更大。安全
高可用是一個比較複雜的命題,基本上在全部的處理中都會涉及到高可用,全部在設計高可用方案也涉及到了方方面面。這中間將會出現的細節是多種多樣的,因此咱們須要對這樣一個微服務高可用方案進行一個頂層的設計,圍繞服務高可用,先檢查下咱們手裏有多少張牌。通常的策略主要有:服務冗餘、無狀態化、數據存儲高可用、柔性化、兜底容錯、負載均衡、服務限流、服務監控等。服務器
每個訪問可能都會有多個服務組成而成,每一個機器每一個服務均可能出現問題,因此第一個考慮到的就是每一個服務必須不止一份能夠是多份,所謂多份一致的服務就是服務的冗餘,這裏說的服務泛指了機器的服務,容器的服務,還有微服務自己的服務。網絡
在機器服務層面須要考慮,各個機器間的冗餘是否有在物理空間進行隔離冗餘,例如是否全部機器是否有分別部署在不一樣機房,若是在同一個機房是否作到了部署在不一樣的機櫃,若是是docker容器是否部署在分別不一樣的物理機上面。採起的策略其實也仍是根據服務的業務而定,因此須要對服務進行分級評分,從而採起不一樣的策略,不一樣的策略安全程度不一樣,伴隨這的成本也是不一樣,安全等級更高的服務可能還不止考慮不一樣機房,還須要把各個機房所處的區域考慮進行,例如,兩個機房不要處在同一個地震帶上等等。架構
服務的冗餘會要求咱們能夠隨時對服務進行擴容或者縮容,有可能咱們會從2臺機器變成3臺機器,想要對服務進行隨時隨地的擴縮容,就要求咱們的服務是一個無狀態化,所謂無狀態化就是每一個服務的服務內容和數據都是一致的。
例如,從咱們的微服務架構來看,咱們總共分水平劃分了好幾個層,正由於咱們每一個層都作到了無狀態,因此在這個水平架構的擴張是很是的簡單。
假設,咱們須要對網關進行擴容,咱們只須要增長服務就能夠,而不須要去考慮網關是否存儲了一個額外的數據。
分佈式領域中有一個著名的CAP定理,從理論上論證了存儲高可用的複雜度,也就是說,存儲高可用不可能同時知足「一致性,可用性,分區容錯性」,最多隻能知足2個,其中分區容錯在分佈式中是必須的,就意味着,咱們在作架構設計時必須結合業務對一致性和可用性進行取捨。
存儲高可用方案的本質是將數據複製到多個存儲設備中,經過數據冗餘的方式來現實高可用,其複雜度主要呈如今數據複製的延遲或中斷致使數據的不一致性,咱們在設計存儲架構時必須考慮到一下幾個方面:
主從複製是最多見的也是最簡單的存儲高可用方案,例如Mysql,redis等等。
其架構的優勢就是簡單,主機複製寫和讀,而從機只負責讀操做,在讀併發高時候可用擴張從庫的數量減低壓力,主機出現故障,讀操做也能夠保證讀業務的順利進行。
缺點就是客戶端必須感知主從關係的存在,將不一樣的操做發送給不一樣的機器進行處理,並且主從複製中,從機器負責讀操做,可能由於主從複製時延大,出現數據不一致性的問題。
剛說了主從切換存在兩個問題: 1.主機故障寫操做沒法進行 2.須要人工將其中一臺從機器升級爲主機
爲了解決這個兩個問題,咱們能夠設計一套主從自動切換的方案,其中設計到對主機的狀態檢測,切換的決策,數據丟失和衝突的問題。
上述的數據冗餘能夠經過數據的複製來進行解決,可是數據的擴張須要經過數據的分片來進行解決(若是在關係型數據庫是分表)。
何爲數據分片(segment,fragment, shard, partition),就是按照必定的規則,將數據集劃分紅相互獨立、正交的數據子集,而後將數據子集分佈到不一樣的節點上。
HDFS , mongoDB 的sharding 模式也基本是基於這種分片的模式去實現,咱們在設計分片主要考慮到的點是:
在每一次調用,時間越長存在超時的風險就越大,邏輯越複雜執行的步驟越多存在失敗的風險也就越大,若是在業務容許的狀況下,用戶調用只給用戶必需要的結果,而不是須要同步的結果能夠放在另外的地方異步去操做,這就減小了超時的風險也把複雜業務進行拆分減低複雜度。
固然異步化的好處是很是多,例如削封解耦等等,這裏只是從可用的角度出發。
所謂的柔性化,就是在咱們業務中容許的狀況下,作不到給予用戶百分百可用的經過降級的手段給到用戶儘量多的服務,而不是非得每次都交出去要麼100分或0分的答卷。
怎麼去作柔性化,更多實際上是對業務的理解和判斷,柔性化更可能是一種思惟,須要對業務場景有深刻的瞭解。
在電商訂單的場景中,下單,扣庫存,支付是必定要執行的步驟,若是失敗則訂單失敗,可是加積分,發貨,售後是能夠柔性處理,就算出錯也能夠經過日誌報警讓人工去檢查,不必爲加積分損失整個下單的可用性。
兜底是可能咱們常常談論的是一種降級的方案,方案是用來實施,可是這裏兜底可能更可能是一種思想,更多的是一種預案,每一個操做均可以犯錯,咱們也能夠接受犯錯,可是每一個犯錯咱們都必須有一個兜底的預案,這個兜底的預案其實就是咱們的容錯或者說最大程度避免更大傷害的措施,實際上也是一個不斷降級的過程。
相信負載均衡這個話題基本已經深刻每一個作微服務開發或設計者的人心,負載均衡的實現有硬件和軟件,硬件有F5,A10等機器,軟件有LVS,nginx,HAProxy等等,負載均衡的算法有 random , RoundRobin , ConsistentHash等等。
先來說講微服務中限流/熔斷的目的是什麼,微服務後,系統分佈式部署,系統之間經過rpc框架通訊,整個系統發生故障的機率隨着系統規模的增加而增加,一個小的故障通過鏈路的傳遞放大,有可能會形成更大的故障。
服務監控是微服務治理的一個重要環節,監控系統的完善程度直接影響到咱們微服務質量的好壞,咱們的微服務在線上運行的時候有沒有一套完善的監控體系能去了解到它的健康狀況,對整個系統的可靠性和穩定性是很是重要,可靠性和穩定性是高可用的一個前提保證。
【注:文章部份內容參考 李雲華《從0開始學架構》楊波老師《微服務》】關注「SpringForAll社區」公衆號,2020讓咱們一塊兒精進。
[](https://tva1.sinaimg.cn/large...
本文由博客一文多發平臺 OpenWrite 發佈!