你好,我是悟空。前端
不用想象一種異常場景了,這就真實發生了:B 站晚上 11 點忽然掛了,網站主頁直接報 404。java
手機 APP 端數據加載不出來。面試
23:30 分,B 站作了降級頁面,將 404 頁面跳轉到了比較友好的異常頁面。算法
可是刷新下頁面,又會跳轉到 404 頁面。數據庫
22:35 主頁能夠加載出數據了,可是點擊動態
仍是會報 502小程序
點擊某個視頻,直接報 404。緩存
2021-07-14 02:00 以後 B 站開始逐漸恢復。性能優化
今日凌晨 2 點,B 站發佈公告稱,昨晚,B 站的部分服務器機房發生故障,形成沒法訪問。技術團隊隨即進行了問題排查和修復,如今服務已經陸續恢復正常。而針對網友傳言的 B 站大樓失火一事,上海消防官博進行了闢謠,B 站大樓並未出現火情。服務器
看來 B 站的高可用並不令咱們滿意。接下來咱們來探討下什麼是高可用以及跨機房部署的思路。本篇正文內容以下:網絡
通過了 2 個小時,B 站纔開始逐漸恢復,那 B 站系統到底算不算高可用呢?
首先高可用是個相對的形容詞。那什麼是高可用呢?
高可用性(High Availability,HA)咱們已經耳熟能詳,指的時系統具有較高的無端障運行的能力。
B 站針對高可用架構還作過一篇分享:
https://cloud.tencent.com/developer/article/1618923
重點:之後 B 站面試這類題不考,望周知。
常見的高可用的方案就是一主多從,主節點掛了,能夠快速
切換到從節點,從節點充當主節點,繼續提供服務。好比 SQL Server 的主從架構,Redis 的主從架構,它們都是爲了達到高可用性,即便某臺服務器宕機了,也能繼續提供服務。
剛剛提到了快速,這是一個定性詞語,那定量
的高可用是怎麼樣的?
有兩個相關的概念須要說起:MTBF 和 MTTR。
MTBF:故障間隔時間,能夠理解爲從上次故障到此次故障,間隔多久,間隔的越長,系統穩定性越高。
MTTR:故障平均恢復時間,能夠理解爲忽然發生故障了,到系統恢復正常,經歷了多長時間,這個時間越短越好,否則用戶等着急了,會收到不少投訴。
可用性計算公式:MTBF/(MTBF+MTTR)* 100%,就是用故障的間隔時間除以故障間隔時間+故障平均恢復時間的總和。
一般狀況下,咱們使用幾個九來表示系統的可用性,以前咱們項目組的系統要求達到年故障時間不超過 5 分鐘,也就是五個九的標準。
來反觀下 B 站故障了多久,2021-07-13 23:00 到 2021-07-14 02:00,系統逐漸恢復,若是按照年故障總時間來算的話:B 站故障超過 1 個小時了,只能算達到了三個九的標準。若是按照日故障時間來算,只能達到兩個九的標準,也就是 99% 的高可用性,有點慘...
很是容易達到,一個正常的線上系統不會天天宕機 15 分鐘吧,否則真用不下去了。
容許故障的時間很短,年故障時間是 1 小時到 8 小時,須要從架構設計、代碼質量、運維體系、故障處理手冊等入手,其中很是關鍵的一環是運維體系,若是線上出了問題,第一波收到異常通知的確定是運維團隊,根據問題的嚴重程度,會有不一樣的運維人員來處理,像 B 站這種大事故,就得運維負責人親自上陣了。
另外在緊急故障發生時,是否能夠人工手段降級或者加開關,限制部分功能,也是須要考慮的。以前我遇到過一個問題,二維碼刷卡功能出現故障,辛虧以前作了一個開關,能夠將二維碼功能隱藏,若是用戶要使用二維碼刷卡功能,統一引導用戶走線下刷卡功能。
年故障時間 5 分鐘之內,這個至關短,即便有強大的運維團隊天天值班也很難在收到異常報警後,5 分鐘內快速恢復,因此只能用自動化運維來解決。也就是服務器本身來保證系統的容災和自動恢復的能力。
這個標準至關苛刻了,年故障時間 32 秒。
針對不一樣的系統,其實對幾個九也不相同。好比公司內部的員工系統,要求四個九組以,若是是給全國用戶使用,且使用人數不少,好比某寶、某餓,那麼就要求五個九以上了,可是即便是首屈一指的電商系統,它裏面也有非核心的業務,其實也能夠放寬限制,四個九足以,這個就看各家系統的要求,都是成本、人力、重要程度的權衡考慮。
高可用的方案也是很常見,故障轉移、超時控制、限流、隔離、熔斷、降級,這裏也作個總結。
也能夠看這篇:雙 11 的狂歡,乾了這碗「流量防控」湯
對請求的流量進行控制, 只放行部分請求
,使服務可以承擔不超過本身能力的流量壓力。
常見限流算法有三種:時間窗口、漏桶算法、令牌桶算法。
時間窗口又分爲固定窗口和滑動窗口。具體原理能夠看這篇:東漢末年,他們把「服務雪崩」玩到了極致(乾貨)
固定時間窗口:
原理:固定時間內統計流量總量,超過閥值則限制流量。
缺陷:沒法限制短期以內的集中流量。
滑動窗口原理:
原理:統計的總時間固定,但時間段是滑動的。
缺陷:沒法控制流量讓它們更加平滑
時間窗口的原理圖在這裏:
原理:按照一個固定的速率將流量露出到接收端。
缺陷:面對突發流量的時候,採用的解決方式是緩存在漏桶中,這樣流量的響應時間就會增加,這就與互聯網業務低延遲的要求不符。
原理:一秒內限制訪問次數爲 N 次。每隔 1/N 的時間,往桶內放入一個令牌。分佈式環境下,用 Redis 做爲令牌桶。原理圖以下:
總結的思惟導圖在這裏:
而常規的方案是使用兩款組件:Sentinel 和 Hystrix。
故障轉移分爲兩種:
對等節點的系統中,全部節點都承擔讀寫流量,而且節點不保存狀態,每一個節點就是另一個的鏡像。若是某個節點宕機了,按照負載均衡的權重配置訪問其餘節點就能夠了。
不對等的系統中,有一個主節點,多個備用節點,能夠是熱備(備用節點也在提供在線服務),也能夠是冷備(只是備份做用)。若是主節點宕機了,能夠被系統檢測到,當即進行主備切換。
而如何檢測主節點宕機,就須要用到分佈式 Leader 選舉的算法,常見的就有 Paxos 和 Raft 算法,詳細的選舉算法能夠看這兩篇:
諸葛亮 VS 龐統,拿下分佈式 Paxos
用動圖講解分佈式 Raft
超時控制就是模塊與模塊之間的調用須要限制請求的時間,若是請求超時的設置得較長,好比 30 s,那麼當遇到大量請求超時的時候,因爲請求線程都阻塞在慢請求上,致使不少請求都沒來得及處理,若是持續時間足夠長,就會產生級聯反應,造成雪崩
。
仍是以咱們最熟悉的下單場景爲例:用戶下單了一個商品,客戶端調用訂單服務來生成預付款訂單,訂單服務調用商品服務查看下單的哪款商品,商品服務調用庫存服務判斷這款商品是否有庫存,若有庫存,則能夠生成預付款訂單。
雪崩如何形成的?
因此設置合理的超時時間很是重要。具體設置的地方:模塊與模塊之間、請求數據庫、緩存處理、調用第三方服務。
關鍵字:斷路保護
。好比 A 服務調用 B 服務,因爲網絡問題或 B 服務宕機了或 B 服務的處理時間長,致使請求的時間超長,若是在必定時間內屢次出現這種狀況,就能夠直接將 B 斷路了(A 再也不請求B)。而調用 B 服務的請求直接返回降級數據,沒必要等待 B 服務的執行。所以 B 服務的問題,不會級聯影響到 A 服務。
熔斷的詳細原理能夠看這篇:東漢末年,他們把「服務雪崩」玩到了極致(乾貨)
關鍵字:返回降級數據
。網站處於流量高峯期,服務器壓力劇增,根據當前業務狀況及流量,對一些服務和頁面進行有策略的降級(中止服務,全部的調用直接返回降級數據)。以此緩解服務器資源的壓力,保證核心業務的正常運行,保持了客戶和大部分客戶獲得正確的響應。降級數據能夠簡單理解爲快速返回了一個 false,前端頁面告訴用戶「服務器當前正忙,請稍後再試。」
含義:在不一樣地域的數據中心(IDC)部署了多套服務,而這些服務又是共享同一份業務數據的,並且他們均可以處理用戶的流量。
某個服務掛了,其餘服務隨時切換到其餘地域的機房中。
如今服務是多套的,那數據庫是否是也要多套,無非就兩種方案:共用數據庫或不共用。
不共用數據庫。每一個機房都有本身的數據庫,數據庫之間作同步。實現起來這個方案更復雜。
不論使用哪一種方式,都涉及到跨機房數據傳輸延遲的問題。
高性能的同城雙活,核心思想就是避免跨機房調用:
保證同機房服務調用:不一樣的 PRC(遠程調用) 服務,向註冊中心註冊不一樣的服務組,而 RPC 服務只訂閱同機房的 RPC 服務組,RPC 調用只存在於本機房。
保證同機房緩存調用:查詢緩存發生在本機房,若是沒有,則從數據庫加載。緩存也是採用主備的方式,數據更新採用多機房更新的方式。
保證同機房數據庫查詢:和緩存同樣,讀取本機房的數據庫,一樣採用主備方式。
同城雙活沒法作到城市級別的容災。因此須要考慮異地多活。
好比上海的服務器宕機了,還有重慶的服務器能夠頂上來。但兩地距離不要太近,由於發生自燃災害時有可能會被另一地波及到。
和同城雙活的核心思想同樣,避免跨機房調用。可是由於異地方案中的調用延遲遠大於同機房的方案,因此數據同步是一個很是值得探討的點。提供兩種方案:
這個概念也被業界提到過不少次。
兩地:本地和異地。
三中心:本地數據中心、同城數據中心、異地數據中心。
這兩個概念也就是我上面說的同城雙活和異地多活的方式,只是針對的是數據中心。原理以下圖所示:
經過 B 站這件事情,我從中也學到了不少,本篇算是拋磚引玉,歡迎你們留言探討。
做者簡介:悟空,8年一線互聯網開發和架構經驗,用故事講解分佈式、架構設計、Java 核心技術。《JVM性能優化實戰》專欄做者,開源了《Spring Cloud 實戰 PassJava》項目,自主開發了一個 PMP 刷題小程序。
我是悟空,努力變強,變身超級賽亞人!
巨人的肩膀:
http://www.passjava.cn
https://time.geekbang.org/column/article/171115
https://time.geekbang.org/column/article/140763