
網(wǎng)站的可用性強調(diào)的是對最終用戶的使用價值。它牽動著人們的神經(jīng),直接影響著公司的形象和利益,許多互聯(lián)網(wǎng)公司都將網(wǎng)站的可用性列入工程師的績效考核,與獎金、升遷等利益直接掛鉤。
1 可用性的度量與考核
1.1 可用性度量
網(wǎng)站不可用時間(故障時間) = 故障修復(fù)時間點 - 故障發(fā)現(xiàn)(報告)時間點
網(wǎng)站年度可用性指標(biāo) = (1 - 網(wǎng)站不可用時間/年度總時間 ) * 100%
業(yè)界通常用多個 9 來衡量網(wǎng)站的可用性:
- 2 個 9 - 基本可用,不可用時間小于 88 小時(Twitter 的可用性不足 2 個 9)。
- 3 個 9 - 較高可用,不可用時間小于 9 小時。
- 4 個 9 - 具有自動恢復(fù)能力的高可用,不可用時間小于 53 分鐘(QQ 服務(wù))。
- 5 個 9 - 極高可用,不可用時間小于 5 分鐘。
影響可用性的因素很多:
- 技術(shù)是否過硬。
- 設(shè)備資金的投入。
- 工程師的責(zé)任心。
- 好運氣 O(∩_∩)O~
1.2 可用性考核
對外是服務(wù)承諾,對內(nèi)是考核指標(biāo)。針對每一個工程師的考核,使用的是故障分。故障分是一種對網(wǎng)站故障進行分類加權(quán)計算故障責(zé)任的方法。下面是故障分類權(quán)重示例:
| 分類 | 描述 | 權(quán)重 |
|---|---|---|
| 事故級 | 嚴(yán)重故障,網(wǎng)站整體不可用 | 100 |
| A 類 | 網(wǎng)站訪問不順暢或核心功能不可用 | 20 |
| B 類 | 非核心功能不可用,或核心功能只有少數(shù)用戶不可用 | 5 |
| C 類 | 其他故障 | 1 |
故障分的計算公式:
故障分 = 故障時間(分鐘) * 故障權(quán)重
在年初或考核季度的起始,會根據(jù)網(wǎng)站的可用性指標(biāo)計算總的故障分,然后根據(jù)團隊和個人的職責(zé)角色分?jǐn)偣收戏?,這個故障分是管理預(yù)期的故障分。發(fā)生故障后,根據(jù)故障分類和責(zé)任劃分,把故障分劃定給相關(guān)的責(zé)任人。年末或考核季度結(jié)束時,團隊和個人實際承擔(dān)的故障分如果超過了年初分?jǐn)偟墓收戏郑冃Э己司蜁艿接绊憽?/p>

有時候,一個故障責(zé)任可能會由多個部門或團隊來承擔(dān),那么故障分也會按照相應(yīng)的責(zé)任分?jǐn)偟讲煌膱F隊和個人。
網(wǎng)站的可用性跟技術(shù)、運營等相關(guān)各方的績效息息相關(guān),所以在架構(gòu)設(shè)計與評審會上,關(guān)于系統(tǒng)可用性的討論總是最費精力和時間的。
不同的企業(yè)文化與市場策略,也會影響到系統(tǒng)可用性的架構(gòu)決策:
- 崇尚創(chuàng)新和風(fēng)險的公司,對可用性的要求會低一些。
- 業(yè)務(wù)快速增長的網(wǎng)站忙于應(yīng)對指數(shù)級增長的用戶,對可用性的要求也會低一些。
- 服務(wù)于收費用戶的網(wǎng)站對可用性很敏感,因為服務(wù)的不可用或關(guān)鍵用戶的數(shù)據(jù)丟失,都有可能會導(dǎo)致收費用戶的投訴甚至引來官司。
2 高可用的架構(gòu)
企業(yè)級應(yīng)用為了提高系統(tǒng)的可用性,通常會采用較昂貴的軟硬件設(shè)備(小型機、Oracle 數(shù)據(jù)庫等)。而互聯(lián)網(wǎng)公司則更多地采用 PC 級服務(wù)器、開源的數(shù)據(jù)庫和操作系統(tǒng),因為成本低嘛O(∩_∩)O~
這些廉價的設(shè)備出現(xiàn)硬件故障是常態(tài),所以在高可用的架構(gòu)上就要保證發(fā)生硬件故障時,服務(wù)依然可用、數(shù)據(jù)依然能夠訪問與保存。
實現(xiàn)上述功能的主要手段是數(shù)據(jù)和服務(wù)的冗余備份以及失效轉(zhuǎn)移。一旦服務(wù)器宕機,就將服務(wù)切換到其他可用的服務(wù)器上;如果磁盤損壞,就從備份的磁盤中讀取數(shù)據(jù)。
典型的網(wǎng)站設(shè)計遵循基本分層架構(gòu)模型:

- 應(yīng)用層:處理具體的業(yè)務(wù)邏輯。
- 服務(wù)層:提供可復(fù)用的服務(wù)。
- 數(shù)據(jù)層:數(shù)據(jù)的存儲和訪問。
中小型網(wǎng)站在部署時,通常將應(yīng)用層和服務(wù)層一起部署,而數(shù)據(jù)層則另外部署。

復(fù)雜的大型網(wǎng)站架構(gòu),劃分的粒度會更小、更詳細(xì),結(jié)構(gòu)更復(fù)雜,但還是能夠把這些模塊劃分到這三層架構(gòu)中的:

不同的業(yè)務(wù)產(chǎn)品會部署在不同的服務(wù)器集群上。而這些產(chǎn)品又會依賴一些共用的可復(fù)用的服務(wù)(比如賬戶服務(wù)等),這些服務(wù)也是部署在各自的服務(wù)器集群上的。至于最底層的數(shù)據(jù)層,也是部署在服務(wù)器集群上的哦O(∩_∩)O~
大型網(wǎng)站的分布式部署,使得位于不同層次的服務(wù)器具有不同的可用性設(shè)計:
- 應(yīng)用層 - 為了應(yīng)對高并發(fā)的訪問請求,通常會使用負(fù)載均衡設(shè)備把一組的服務(wù)器組合為一個集群,共同對外提供服務(wù)。當(dāng)負(fù)載均衡設(shè)備監(jiān)控到某臺服務(wù)器不可用時,就將其從集群中剔除,并把請求轉(zhuǎn)發(fā)到集群中的其他可用的服務(wù)器。
- 服務(wù)層 - 應(yīng)用層通過分布式服務(wù)框架來調(diào)用這一層提供的服務(wù)。分布式服務(wù)框架會在應(yīng)用層的客戶端程序中實現(xiàn)軟件級的負(fù)載均衡,并通過注冊中心監(jiān)控這些提供服務(wù)的服務(wù)器。一旦發(fā)現(xiàn)某個服務(wù)器不可用,會立即通知客戶端程序修改服務(wù)訪問列表,剔除不可用的服務(wù)器。
- 數(shù)據(jù)層 - 寫入數(shù)據(jù)的同時同步復(fù)制數(shù)據(jù),把數(shù)據(jù)寫入多臺服務(wù)器,實現(xiàn)數(shù)據(jù)的冗余備份。當(dāng)數(shù)據(jù)服務(wù)器宕機時,會把針對數(shù)據(jù)的訪問切換到擁有備份數(shù)據(jù)的服務(wù)器上。
下面我們會針對每一層究竟如何實現(xiàn)高可用,進行一一探討哦O(∩_∩)O~
3 實現(xiàn)高可用的應(yīng)用層
應(yīng)用層是處理業(yè)務(wù)邏輯,這一層的特點是無狀態(tài)性。
無狀態(tài)性指的是:多個服務(wù)器之間是完全對等的,即把請求提交給任意一臺服務(wù)器,處理的結(jié)果都是一樣的。
3.1 通過負(fù)載均衡實現(xiàn)失效轉(zhuǎn)移
在業(yè)務(wù)量和數(shù)據(jù)量都較高的情況下,通過負(fù)載均衡,可以將流量和數(shù)據(jù)分?jǐn)偟揭粋€集群所組成的多臺服務(wù)器上,以提高整體的處理能力。目前的負(fù)載均衡軟、硬件都提供了失效轉(zhuǎn)移功能。所以,如果集群的服務(wù)是無狀態(tài)的對等服務(wù)時,負(fù)載均衡技術(shù)可以保證系統(tǒng)的高可用:

當(dāng) Web 服務(wù)器集群中的服務(wù)器都可用時,負(fù)載均衡服務(wù)器會把訪問請求分發(fā)給任意一臺服務(wù)器進行處理。負(fù)載均衡服務(wù)器通過心跳檢測機制,如果發(fā)現(xiàn)某臺服務(wù)器(比如圖示中的 10.0.0.1)失去響應(yīng),就會把它從服務(wù)器列表中剔除。
為了保證高可用,即使某個應(yīng)用訪問量非常少,也必須至少部署兩臺服務(wù)器,通過負(fù)載均衡技術(shù)來構(gòu)建一個小型集群。
3.2 服務(wù)器集群中的 Session 管理
業(yè)務(wù)總是有狀態(tài)的,比如交易類網(wǎng)站,需要有購物車記錄用戶購買的商品。在 web 應(yīng)用中,這些狀態(tài)就稱為 Session。在單機的情況下,Session 可以由部署在服務(wù)器上的 Web 容器(如 Tomcat)進行統(tǒng)一管理。但在使用負(fù)載均衡的集群環(huán)境中,要保證每次請求都能夠獲得正確的 Session 就很復(fù)雜。
在集群環(huán)境中,有這些手段可以進行 Session 管理:
3.2.1 復(fù)制 Session
這是早期的企業(yè)應(yīng)用系統(tǒng)使用較多的一種 Session 管理策略。應(yīng)用服務(wù)器開啟 Web 容器的 Session 復(fù)制功能,然后在集群中的幾臺服務(wù)器之間同步 Session 對象,使得每一臺服務(wù)器都保存著所有用戶的 Session 信息:

3.2.2 綁定 Session
利用負(fù)載均衡的源地址 Hash 算法,將源于同一 IP 的請求分發(fā)到同一臺服務(wù)器上。這樣在整個會話期間,用戶的所有請求都是在同一臺服務(wù)器上進行處理,即把 Session 綁定到某臺特定的服務(wù)器上。這種方法又稱為 “會話黏滯”。

綁定 Session 的方案不符合系統(tǒng)高可用的需求,因為一旦某臺服務(wù)器宕機,那么該服務(wù)器上的 Session 就不存在咯。即使把用戶的請求切換到其他服務(wù)器也會因為沒有 Session 而導(dǎo)致業(yè)務(wù)無法正常處理。所以很少有網(wǎng)站使用綁定 Session 的方案。
3.2.3 利用 Cookie 記錄 Session
這種方式是將 Session 記錄在客戶端,每次請求服務(wù)器時,把 Session 放在請求中發(fā)送給服務(wù)器,服務(wù)器處理后,再把修改過的 Session 發(fā)送回客戶端。
網(wǎng)站可以利用瀏覽器支持的 Cookie 記錄 Session:

利用 Cookie 記錄 Session 也有一些缺點:
- Cookie 有大小限制,記錄的信息有限。
- 每次請求響應(yīng)都要傳輸 Cookie,影響性能。
- 如果用戶關(guān)閉了 Cookie,訪問會變得不正常。
但由于 Cookie 簡單易用,能夠支持應(yīng)用服務(wù)器的線性伸縮;而且大部分需要記錄的 Session 信息又比較小。所以許多網(wǎng)站都或多或少地使用 Cookie 記錄 Session。
3.2.4 Session 服務(wù)器
利用獨立部署的 Session 服務(wù)器或集群,來統(tǒng)一管理 Session。應(yīng)用服務(wù)器每次讀寫 Session 時,都需要訪問 Session 服務(wù)器。

這樣的方案是把應(yīng)用服務(wù)器,分為無狀態(tài)的應(yīng)用服務(wù)器與有狀態(tài)的 Session 服務(wù)器。
對于有狀態(tài)的 Session 服務(wù)器,可以這樣簡單實現(xiàn):利用分布式緩存、數(shù)據(jù)庫等組件的基礎(chǔ)上進行封裝,使其符合 Session 的存儲與訪問的要求。
4 實現(xiàn)高可用的服務(wù)層
可復(fù)用的服務(wù)模塊為產(chǎn)品提供了基礎(chǔ)公共服務(wù)。這些服務(wù)通常都是獨立分布式部署,由具體應(yīng)用進行遠(yuǎn)程調(diào)用。它們也是無狀態(tài)的服務(wù),因此可以使用類似負(fù)載均衡的失效轉(zhuǎn)移策略實現(xiàn)高可用。
還有這些高可用的策略:
4.1 分級管理
運維層面對服務(wù)器進行分級管理,核心應(yīng)用與服務(wù)優(yōu)先使用更好的硬件。
在服務(wù)部署上進行必要的隔離,避免故障的連鎖反應(yīng):
- 低優(yōu)先級的服務(wù)通過啟動不同的線程或部署在不同的虛擬機上進行隔離。
- 高優(yōu)先級的服務(wù)需要部署在不同的物理機上,核心服務(wù)和數(shù)據(jù)最好是部署在不同地域的數(shù)據(jù)中心上。
4.2 超時設(shè)置
在應(yīng)用中設(shè)置調(diào)用服務(wù)的超時時間,一旦超時,通信框架就拋出異常。應(yīng)用根據(jù)服務(wù)調(diào)度策略,可以選擇繼續(xù)重試或者將請求轉(zhuǎn)移到提供相同服務(wù)的其他服務(wù)器上。
4.3 異步調(diào)用
應(yīng)用對服務(wù)的調(diào)用,通過消息隊列的異步方式實現(xiàn)。應(yīng)用程序會將用戶注冊信息發(fā)送給消息隊列服務(wù)器后,立即返回用戶注冊成功的響應(yīng)。而多個消費者任務(wù)(記錄用戶信息到數(shù)據(jù)庫、發(fā)送注冊成功郵件、開通權(quán)限)會從消息隊列中獲取用戶注冊信息后異步執(zhí)行。
注意:不是所有的的服務(wù)調(diào)用都可以使用異步調(diào)用模式。比如 “獲取用戶信息的服務(wù)” 或 “必須確認(rèn)服務(wù)調(diào)用成功才能繼續(xù)下一步操作的服務(wù)” 等,都不適合使用異步調(diào)用模式。
4.4 服務(wù)降級
網(wǎng)站訪問的高峰期,服務(wù)可能因為大量的并發(fā)調(diào)用而導(dǎo)致性能下降,嚴(yán)重時甚至?xí)?dǎo)致服務(wù)宕機。所以為了保證核心應(yīng)用與服務(wù)的正常運行,我們必須對某些服務(wù)進行降級。降級有兩種手段:
- 拒絕服務(wù) - 拒絕低優(yōu)先級應(yīng)用的調(diào)用,減少并發(fā)數(shù),以確保核心應(yīng)用;或隨機拒絕部分請求,以節(jié)約資源。
- 關(guān)閉功能 - 關(guān)閉部分不重要的服務(wù),或關(guān)閉服務(wù)內(nèi)不重要的功能,以節(jié)約資源。比如淘寶在 “雙十一” 促銷期間就使用了這種方法:它在系統(tǒng)最繁忙的階段關(guān)閉了 “評價”、“確認(rèn)收貨” 等非核心服務(wù),以保證核心的交易服務(wù)。
4.5 冥等性設(shè)計
應(yīng)用調(diào)用服務(wù)失敗后,會把請求發(fā)給其他的服務(wù)器,但這個失敗可能不是真的!比如服務(wù)實際已處理成功,但因為網(wǎng)絡(luò)故障,所以應(yīng)用沒有收到響應(yīng),那么這時應(yīng)用所重新提交的請求,就是在重復(fù)調(diào)用服務(wù)!如果這是一個轉(zhuǎn)賬服務(wù),那么后果就很嚴(yán)重啦。
重復(fù)調(diào)用服務(wù)是不可避免的,所以服務(wù)層必須保證重復(fù)調(diào)用服務(wù)與調(diào)用一次服務(wù)的結(jié)果是相同的,即服務(wù)具有冥等性。
比如轉(zhuǎn)賬交易的操作,就需要通過交易編號對調(diào)用的服務(wù)進行有效性校驗,保證調(diào)用是有效的才能繼續(xù)執(zhí)行。
5 實現(xiàn)高可用的數(shù)據(jù)層
對網(wǎng)站而言,最高貴的資產(chǎn)是多年運營積累下來的數(shù)據(jù)(用戶數(shù)據(jù)、交易數(shù)據(jù)、商品數(shù)據(jù)等)。所以保護了數(shù)據(jù)就是保護了企業(yè)的命脈。
保證數(shù)據(jù)高可用的手段是數(shù)據(jù)備份和失效轉(zhuǎn)移:
- 數(shù)據(jù)備份 - 保證數(shù)據(jù)有多個副本,任意副本的失效不會導(dǎo)致數(shù)據(jù)的永久丟失。
- 失效轉(zhuǎn)移 - 當(dāng)一個數(shù)據(jù)副本不可訪問時,可以快速地切換到其他副本。
注意:緩存服務(wù)不是數(shù)據(jù)存儲服務(wù),緩存服務(wù)器的宕機所引起的緩存數(shù)據(jù)丟失而導(dǎo)致的服務(wù)器負(fù)載過高的情況,應(yīng)該通過其他手段進行解決??梢宰屨麄€網(wǎng)站共享一個分布式緩存集群,應(yīng)用只需要向共享緩存集群申請緩存資源即可。這樣任何一臺緩存服務(wù)器宕機所引起的緩存失效,都只會影響到緩存數(shù)據(jù)的一小部分,而不會對應(yīng)用的性能和數(shù)據(jù)庫負(fù)載造成太大的影響。
5.1 CAP 原理
為了保證數(shù)據(jù)的高可用,網(wǎng)站通常會犧牲數(shù)據(jù)的一致性。
高可用的數(shù)據(jù)有這幾層含義:
- 數(shù)據(jù)持久性 - 保證數(shù)據(jù)可持久存儲,即把數(shù)據(jù)寫入可持久性存儲的硬件的同時,還需要把數(shù)據(jù)備份成一個或多個副本。
- 數(shù)據(jù)可訪問性 -把多個數(shù)據(jù)副本存儲在不同的存儲設(shè)備下,如果一個存儲設(shè)備損壞,就需要把對數(shù)據(jù)的訪問切換到另一個數(shù)據(jù)存儲設(shè)備上。這個過程要盡量快,讓客戶不可感知。
- 數(shù)據(jù)一致性 - 在數(shù)據(jù)有多個副本的情況下,如果網(wǎng)絡(luò)、服務(wù)器或軟件出現(xiàn)故障,會導(dǎo)致部分副本寫入成功,部分寫入失敗。這樣就會造成各個副本之間存在數(shù)據(jù)不一致的情況。

CPA 原理認(rèn)為:一個提供數(shù)據(jù)服務(wù)的存儲系統(tǒng)無法同時滿足數(shù)據(jù)一致性(Consistency)、數(shù)據(jù)可用性(Availability )、分區(qū)耐受性(Patition Tolerance)這三個條件。
大型網(wǎng)站中,數(shù)據(jù)規(guī)模會快速擴張,因此可伸縮性(分區(qū)耐受性)必不可少;規(guī)模變大后,機器數(shù)量也會變得龐大,這時網(wǎng)絡(luò)和服務(wù)器故障就會頻繁出現(xiàn),所以網(wǎng)站使用了分布式系統(tǒng)保證應(yīng)用高可用。一般情況下,大型網(wǎng)站大都會強化存儲系統(tǒng)的可用性(A)和伸縮性(P),在某種程度上放棄一致性(C)。
CPA 原理告訴我們:在系統(tǒng)設(shè)計開發(fā)的過程中,如果不恰當(dāng)?shù)赜细鞣N需求,就會使設(shè)計進入兩難境地,難以為繼。
數(shù)據(jù)的一致性有這幾個級別:
- 數(shù)據(jù)強一致 - 各個副本的數(shù)據(jù)在物理存儲中總是一致的。
- 數(shù)據(jù)用戶一致 - 各個副本的數(shù)據(jù)可能是不一致的,但當(dāng)用戶訪問時,通過糾錯和校驗機制,可以確定一個一致的、正確的數(shù)據(jù)返回給用戶。
- 數(shù)據(jù)最終一致 - 這是數(shù)據(jù)一致性中最弱的一種。系統(tǒng)經(jīng)過一段時間(比較短的時間)的自我修復(fù),數(shù)據(jù)會達(dá)到最終的一致。
數(shù)據(jù)強一致很難達(dá)到,所以網(wǎng)站會綜合考慮成本、技術(shù)、業(yè)務(wù)場景等因素,使用數(shù)據(jù)監(jiān)控和糾錯功能,達(dá)到“數(shù)據(jù)用戶一致”。
5.2 備份數(shù)據(jù)
早期的數(shù)據(jù)備份主要是冷備份,即定期地將數(shù)據(jù)復(fù)制到存儲介質(zhì)中(磁帶、光盤等)并物理存檔保存。
冷備份的優(yōu)點是簡單、廉價。缺點是不能保證數(shù)據(jù)最終一致。因為數(shù)據(jù)是定期復(fù)制,所以備份設(shè)備中的數(shù)據(jù)比系統(tǒng)的數(shù)據(jù)來的舊,如果系統(tǒng)數(shù)據(jù)發(fā)生丟失,那么從上一個備份點開始后,更新的數(shù)據(jù)就會永久丟失,不能恢復(fù)。
冷備份作為一個傳統(tǒng)的數(shù)據(jù)保護手段,依然在網(wǎng)站日常運維中使用。但還需要進行數(shù)據(jù)熱備份,以提供更好的數(shù)據(jù)可用性。
數(shù)據(jù)熱備份有兩種:異步熱備和同步熱備。
5.2.1 異步熱備
異步熱備指的是,使用異步方式寫入多個數(shù)據(jù)副本。應(yīng)用收到存儲系統(tǒng)的寫操作成功響應(yīng)時,實際上只成功寫入了一份,其他副本由存儲系統(tǒng)異步寫入(可能會失?。?/p>

存儲服務(wù)器分為主服務(wù)器(Master )和從服務(wù)器(Slave )。應(yīng)用只連接到主服務(wù)器。寫入數(shù)據(jù)時,由主服務(wù)器上的寫操作代理模塊,把數(shù)據(jù)寫入本機后立即返回寫操作成功響應(yīng),然后通過異步線程把寫操作的數(shù)據(jù)同步到存儲服務(wù)器。
關(guān)系型數(shù)據(jù)庫的熱備機制就是 Master-Slave 同步機制。這樣不但實現(xiàn)了數(shù)據(jù)備份,還改善了性能。因為在實踐中,通常采用讀寫分離的方法來訪問數(shù)據(jù)庫。寫操作只訪問 Master 數(shù)據(jù)庫,讀操作只訪問 Slave 數(shù)據(jù)庫。
5.2.2 同步熱備
同步熱備指的是,同步寫入多個數(shù)據(jù)副本,都寫入成功后,應(yīng)用才會收到寫成功響應(yīng)。如果應(yīng)用收到寫失敗響應(yīng)時(網(wǎng)絡(luò)或系統(tǒng)故障),可能有部分或全部副本都已寫入成功,這時就要進行糾錯咯。

為了提高性能,應(yīng)用的客戶端會并發(fā)地向多個存儲服務(wù)器同時寫入數(shù)據(jù),然后等待所有的存儲服務(wù)器都返回操作成功的響應(yīng)后,才會通知應(yīng)用寫操作成功。
這里的存儲服務(wù)器是完全對等,這樣有利于管理與維護。總的寫操作延遲是那個響應(yīng)最慢的存儲服務(wù)器。
不管是關(guān)系型數(shù)據(jù)庫還是 NoSQL 數(shù)據(jù)庫,都提供了數(shù)據(jù)實時備份功能。
5.3 失效轉(zhuǎn)移
失效轉(zhuǎn)移指的是,服務(wù)器集群中,如果任何一臺服務(wù)器宕機,那么應(yīng)用所針對這臺服務(wù)器的所有讀寫操作,都需要重新路由到其他服務(wù)器,保證服務(wù)依然是可用的。
失效轉(zhuǎn)移有這些部分:
1.失效確認(rèn)
系統(tǒng)通過心跳檢測和應(yīng)用訪問失敗的報告來確認(rèn)某臺服務(wù)器是否宕機:

對于應(yīng)用程序的訪問失敗報告,控制中心還需要再發(fā)送一次心跳檢測對服務(wù)器進行確認(rèn),以免應(yīng)用程序判斷錯誤。因為一旦進行失效轉(zhuǎn)移,就會出現(xiàn)存儲的多份數(shù)據(jù)副本不一致,那么后續(xù)就要對這種情況進行一系列復(fù)雜的糾錯操作。
2. 訪問轉(zhuǎn)移
確認(rèn)服務(wù)器宕機后,就要把數(shù)據(jù)的讀寫訪問重新路由到其他的服務(wù)器上。這又分為兩種情況:
- 存儲完全對等:直接切換到對等服務(wù)器上。
- 存儲不對等:重新計算路由,選擇健康的服務(wù)器。
3. 數(shù)據(jù)恢復(fù)
某臺服務(wù)器宕機后,數(shù)據(jù)存儲的副本就會減少,這時系統(tǒng)會從健康的服務(wù)器上復(fù)制數(shù)據(jù),把副本的數(shù)目恢復(fù)到系統(tǒng)設(shè)定的值。
6 高可用質(zhì)量保證
6.1 發(fā)布網(wǎng)站
網(wǎng)站的發(fā)布實際上與服務(wù)器的宕機效果相當(dāng),因為需要關(guān)閉服務(wù)器上原有的應(yīng)用,然后重新部署啟動新的應(yīng)用。
但網(wǎng)站的發(fā)布畢竟是一次提前預(yù)知的“服務(wù)器宕機”,因為過程可以更柔和,對用戶的影響可以更小。我們通常使用腳本來完成發(fā)布。

因為每次關(guān)閉的服務(wù)器只是集群中的一小部分,而且在發(fā)布完成后可以立即訪問,所以整個發(fā)布過程并不影響用戶的使用。
6.2 自動化測試
代碼在發(fā)布到服務(wù)器之前需要進行嚴(yán)格的測試。即使發(fā)布的新功能都是在原有系統(tǒng)的功能上進行小幅的增加,也需要對整個網(wǎng)站功能進行全面的回歸測試。此外,還要針對各種瀏覽器進行兼容性測試。
大部分網(wǎng)站都是采用 Web 自動化測試技術(shù)。比較流行的是 Selenium。它運行于瀏覽器,可以模擬用戶的操作進行測試,因此 Selenium 可以同時完成 Web 功能測試和瀏覽器兼容性測試。
大型網(wǎng)站會開發(fā)自有的自動化測試工具,實現(xiàn)一鍵部署、生成測試數(shù)據(jù)、執(zhí)行測試和生成測試報告等測試過程。測試工程師的編碼能力毫不遜于軟件工程師哦O(∩_∩)O~
6.3 預(yù)發(fā)布過程
即使經(jīng)過了嚴(yán)格測試,部署到現(xiàn)網(wǎng)后還是有可能出現(xiàn)問題。因為測試環(huán)境與現(xiàn)網(wǎng)環(huán)境不同,特別是應(yīng)用可能會依賴的其他服務(wù),諸如數(shù)據(jù)庫、緩存以及第三方的服務(wù)(短信網(wǎng)關(guān)、網(wǎng)銀接口等)。
因此在發(fā)布時,可以先把包發(fā)布到 “預(yù)發(fā)布服務(wù)器” 上,這樣開發(fā)與測試工程師就可以在預(yù)發(fā)布服務(wù)器進行驗證咯,一般會測試一些典型的業(yè)務(wù)流程,確認(rèn)系統(tǒng)沒有問題后才會正式發(fā)布。
預(yù)發(fā)布服務(wù)器與正式服務(wù)器的不同之處是:外部用戶無法訪問(沒有配置在負(fù)載均衡服務(wù)器上)。

預(yù)發(fā)布服務(wù)器與線上的正式服務(wù)器部署在相同的物理環(huán)境上(同一個數(shù)據(jù)中心或同一個機架,如果使用虛擬機,甚至可以部署在同一個物理服務(wù)器上),使用相同的線上配置,依賴同樣的外部服務(wù)。工程師在開發(fā)機上配置 hosts 文件綁定域名,這樣就可以訪問到預(yù)發(fā)布服務(wù)器咯。如果預(yù)發(fā)布服務(wù)器執(zhí)行的驗證通過的話,基本上可以確保部署到線上的正式服務(wù)器沒有問題。
但有可能會因為預(yù)發(fā)布驗證而引入新的問題。因為預(yù)發(fā)布服務(wù)器連接的是真實的生產(chǎn)環(huán)境,所以,所有的預(yù)發(fā)布驗證操作的都是真實有效的數(shù)據(jù),這些操作會引起某些不可預(yù)期的問題。比如上架了一個商品,可能真的會有用戶過來購買,如果不能發(fā)貨,那就慘了哦。
注意:在應(yīng)用中應(yīng)該強調(diào) “快速失敗” 的錯誤理念。即如果在系統(tǒng)啟動時發(fā)現(xiàn)問題就立刻拋出異常,讓工程師可以盡快介入解決問題。
6.4 代碼控制
代碼控制的核心問題是如何進行代碼管理,即能保證代碼發(fā)布的版本穩(wěn)定正確,又能保證不同團隊的開發(fā)互不影響。
目前大部分網(wǎng)站的源代碼版本控制工具是 SVN 與 Git。
SVN 的代碼控制發(fā)布的方式有兩種:
1. 主干開發(fā)、分支發(fā)布
修改都在主干(trunk)上進行,在需要發(fā)布的時候,從主干上拉出一個分支(branch)發(fā)布,這個分支就是一個發(fā)布版本,如果這個版本發(fā)現(xiàn)了 bug,就繼續(xù)在該分支上修改發(fā)布,并將修改合并(merge)回主干,直到下一次發(fā)布。
2. 分支開發(fā)、主干發(fā)布
任何修改都不得在主干上進行。需要開發(fā)新功能或修復(fù) bug 時,就從主干上拉下一個分支進行開發(fā),開發(fā)完成并測試通過后,合并回主干,然后從主干上發(fā)布,主干上的代碼永遠(yuǎn)是最新發(fā)布的版本。
“主干開發(fā)、分支發(fā)布” 的方式,主干代碼反映的是目前應(yīng)用的狀態(tài),便于管理和控制,也有利于持續(xù)集成。
“ 分支開發(fā)、主干發(fā)布” 的方式,各個分支獨立進行,互不干擾,因此可以同時進行不同發(fā)布周期的執(zhí)行過程。
目前網(wǎng)站應(yīng)用主要使用的是 “ 分支開發(fā)、主干發(fā)布” 的方式:

同一個應(yīng)用,有可能 A 項目發(fā)布時, B 項目還在開發(fā)中,那么“ 分支開發(fā)、主干發(fā)布” 的方式,只需要將 A 項目的分支合并回主干即可,這樣可以不受 B 項目發(fā)布時間的影響。
Git 目前正逐步取代 SVN。雖然 Git 學(xué)習(xí)成本較高,但它對分布式開發(fā)和分支開發(fā)等有更好的支持,而且可以更容易在各個開發(fā)分支上及時反映出主干上的最新更新(代碼變得更容易合并啦)。相信 Git 遲早會成為網(wǎng)站標(biāo)準(zhǔn)版本的控制工具。
6.5 自動化發(fā)布
很多網(wǎng)站選擇周四作為發(fā)布日,這樣一周的前三天可以做好發(fā)布準(zhǔn)備,后面一天可以挽回錯誤。如果選擇的是周五,那么如果發(fā)現(xiàn)了問題,就必須周末來加班咯。
使用 “火車發(fā)布模型” 可以有效地控制發(fā)布故障、減少發(fā)布日的加班問題。
火車發(fā)布模型是這樣的:可以把應(yīng)用的發(fā)布過程看做是一次火車旅行。旅行路線上有若干個站點,每一站都要進行例行檢查。不通過的項目就下車,剩下的項目繼續(xù)旅行,直到達(dá)到終點(應(yīng)用發(fā)布成功)。

火車發(fā)布模型是基于規(guī)則驅(qū)動的流程,所以可以自動化。因為人工干預(yù)的越少,自動化程度就會越高,引入故障的可能性也就越小。
6.6 灰度發(fā)布
應(yīng)用發(fā)布成功后,仍可能因為軟件問題而引入故障。這時候就要做發(fā)布回滾,即卸載剛剛發(fā)布的軟件,將上一個版本的軟件包重新發(fā)布,復(fù)原系統(tǒng)。
大型網(wǎng)站的服務(wù)器集群規(guī)模非常大,有的甚至超過一萬臺。一旦發(fā)生故障,回滾也需要花費很長的時間才能完成。所以大型網(wǎng)站一般使用灰度發(fā)布模式:即把集群服務(wù)器分為若干部分,每天只發(fā)布一部分服務(wù)器,觀察運行穩(wěn)定沒有出現(xiàn)故障,那么第二天再繼續(xù)發(fā)布另一部分的服務(wù)器,這樣持續(xù)幾天才會把整個集群都發(fā)布完畢。期間如果發(fā)現(xiàn)問題,就只需要回滾那些已發(fā)布的那部分服務(wù)器就好啦O(∩_∩)O~

灰度發(fā)布模型也常用于用戶測試,即在部分服務(wù)器上發(fā)布新版本,其余服務(wù)器保持舊版本,然后監(jiān)控用戶的操作行為,通過用戶的體驗報告,就可以比較出用戶對新舊兩個版本的滿意度,以確定最終的發(fā)布版本。這也被稱為 AB 測試。
7 運行監(jiān)控
沒有被監(jiān)控的系統(tǒng)不能上線! 因為運行監(jiān)控對于網(wǎng)站運維與架構(gòu)設(shè)計優(yōu)化至關(guān)重要。
7.1 采集監(jiān)控數(shù)據(jù)
- 收集用戶行為日志
用戶行為日志指的是用戶在瀏覽器所做的所有操作以及用戶所在的操作環(huán)境(操作系統(tǒng)與瀏覽器的版本、IP 地址、頁面訪問路徑、頁面停留時間等)。
有兩種收集對象:
- 服務(wù)端日志 - 開啟 web 服務(wù)器的日志記錄即可。缺點是可能出現(xiàn)信息失真,比如 IP 地址可能是代理服務(wù)器的地址。
- 客戶端瀏覽器日志 - 嵌入專門的 JavaScript 腳本就可以收集用戶真實的操作行為。缺點是麻煩,因為需要在頁面中嵌入特定的腳本。
大型網(wǎng)站的用戶日志數(shù)據(jù)量驚人,數(shù)據(jù)存儲與計算的壓力都很大,所以許多網(wǎng)站都逐步開發(fā)了基于實時計算框架 Apache Storm 的日志統(tǒng)計與分析工具。
2.監(jiān)控服務(wù)器性能
運維人員在初始化系統(tǒng)時統(tǒng)一部署,收集服務(wù)器性能指標(biāo)。根據(jù)監(jiān)控到的數(shù)據(jù),運維工程師可以合理安排服務(wù)器的集群規(guī)模,架構(gòu)師可以及時改善系統(tǒng)的性能和調(diào)整伸縮性策略。
目前使用廣泛的性能監(jiān)控工具是 Ganglia,它支持大規(guī)模的服務(wù)器集群,并支持以圖形的方式在瀏覽器中展示實時的性能曲線。
- 運行數(shù)據(jù)報告
應(yīng)用需要在代碼中加入采集運行數(shù)據(jù)的邏輯,匯總后統(tǒng)一顯示。
7.2 監(jiān)控管理
- 系統(tǒng)報警
如果監(jiān)控的某項指標(biāo)超過了閾值,那就意味著系統(tǒng)可能將要出現(xiàn)故障,這時就要對相關(guān)人員進行報警。
監(jiān)控管理系統(tǒng)可以配置報警的閾值和值守人員的聯(lián)絡(luò)方式(通過郵件、即時通信工具、手機短信等方式),及時發(fā)出預(yù)警。
- 失效轉(zhuǎn)移
監(jiān)控系統(tǒng)在發(fā)現(xiàn)故障時應(yīng)該主動通知應(yīng)用,及時進行失效轉(zhuǎn)移。
- 自動優(yōu)雅降級
優(yōu)雅降級指的是,網(wǎng)站為了應(yīng)付突發(fā)的訪問高峰,會主動關(guān)閉一部分功能,釋放系統(tǒng)資源。
自動優(yōu)雅降級的監(jiān)控系統(tǒng)是一種柔性架構(gòu)的理想狀態(tài):監(jiān)控系統(tǒng)會實時監(jiān)控所有的服務(wù)器,如果發(fā)現(xiàn)某部分的應(yīng)用負(fù)載過高,那么就會適當(dāng)卸載低負(fù)載應(yīng)用的一部分服務(wù)器,重新安裝啟動高負(fù)載的應(yīng)用,使得應(yīng)用負(fù)載總體均衡。如果所有應(yīng)用的負(fù)載都很高,那么就會自動關(guān)閉一部分非重要的功能,保證核心功能的正常運行。
對公司而言,可用性關(guān)系到了網(wǎng)站的生死存亡;對個人而言,可用性關(guān)系到了個人的績效升遷。所以一定要重視呀O(∩_∩)O~