十年前的阿里大牛困惑:咱們爲何感受不到淘寶應用升級時的停機?

十年前的阿里大牛困惑:咱們爲何感受不到淘寶應用升級時的停機?

本文已收錄GitHub,更有互聯網大廠面試真題,面試攻略,高效學習資料等git

十幾年前,我參加阿里巴巴面試的時候,以爲阿里巴巴這樣的網站 Web 應用開發簡直小菜,由於我以前是作相似 Tomcat 這樣的 Web 容器開發的,因此面試的時候信心滿滿。github

確實,面試官前面的問題都是關於數據結構、操做系統、設計模式的,也就是咱們這個專欄模塊一和模塊二的內容。我感受本身回答得還不錯,因此更加信心滿滿。這時候,面試官突然提了一個問題:面試

咱們的 Web 程序每一個星期都會發佈一個新版本,可是程序要求 7*24 小時可用,也就是說,啓動新版本程序替換老程序,進行程序升級的時候,程序還在對外提供服務,用戶沒有感受到停機,咱們是怎麼作到的呢?數據庫

應用程序升級必需要用新版本的程序包替代老版本的程序包,並從新啓動程序,這段時間程序是不能對外提供服務的,用戶請求必定會失敗。可是阿里巴巴讓這段時間的用戶請求依然是成功的。打個比方,就是要在飛機飛行過程當中更換髮動機,還不能讓乘客感受到。這個問題當時徹底不在個人知識範圍以內,可是我知道這個需求場景是真實存在的,並且確實應該是能夠作到的,但是我徹底不知道是怎麼作到的。設計模式

面試官看我瞠目結舌,笑着問我,想不想知道答案。我馬上回答說想知道,結果面試官跟我說,加入咱們團隊你就知道了。服務器

這實際上是一個關於互聯網應用可用性的問題。咱們知道,Web 應用在各類狀況下都有可能不可訪問,也就是不可用。各類硬件故障,好比應用服務器及數據庫宕機、網絡交換機宕機、磁盤損壞、網卡鬆掉等等。還有各類軟件故障,程序 Bug 什麼的。即便沒有 Bug,程序要升級,必需要關閉進程從新啓動,這段時間應用也是不可用的;此外,還有外部環境引起的不可用,好比促銷引來大量用戶訪問,致使系統併發壓力太大而崩潰,以及,******、機房火災、挖掘機挖斷光纜,各類狀況致使的應用不可用。微信

而互聯網的高可用是說,在上面各類狀況下,應用都要是可用的,用戶都可以正常訪問系統,完成業務處理。網絡

這彷佛是不可能的任務。數據結構

高可用的度量

首先咱們看下,什麼叫作應用的高可用,以及可用性如何度量。業界一般用多少個 9 來講明互聯網應用的可用性。好比說淘寶的可用性是 4 個 9,就是說淘寶的服務 99.99% 可用。這句話的意思是,淘寶的服務要保證在全部的運行時間裏只有 0.01% 不可用,也就是說一年大概有 53 分鐘不可用。這個 99.99% 就叫作系統的可用性指標,這個值的計算公式是:架構

十年前的阿里大牛困惑:咱們爲何感受不到淘寶應用升級時的停機?

通常說來,兩個 9 表示系統基本可用,年度不可用時間小於 88 小時;3 個 9 是較高可用,年度不可用時間小於 9 個小時;4 個 9 是具備自動恢復能力的高可用,年度不可用時間小於 53 分鐘;5 個 9 指極高的可用性,年度不可用時間小於 5 分鐘。咱們熟悉的互聯網產品的可用性大可能是 4 個 9。淘寶、百度、微信,差很少都是這樣。

下面我會討論各類高可用技術方案。但無論是哪一種方案,實現高可用須要投入的技術和設備成本都很是高。所以可用性並非越高越好,而是要根據產品策略尋找高可用投入產出的最佳平衡點,像支付寶這樣的金融產品就須要更高的可用性,而微博的可用性要求就會相對低一些。相對支付寶的可用性超過 99.99%,Twitter 的可用性只有 98%。

可用性指標是對系統總體可用性的一個度量。在互聯網企業中,爲了更好地管理系統的可用性,界定好系統故障之後的責任,一般會用故障分進行管理。通常過程是,根據系統可用性指標換算成一個故障分,這個故障分是整個系統的故障分,好比 10 萬分,而後根據各自團隊各個產品各個職能角色承擔的責任的不一樣,把故障分下發給每一個團隊,直到每一個人,也就是說每一個工程師在年初的時候就會收到一個預計的故障分。而後每一次系統出現可用性故障間小於 53 分鐘;5 個 9 指極高的可用性,年度不可用時間小於 5 分鐘。咱們熟悉的互聯網產品的可用性大可能是 4 個 9。淘寶、百度、微信,差很少都是這樣。

下面我會討論各類高可用技術方案。但無論是哪一種方案,實現高可用須要投入的技術和設備成本都很是高。所以可用性並非越高越好,而是要根據產品策略尋找高可用投入產出的最佳平衡點,像支付寶這樣的金融產品就須要更高的可用性,而微博的可用性要求就會相對低一些。相對支付寶的可用性超過 99.99%,Twitter 的可用性只有 98%。

可用性指標是對系統總體可用性的一個度量。在互聯網企業中,爲了更好地管理系統的可用性,界定好系統故障之後的責任,一般會用故障分進行管理。通常過程是,根據系統可用性指標換算成一個故障分,這個故障分是整個系統的故障分,好比 10 萬分,而後根據各自團隊各個產品各個職能角色承擔的責任的不一樣,把故障分下發給每一個團隊,直到每一個人,也就是說每一個工程師在年初的時候就會收到一個預計的故障分。而後每一次系統出現可用性故障的時候,都會進行故障考覈,劃定到具體的團隊和責任人之後,會扣除他的故障分。若是到了年末的時候,若是一個工程師的故障分爲負分,那麼頗有可能會影響他的績效考覈。

故障分=故障時間*故障權重

高可用的架構

系統的高可用架構就是要在上述各類故障狀況下,保證系統依然能夠提供服務,具體包含如下幾種架構方案。咱們已經在前面幾篇架構專欄中提到過這些架構方案,這裏咱們從高可用
的視角從新審視如下這些架構是如何實現高可用的。

冗餘備份

既然各類服務器故障是不可避免的,那麼架構設計上就要保證,當服務器故障的時候,系統依然能夠訪問。具體上就是要實現服務器的冗餘備份。

冗餘備份是說,提供同一服務的服務器要存在冗餘,即任何服務都不能只有一臺服務器,服務器之間要互相進行備份,任何一臺服務器出現故障的時候,請求能夠發送到備份的服務器去處理。這樣,即便某臺服務器失效,在用戶看來,系統依然是可用的。

我在負載均衡架構這篇文章中講了經過負載均衡服務器,將多臺應用服務器構成一個集羣共同對外提供服務,這樣能夠利用多臺應用服務器的計算資源,知足高併發的用戶訪問請求。事實上,負載均衡還能夠實現系統的高可用

十年前的阿里大牛困惑:咱們爲何感受不到淘寶應用升級時的停機?

負載均衡服務器經過心跳檢測發現集羣中某臺應用服務器失效,而後負載均衡服務器就不將請求分發給這臺服務器,對用戶而言,也就感受不到有服務器失效,系統依然可用。

回到咱們開頭的問題,阿里巴巴就是用這種方法實現的。應用程序升級的時候,中止應用進程,可是不影響用戶訪問。由於應用程序部署在多臺服務器上,應用程序升級的時候,每次只 STOP 一臺或者一部分服務器,在這些機器上進行程序升級,這個時候,集羣中還有其餘服務器在提供服務器,所以用戶感受不到服務器已經停機了。

此外我在數據存儲架構這篇文章中提到的數據庫主主複製,也是一種冗餘備份。這個時候,不僅是數據庫系統 RDBMS 互相進行冗餘備份,數據庫裏的數據也要進行冗餘備份,一份數據存儲在多臺服務器裏,保證當任何一臺服務器失效,數據庫服務依然可使用。

失敗隔離

保證系統高可用的另外一個策略是失敗隔離,將失敗限制在一個較小的範圍以內,使故障影響範圍不擴大。具體實現失敗隔離的主要架構技術是消息隊列。

一方面,消息的生產者和消費者經過消息隊列進行隔離。若是消費者出現故障的時候,生產者能夠繼續向消息隊列發送消息,而不會感知到消費者的故障,等消費者恢復正常之後再去從消息隊列中消費消息,因此從用戶處理的視角看,系統一直是可用的。

發送郵件消費者出現故障,不會影響生產者應用的運行,也不會影響發送短信等其餘消費者正常的運行。

十年前的阿里大牛困惑:咱們爲何感受不到淘寶應用升級時的停機?

另外一方面,因爲分佈式消息隊列具備削峯填谷的做用,因此在高併發的時候,消息的生產者能夠將消息緩衝在分佈式消息隊列中,消費者能夠慢慢地從消息隊列中去處理,而不會將瞬時的高併發負載壓力直接施加到整個系統上,致使系統崩潰。也就是將壓力隔離開來,使消息生產者的訪問壓力不會直接傳遞到消息的消費者,這樣能夠提升數據庫等對壓力比較敏感的服務的可用性。

同時,消息隊列還使得程序解耦,將程序的調用和依賴隔離開來,咱們知道,低耦合的程序更加易於維護,也能夠減小程序出現 Bug 的概率。

限流降級

限流和降級也是保護系統高可用的一種手段。在高併發場景下,若是系統的訪問量超過了系統的承受能力,能夠經過限流對系統進行保護。限流是指對進入系統的用戶請求進行流量限制,若是訪問量超過了系統的最大處理能力,就會丟棄一部分的用戶請求,保證整個系統可用,保證大部分用戶是能夠訪問系統的。這樣雖然有一部分用戶的請求被丟棄,產生了部分不可用,但仍是好過整個系統崩潰,全部的用戶都不可用要好。

降級是保護系統的另外一種手段。有一些系統功能是非核心的,可是它也給系統產生了很是大的壓力,好比說在電商系統中有確認收貨這個功能,即使咱們不去確認收貨,系統也會超時自動確認收貨。

但實際上確認收貨這個操做是一個很是重的操做,由於它會對數據庫產生很大的壓力:它要進行更改訂單狀態,完成支付確認,並進行評價等一系列操做。若是在系統高併發的時候去完成這些操做,那麼會對系統雪上加霜,使系統的處理能力更加惡化。

解決辦法就是在系統高併發的時候,好比說像淘寶雙 11 的時候,當天可能成天系統都處於一種極限的高併發訪問壓力之下,這時候就能夠將確認收貨、評價這些非核心的功能關閉,將寶貴的系統資源留下來,給正在購物的人,讓他們去完成交易。

異地多活

咱們前面提到的各類高可用策略,都仍是針對一個數據中心內的系統架構,針對服務器級別的軟硬件故障而言的。但若是整個數據中心都不可用,好比說數據中心所在城市遭遇了地震,機房遭遇了火災或者停電,這樣的話,無論咱們前面的設計和系統多麼的高可用,系統依然是不可用的。

爲了解決這個問題,同時也爲了提升系統的處理能力和改善用戶體驗,不少大型互聯網應用都採用了異地多活的多機房架構策略,也就是說將數據中心分佈在多個不一樣地點的機房裏,這些機房均可以對外提供服務,用戶能夠鏈接任何一個機房進行訪問,這樣每一個機房均可以提供完整的系統服務,即便某一個機房不可以使用,系統也不會宕機,依然保持可用。

異地多活的架構考慮的重點就是,用戶請求如何分發到不一樣的機房去。這個主要能夠在域名解析的時候完成,也就是用戶進行域名解析的時候,會根據就近原則或者其餘一些策略,完成用戶請求的分發。另外一個相當重要的技術點是,由於是多個機房均可以獨立對外提供服務,因此也就意味着每一個機房都要有完整的數據記錄。用戶在任何一個機房完成的數據操做,都必須同步傳輸給其餘的機房,進行數據實時同步。

數據庫實時同步最須要關注的就是數據衝突問題。同一條數據,同時在兩個數據中心被修改了,該如何解決?爲了解決這種數據衝突的問題,某些容易引發數據衝突的服務採用相似MySQL 的主主模式,也就是說多個機房在某個時刻是有一個主機房的,某些請求只能到達主機房才能被處理,其餘的機房不處理這一類請求,以此來避免關鍵數據的衝突。

總結

除了以上的高可用架構方案,還有一些高可用的運維方案:經過自動化測試減小系統的Bug;經過自動化監控儘早發現系統的故障;經過預發佈驗證發現測試環境沒法發現的Bug;灰度發佈下降軟件錯誤帶來的影響以及評估軟件版本升級帶來的業務影響等等。

相關文章
相關標籤/搜索