日10億級(jí)處理,基于云的微服務(wù)架構(gòu)
德比軟件:基于云的微服務(wù)架構(gòu)
作者:朱攀,德比軟件架構(gòu)師,同濟(jì)大學(xué)研究生,2007 年 2 月加入德比軟件(DerbySoft),擁有 10 年以上的軟件架構(gòu)和開發(fā)經(jīng)驗(yàn)。目前主要負(fù)責(zé)公司數(shù)據(jù)對(duì)接平臺(tái)的架構(gòu)、基礎(chǔ)設(shè)施建設(shè)、技術(shù)團(tuán)隊(duì)管理及公司技術(shù)的布道。作為德比軟件的早期員工,從無到有地主導(dǎo)了德比軟件數(shù)據(jù)對(duì)接平臺(tái)的架構(gòu)設(shè)計(jì)和實(shí)現(xiàn),完成了數(shù)據(jù)對(duì)接平臺(tái)多個(gè)版本的架構(gòu)改進(jìn)和升級(jí),數(shù)據(jù)對(duì)接平臺(tái)每天處理的 API 調(diào)用從 0 增長到現(xiàn)在的 10 億多。期間設(shè)計(jì)實(shí)現(xiàn)了很多必要的基礎(chǔ)設(shè)施和服務(wù),如公司內(nèi)部的 RPC 框架 DerbySoft-RPC、智能路由服務(wù) Router、分布式數(shù)據(jù)存儲(chǔ)服務(wù) DStorage、網(wǎng)關(guān)服務(wù) DGateway 等。目前主要關(guān)注基礎(chǔ)架構(gòu)、微服務(wù)、大數(shù)據(jù)存儲(chǔ)和技術(shù)團(tuán)隊(duì)建設(shè)。
?
?
10.1???? 概述
?
?
微服務(wù)概念被提出來以后,短時(shí)間內(nèi)就成了互聯(lián)網(wǎng)圈的一個(gè)技術(shù)熱點(diǎn),有很多互聯(lián)網(wǎng)公司計(jì)劃或正在進(jìn)行微服務(wù)化改造,那么應(yīng)該怎么開始實(shí)施微服務(wù)呢?需要哪些基礎(chǔ)設(shè)施來支持呢?我所在的公司德比軟件從 2009 年就開始采用面向服務(wù)架構(gòu)(SOA)來重新實(shí)現(xiàn)數(shù)據(jù)對(duì)接平臺(tái),我們積累了豐富的面向服務(wù)架構(gòu)的經(jīng)驗(yàn),而微服務(wù)架構(gòu)是面向服務(wù)架構(gòu)思想的一種實(shí)現(xiàn),只是服務(wù)職責(zé)更單一,粒度更小,過程更自動(dòng)化。我們?cè)诙嗄甑姆?wù)化架構(gòu)實(shí)踐過程中,已經(jīng)不自覺地將服務(wù)的粒度細(xì)化了。本文想分享德比軟件在實(shí)施微服務(wù)架構(gòu)過程中積累的一些基礎(chǔ)設(shè)施及這些基礎(chǔ)設(shè)施解決的痛點(diǎn)問題,希望對(duì)大家有所幫助和啟發(fā)。
?
?
10.2???? 德比軟件數(shù)據(jù)對(duì)接平臺(tái)的架構(gòu)
?
數(shù)據(jù)對(duì)接平臺(tái)的架構(gòu)大體上分三個(gè)層次,如圖 10.1 所示,最外面是 API 層,由 API Gateway(網(wǎng)關(guān))和各業(yè)務(wù)的 API 服務(wù)組成;中間層是服務(wù)層(Service),平臺(tái)的大部分功能在這一層實(shí)現(xiàn),服務(wù)之間可以通過依賴或組合組成功能更強(qiáng)的服務(wù);底層是數(shù)據(jù)存儲(chǔ)層(Data Storage),由緩存層和存儲(chǔ)層組成。數(shù)據(jù)對(duì)接平臺(tái)采用微服務(wù)架構(gòu),為了支撐這個(gè)架構(gòu),我們提供了必要的基礎(chǔ)設(shè)施來保障上層各個(gè)服務(wù)和應(yīng)用的可用性。
?
圖 10.1
?
?
10.3???? 德比軟件微服務(wù)架構(gòu)基礎(chǔ)設(shè)施
?
如圖 10.2 所示,將基礎(chǔ)設(shè)施分為了八大部分,分別是服務(wù)框架、基礎(chǔ)服務(wù)、API 網(wǎng)關(guān)、自動(dòng)化、服務(wù)降級(jí)、監(jiān)控報(bào)警(服務(wù)健康狀態(tài))、日志處理和調(diào)用鏈追蹤。其中,
服務(wù)框架、基礎(chǔ)服務(wù)、API 網(wǎng)關(guān)和服務(wù)降級(jí)的作用是提高服務(wù)的連續(xù)工作時(shí)間;
自動(dòng)化可以簡化開發(fā)和部署過程;
監(jiān)控報(bào)警、日志處理和調(diào)用鏈追蹤可以幫助快速發(fā)現(xiàn)問題、定位問題并解決問題。
?
圖 10.2
?
?
基礎(chǔ)設(shè)施全景圖如圖 10.3 所示。
?
?
圖 10.3
?
?
10.4???? API 網(wǎng)關(guān)
?
API 網(wǎng)關(guān)是微服務(wù)架構(gòu)中不可或缺的部分。API 網(wǎng)關(guān)是對(duì)外提供的服務(wù),是系統(tǒng)的入口,所有的外部系統(tǒng)都需要通過 API 網(wǎng)關(guān)來接入。Dgateway 提供安全認(rèn)證、流控、路由、 API 版本管理等功能。流控維度分為用戶類型、用戶來源、IP、業(yè)務(wù) API 等,保護(hù)服務(wù)或資源不被濫用或攻擊。DGateway 基于開源軟件 Tyk 做了二次開發(fā)。
?
?
10.5???? 服務(wù)框架
?
服務(wù)框架分兩部分,高可用的 RPC(DerbySoft-RPC)和服務(wù)依賴管理,如圖 10.4 所示。
?
圖?10.4
10.5.1??? 高可用 RPC
?
RPC 是微服務(wù)架構(gòu)中最重要的基礎(chǔ)組件,一個(gè)健壯的 RPC 能有效降低實(shí)施微服務(wù)架構(gòu)的成本。RPC 封裝了遠(yuǎn)程調(diào)用的復(fù)雜細(xì)節(jié),讓服務(wù)使用方感覺像調(diào)用本地方法一樣調(diào)用遠(yuǎn)程方法,服務(wù)提供方感覺像實(shí)現(xiàn)本地接口一樣來實(shí)現(xiàn)服務(wù)。DerbySoft-RPC 分為 Client 和Server 兩部分。Client 主要有以下功能。
?
客戶端故障檢測(cè),識(shí)別并標(biāo)示太慢或崩潰了的服務(wù)器。
?
熔斷機(jī)制,如果發(fā)現(xiàn)服務(wù)超時(shí)比例過限,則啟動(dòng)熔斷,客戶端會(huì)快速返回失敗,以減輕服務(wù)端的壓力,定時(shí)允許部分請(qǐng)求通過,根據(jù)請(qǐng)求返回的健康程度來決定是否恢復(fù)熔斷。
?
負(fù)載均衡策略,通過記錄到每個(gè)節(jié)點(diǎn)的未完成請(qǐng)求數(shù)來決定下一個(gè)請(qǐng)求發(fā)到哪里。容錯(cuò)機(jī)制,對(duì)某些錯(cuò)誤自動(dòng)重試,比如連接的服務(wù)節(jié)點(diǎn)不可用時(shí)可以自動(dòng)將請(qǐng)求再次發(fā)送到其他節(jié)點(diǎn),可定義重試次數(shù)。
?
序列化和反序列化,選擇序列化工具最重要的考量點(diǎn)有性能高低、是否多語言支持、序列化后的消息大小、是否向前兼容等。我們嘗試過各種序列化工具,而 Protocol Buffer 在性能和空間占用上都表現(xiàn)優(yōu)異,是我們使用最頻繁的序列化工具。對(duì)敏感數(shù)據(jù)加密,比如信用卡等敏感信息,需要在 Client 端加密傳輸。
?
超時(shí)管理,可設(shè)定每個(gè)請(qǐng)求的超時(shí)時(shí)間。
Server 部分相對(duì)簡單,主要提供超時(shí)管理、序列化和反序列化、敏感信息解密、隊(duì)列管理、線程管理等功能。
剛才提到選擇序列化工具時(shí)需要考慮是否支持多語言,這一點(diǎn)很重要,RPC 最好能在多語言環(huán)境下實(shí)現(xiàn),這樣能讓技術(shù)團(tuán)隊(duì)突破編程語言限制,使技術(shù)棧更豐富靈活。我們?cè)谶@方面是有過教訓(xùn)的。
在公司早期,大概是 2009 年,當(dāng)時(shí)的業(yè)務(wù)量不大,在語言上主要使用 Java,為了方便我們?cè)诘谝粋€(gè) RPC 版本上采用了 Java 序列化機(jī)制,卻導(dǎo)致后面想要更換編程語言時(shí)大受限制。因此我們做了第二版 RPC,將序列化機(jī)制換掉,采用 Java 的字節(jié)序以兼容第一個(gè)版本。DerbySoft-RPC 是第三版 RPC,實(shí)現(xiàn)了對(duì) Go、Scala 和 Java 三種語言的兼容。原則上我們不限制服務(wù)的實(shí)現(xiàn)語言,只要能按要求實(shí)現(xiàn)服務(wù)接口并滿足性能要求即可。微服務(wù)化后的一個(gè)好處就是根本不用擔(dān)心使用小眾的編程語言,如果每個(gè)服務(wù)的粒度足夠小,那么最壞的情況就是在沒人能維護(hù)這個(gè)小眾語言的服務(wù)時(shí),需要花點(diǎn)時(shí)間用熟悉的語言來重寫。
?
?
10.5.2??? 服務(wù)依賴管理
?
?
微服務(wù)化之后,系統(tǒng)面臨的一個(gè)突出問題是服務(wù)雖小,但是數(shù)量極多。如果這些服務(wù)全部在一個(gè)可用區(qū)內(nèi),那么服務(wù)之間的依賴還比較好管理,可以做服務(wù)自動(dòng)注冊(cè)和發(fā)現(xiàn)來實(shí)現(xiàn)依賴管理,但是如果服務(wù)分布在很多可用區(qū)中,尤其是分布在跨國跨地區(qū)的可用區(qū)之間,則其依賴和調(diào)用的管理就會(huì)比較麻煩。
?
另外,跨可用區(qū)服務(wù)之間的調(diào)用還需要考慮通信安全的問題,對(duì)每個(gè)服務(wù)設(shè)置不同的特殊端口,如果需要跨區(qū)域調(diào)用服務(wù),那么配置訪問權(quán)限也是一件麻煩的事情。
?
眾多服務(wù)的依賴示例如圖 10.5 所示。
?
?
圖 10.5
圖 10.5 所示的服務(wù)依賴是不是很亂?我們的服務(wù)節(jié)點(diǎn)分布在全球 14 個(gè)可用區(qū),大部分在亞馬遜云上,小部分在自建的私有云里,可用區(qū)之間的服務(wù)有復(fù)雜的依賴關(guān)系。為了解決這種情況下服務(wù)之間的依賴調(diào)用問題、API 安全問題和服務(wù)的高可用問題,我們?cè)O(shè)計(jì)開發(fā)了路由服務(wù),以解耦服務(wù)的調(diào)用者和提供者,簡化網(wǎng)絡(luò)拓?fù)浼胺?wù)器的安全配置。引入路由之后,簡化后的服務(wù)之間的依賴關(guān)系如圖 10.6 所示。
?
?
圖 10.6
?
所有的服務(wù)只和路由通信,服務(wù)之間不再相互依賴,每個(gè)服務(wù)只需要依賴并維護(hù)自己所在的可用區(qū)路由節(jié)點(diǎn),路由會(huì)找到調(diào)用的服務(wù)目的地。絕大部分情況下,它在本區(qū)域內(nèi)就能找到相應(yīng)的服務(wù),不需要跨區(qū),這取決于服務(wù)的部署情況。為了提高響應(yīng)速度,每個(gè)可用區(qū)都需要部署關(guān)鍵的服務(wù),除非本可用區(qū)的服務(wù)崩潰了,否則在這種情況下不會(huì)出現(xiàn)跨區(qū)訪問。有些服務(wù)不是那么重要,可能只會(huì)在某個(gè)或某幾個(gè)可用區(qū)中部署,這時(shí)也可能會(huì)出現(xiàn)服務(wù)跨可用區(qū)調(diào)用的情況。
這樣不僅更好地管理了依賴,解決了服務(wù)器可用區(qū)調(diào)用問題,還解決了 API 訪問安全問題:每個(gè)可用區(qū)建立一個(gè) VPC(虛擬私有云),所有的服務(wù)都在 VPC 內(nèi),VPC 內(nèi)的 API 調(diào)用可忽略安全驗(yàn)證,跨 VPC 路由節(jié)點(diǎn)之間用安全組來限制 IP 白名單訪問,只允許路由節(jié)點(diǎn)可以跨可用區(qū)訪問其他 VPC 內(nèi)的路由節(jié)點(diǎn),服務(wù)訪問路由或者路由訪問服務(wù)都必須在同一個(gè) VPC 內(nèi)使用內(nèi)網(wǎng)地址訪問。
?
10.6???? 基礎(chǔ)服務(wù)
?
?
基礎(chǔ)服務(wù)分為四部分,分別是配置中心、安全數(shù)據(jù)服務(wù)、數(shù)據(jù)存儲(chǔ)服務(wù)、訂單服務(wù),如圖 10.7 所示。基礎(chǔ)服務(wù)大多和存儲(chǔ)有關(guān),提供高性能、高可用的服務(wù)。
?
?
圖 10.7
?
10.6.1??? 配置中心
?
?
配置中心提供高可用的配置數(shù)據(jù)存儲(chǔ)服務(wù),幾乎所有的應(yīng)用和服務(wù)都依賴配置中心。配置中心主要解決基礎(chǔ)數(shù)據(jù)和配置數(shù)據(jù)的單點(diǎn)依賴及節(jié)點(diǎn)之間的數(shù)據(jù)同步問題,以便更好地支持各個(gè)服務(wù)的水平伸縮。配置中心可以配置主鍵、索引字段、唯一約束、每個(gè)字段的類型約束等,其功能類似于數(shù)據(jù)庫,開放全量和變量的同步接口,提供多語言的客戶端 SDK,同步全量或變量數(shù)據(jù),根據(jù)服務(wù)端的配置,在內(nèi)存中建立數(shù)據(jù)索引,緩存數(shù)據(jù),并在本地文件中持久化緩存的備份,如圖 10.8 所示。
圖 10.8
?
一個(gè)依賴配置中心的服務(wù),在啟動(dòng)時(shí)會(huì)先查找本地文件中有沒有配置數(shù)據(jù)的緩存,如果有,則從文件中加載配置數(shù)據(jù)到內(nèi)存中,啟動(dòng)服務(wù),接著調(diào)用變量接口對(duì)比本地?cái)?shù)據(jù)和配置中心的數(shù)據(jù)是否是同一版本,如果數(shù)據(jù)有變化,則更新數(shù)據(jù)到本地緩存。如果本地文件中沒有配置數(shù)據(jù)的緩存,則先調(diào)用一次全量接口緩存所有配置數(shù)據(jù)到本地緩存。即使配置中心的所有節(jié)點(diǎn)都無法運(yùn)行,也不影響各個(gè)依賴它服務(wù)的現(xiàn)有節(jié)點(diǎn)的正常工作。
?
因?yàn)槊總€(gè)服務(wù)都會(huì)緩存依賴的配置數(shù)據(jù),所以對(duì)配置中心的性能要求不是太高,我們用 AWS RDS 來解決配置數(shù)據(jù)存儲(chǔ)的高可用問題。AWS RDS 是一個(gè)托管關(guān)系數(shù)據(jù)庫服務(wù)。
?
10.6.2??? 安全數(shù)據(jù)服務(wù)
?
?
高可用的安全數(shù)據(jù)服務(wù)提供數(shù)據(jù)加密和解密服務(wù),定時(shí)清理過期的數(shù)據(jù),解決敏感數(shù)據(jù)的安全臨時(shí)存儲(chǔ)和傳輸問題,比如銀行卡和信用卡信息的臨時(shí)存儲(chǔ)和傳輸。需要傳輸敏感信息時(shí),在數(shù)據(jù)傳輸方調(diào)用數(shù)據(jù)加密服務(wù)的加密接口,并明確信息有效時(shí)間,加密服務(wù)會(huì)將信息加密后存儲(chǔ),并返回一個(gè)全局唯一 ID,數(shù)據(jù)傳輸方發(fā)送這個(gè)唯一 ID 給數(shù)據(jù)接收方,如果數(shù)據(jù)接收方收到這個(gè) ID 之后,調(diào)用數(shù)據(jù)解密接口,則加密服務(wù)會(huì)根據(jù) ID 找到相應(yīng)的數(shù)據(jù),返回解密之后的數(shù)據(jù)。
?
?
10.6.3??? 數(shù)據(jù)存儲(chǔ)服務(wù)
?
Dstorage 提供高可用的酒店動(dòng)態(tài)數(shù)據(jù)存儲(chǔ)服務(wù),可以解決酒店海量動(dòng)態(tài)數(shù)據(jù)存儲(chǔ)問題,提供高性能的數(shù)據(jù)存取接口,提供變量數(shù)據(jù)的同步接口。根據(jù)性能和容量需求,用戶可選的存儲(chǔ)引擎有 Redis、Codis、Ardb、DynamoDB 等。DStorage 支持多可用區(qū)部署,通過變化發(fā)現(xiàn)服務(wù),實(shí)現(xiàn)多可用區(qū)的數(shù)據(jù)同步,保證數(shù)據(jù)最終一致性。
?
Dcontent 提供高可用的酒店靜態(tài)數(shù)據(jù)緩存服務(wù)可以解決酒店海量靜態(tài)數(shù)據(jù)的緩存問題。底層支持的存儲(chǔ)引擎有 Ardb、Redis 等。DContent 支持一主多從多可用區(qū)部署,也支持多主多可用區(qū)部署,保證數(shù)據(jù)最終一致性。
?
AWS S3 提供高可用的文件存儲(chǔ)服務(wù),可以存儲(chǔ)文件數(shù)據(jù),如圖片、視頻、日志文件、備份數(shù)據(jù)等。
?
?
10.6.4??? 訂單服務(wù)
?
?
由于訂單數(shù)據(jù)比較特殊,所以將與訂單相關(guān)的功能單獨(dú)出來,作為獨(dú)立服務(wù)。訂單服務(wù)聚合所有系統(tǒng)節(jié)點(diǎn)的訂單信息,讓訂單比較容易追溯,提供高可用的訂單存儲(chǔ)和查詢服務(wù),解決訂單數(shù)據(jù)的單點(diǎn)存儲(chǔ)問題,更好地支持其他依賴訂單數(shù)據(jù)的系統(tǒng)進(jìn)行水平擴(kuò)展和遷移。訂單服務(wù)對(duì)可用性要求極高,底層存儲(chǔ)依賴 AWS RDS,在全球每個(gè)可能用到訂單服務(wù)的可用區(qū)部署訂單服務(wù)集群。
?
?
10.7???? 服務(wù)降級(jí)
?
?
根據(jù)業(yè)務(wù)要求對(duì)每個(gè)服務(wù)及其依賴的資源按重要程度進(jìn)行分級(jí),限制每個(gè)依賴服務(wù)的超時(shí)時(shí)間,定義各級(jí)服務(wù)的 SLA 指標(biāo),對(duì)強(qiáng)依賴的基礎(chǔ)服務(wù)或資源實(shí)行更高的 SLA 標(biāo)準(zhǔn),根據(jù) SLA 指標(biāo)制定容錯(cuò)方案。
?
制定服務(wù)自動(dòng)降級(jí)策略,設(shè)置服務(wù)開關(guān),關(guān)鍵時(shí)刻“棄車保帥”,對(duì)弱依賴的服務(wù)進(jìn)行降級(jí),比如將日志服務(wù)降級(jí)以保障重要的服務(wù)不受影響。
?
對(duì)超大數(shù)據(jù)或流量用戶進(jìn)行隔離,在隔離的環(huán)境中為這部分用戶提供獨(dú)立的服務(wù),避免影響其他正常用戶服務(wù)。
?
?
10.8???? 自動(dòng)化
?
?
微服務(wù)化后,服務(wù)的數(shù)量很多,為了節(jié)約開發(fā)成本,必須盡可能地自動(dòng)化完成一些有固定步驟的工作,如自動(dòng)化測(cè)試和自動(dòng)化部署,如圖 10.9 所示。
圖 10.9
?
1.自動(dòng)化測(cè)試。
?
單元測(cè)試自動(dòng)化:我們目前要求單元測(cè)試覆蓋率大于 90%,通過 Jenkins 整合 Sonar。每次提交代碼后自動(dòng)運(yùn)行單元測(cè)試,Sonar 會(huì)自動(dòng)給出代碼評(píng)分,如果測(cè)試覆蓋率不夠或代碼不達(dá)標(biāo),則單元測(cè)試失敗。
?
性能測(cè)試自動(dòng)化、平臺(tái)化:我們開發(fā)了自動(dòng)化測(cè)試平臺(tái) DTesting,關(guān)鍵服務(wù)的每次變更都需要在平臺(tái)上進(jìn)行性能測(cè)試,并生成性能測(cè)試報(bào)告,對(duì)比歷史的性能測(cè)試數(shù)據(jù)。
?
功能測(cè)試自動(dòng)化、平臺(tái)化:每個(gè)應(yīng)用都有完整的功能測(cè)試用例和腳本,可自動(dòng)化回歸功能測(cè)試。
?
2.自動(dòng)化部署。
我們引入了 Docker,以減少人為部署時(shí)的誤操作。
?
?
10.9???? 日志處理
?
?
日志處理分為兩部分:一部分是實(shí)時(shí)日志處理,另一部分是冷日志處理。所有的應(yīng)用日志都需要寫入 Kafka 和文件,Kafka 中所有的實(shí)時(shí)日志都會(huì)被 DLog 系統(tǒng)及時(shí)消費(fèi)處理,但是實(shí)時(shí)日志的保留時(shí)間不長,一般保留一個(gè)月。寫入文件的所有日志會(huì)被定時(shí)備份到 AWS S3 上永久保留,如果需要一個(gè)月前甚至更久以前的系統(tǒng)日志,則可以在 DLog 系統(tǒng)中選擇需要的日志范圍,DLog 會(huì)將符合條件的日志從 S3 上下載下來并重新建立日志索引。日志主要是為監(jiān)控提供基礎(chǔ)源數(shù)據(jù),為定位問題提供依據(jù),如圖 10.10 所示。
圖 10.10
?
?
10.10???? 調(diào)用鏈追蹤
?
?
隨著服務(wù)的粒度越來越小,系統(tǒng)的服務(wù)變得越來越多,不同的服務(wù)可能由不同的團(tuán)隊(duì)實(shí)現(xiàn),一個(gè)服務(wù)的實(shí)現(xiàn)可能會(huì)依賴幾個(gè)甚至十幾個(gè)服務(wù)。對(duì)于出現(xiàn)問題后,如何快速準(zhǔn)確地定位故障,如何追蹤業(yè)務(wù)的處理順序和結(jié)果,業(yè)內(nèi)已經(jīng)有了一些實(shí)踐和解決方案,Google Dapper 是 Google 研發(fā)的分布式跟蹤系統(tǒng),Google 也為此發(fā)表論文闡述了分布式跟蹤系統(tǒng)的理論基礎(chǔ),給分布式跟蹤的實(shí)現(xiàn)提供了非常好的參考示范。對(duì)于 Java 編寫的服務(wù),我們采用 Zipkin 來做調(diào)用鏈跟蹤,Zipkin 是 Google Dapper 系統(tǒng)的開源實(shí)現(xiàn),采用 Scala 編寫;
?
而對(duì)于 Go 語言實(shí)現(xiàn)的服務(wù),我們目前還沒有好的解決方案。一個(gè)好的調(diào)用鏈追蹤系統(tǒng)能為定位和排查故障提供強(qiáng)有力的支持。對(duì)于微服務(wù)架構(gòu),調(diào)用鏈追蹤是必備的基礎(chǔ)設(shè)施。
?
?
10.11??? 服務(wù)健康狀態(tài)
?
?
很多情況下,解決故障可能很快,難點(diǎn)在于發(fā)現(xiàn)故障和定位故障,這需要我們的系統(tǒng)有全方位的監(jiān)控和報(bào)警能力?;跇I(yè)務(wù)和技術(shù)對(duì)可用性的需求,我們開發(fā)了服務(wù)健康狀態(tài)監(jiān)控和報(bào)警系統(tǒng),從業(yè)務(wù)層、服務(wù)層、硬件基礎(chǔ)設(shè)施層分別進(jìn)行監(jiān)控和報(bào)警,如圖 10.11 所示。
?
10.11.1??? 報(bào)警
?
?
報(bào)警系統(tǒng)定義所有報(bào)警種類、報(bào)警級(jí)別、處理流程,并提供報(bào)警接入機(jī)制,各個(gè)層次的監(jiān)控都可以通過自定義報(bào)警引擎接入報(bào)警系統(tǒng)來觸發(fā)報(bào)警。7 × 24 小時(shí)服務(wù)監(jiān)控團(tuán)隊(duì)會(huì)根據(jù)各個(gè)報(bào)警的處理流程,依次聯(lián)系最高優(yōu)先級(jí)的處理人來處理故障,如果在規(guī)定時(shí)間內(nèi)沒有處理完畢,則系統(tǒng)會(huì)根據(jù)報(bào)警的種類和級(jí)別自動(dòng)升級(jí)報(bào)警響應(yīng)級(jí)別,提高處理優(yōu)先級(jí)來保障重要的報(bào)警能得到及時(shí)處理。
?
圖 10.11
?
10.11.2??? 監(jiān)控
?
監(jiān)控分為硬件基礎(chǔ)設(shè)施層監(jiān)控、服務(wù)層監(jiān)控和業(yè)務(wù)層監(jiān)控三大類。
?
硬件基礎(chǔ)設(shè)施層監(jiān)控,包括操作系統(tǒng)、內(nèi)存、CPU、網(wǎng)絡(luò)流量和狀態(tài)、連接數(shù)等方面的監(jiān)控。我們用 Zabbix 來做基礎(chǔ)設(shè)施層的監(jiān)控,通過 Zabbix 的 API 將數(shù)據(jù)整合進(jìn)我們的監(jiān)控系統(tǒng) DMonitor。
?
服務(wù)層監(jiān)控,包括基礎(chǔ)組件監(jiān)控、基礎(chǔ)服務(wù)監(jiān)控、常規(guī)服務(wù)監(jiān)控和外部接口調(diào)用監(jiān)控。其中,基礎(chǔ)組件監(jiān)控包括對(duì) Etcd、AWS RDS、Redis、Docker、Kafka 等基礎(chǔ)組件使用情況的監(jiān)控;基礎(chǔ)服務(wù)監(jiān)控包括對(duì)配置中心服務(wù)、認(rèn)證服務(wù)、安全存儲(chǔ)服務(wù)、路由服務(wù)、API Gateway 等關(guān)鍵服務(wù)的監(jiān)控;常規(guī)服務(wù)監(jiān)控則是監(jiān)控所有一般服務(wù)的狀態(tài);而外部接口調(diào)用監(jiān)控是監(jiān)控分析系統(tǒng)依賴的外部訪問情況,包括訪問量、錯(cuò)誤信息、超時(shí)狀況等,為快速定位問題提供依據(jù)。
?
業(yè)務(wù)層監(jiān)控,是指從業(yè)務(wù)角度出發(fā),收集和分析業(yè)務(wù)層的訪問量,根據(jù)各個(gè)業(yè)務(wù)的歷史數(shù)據(jù)和已知的影響因素預(yù)測(cè)現(xiàn)在和未來的業(yè)務(wù)情況,定義監(jiān)控報(bào)警目標(biāo)。比如,在最近半個(gè)小時(shí)內(nèi)某個(gè)業(yè)務(wù)的請(qǐng)求量小于預(yù)期值,在最近 1 個(gè)小時(shí)內(nèi)對(duì)某個(gè)客戶的 API 調(diào)用次數(shù)超過預(yù)期值,在最近 3 個(gè)小時(shí)內(nèi)某酒店的訂單量顯著下降,等等。由于業(yè)務(wù)層的監(jiān)控比較多,因此我們把業(yè)務(wù)層的監(jiān)控獨(dú)立出了一個(gè)子系統(tǒng)。業(yè)務(wù)層監(jiān)控報(bào)警的決策來源于歷史數(shù)據(jù)和未來可能影響系統(tǒng)的因子,通過對(duì)歷史中的海量數(shù)據(jù)進(jìn)行匯總加工和分析,從各個(gè)維度給出報(bào)警的預(yù)期值。
?
服務(wù)層監(jiān)控和業(yè)務(wù)層監(jiān)控都離不開各個(gè)應(yīng)用的支持,有些監(jiān)控目標(biāo)會(huì)對(duì)應(yīng)用的實(shí)現(xiàn)有侵入性,比如需要寫業(yè)務(wù)日志,各個(gè)應(yīng)用根據(jù)監(jiān)控的目標(biāo)來設(shè)計(jì)和實(shí)現(xiàn),為業(yè)務(wù)層監(jiān)控提供必要的技術(shù)支持,因此從系統(tǒng)架構(gòu)層面開始就需要考慮業(yè)務(wù)的可用性需求。有了服務(wù)健
?
康狀態(tài)的監(jiān)控和報(bào)警系統(tǒng),再輔以調(diào)用鏈追蹤系統(tǒng)和日志處理系統(tǒng),發(fā)現(xiàn)和定位故障的時(shí)間就比較可控了,可以很快定位絕大部分故障的發(fā)生原因,為修復(fù)故障提供有力的保障。整個(gè)發(fā)現(xiàn)定位故障的層次如圖 10.12 所示。
?
?
圖 10.12
?
?
10.12???? 發(fā)布管理
?
?
最后我想說說發(fā)布管理。雖然它不屬于基礎(chǔ)設(shè)施,但是它太重要了,對(duì)服務(wù)的高可用影響很大?;A(chǔ)設(shè)施的工作都做到位了就萬事大吉了嗎?不,還差一口氣——還需要確保最后一公里萬無一失,那就是服務(wù)的發(fā)布管理。最后一公里主要從以下三點(diǎn)著手規(guī)劃。
?
容量規(guī)劃
通過測(cè)試報(bào)告評(píng)估應(yīng)用的類型是 I/O 密集型、CPU 密集型還是混合型,根據(jù)應(yīng)用的類型申請(qǐng)合理的硬件資源。單臺(tái)節(jié)點(diǎn)最大處理能力是多少?線上有多少容量正在被使用?集群的最大處理能力是多少?這些在發(fā)布前都需要合理地評(píng)估和測(cè)試。
冗余規(guī)劃
需要考慮異地多可用區(qū)部署,部署服務(wù)實(shí)例不小于 N+2,服務(wù)實(shí)例硬件配置相同,避免部署實(shí)例大小不一。為什么是 N+2 而不是 N+1 呢?這是為了防止在服務(wù)更新時(shí)掛掉一個(gè)服務(wù)節(jié)點(diǎn)(發(fā)布失敗是高概率事件)。
?
發(fā)布控制
在線下進(jìn)行充分測(cè)試,能在線下做的測(cè)試絕不放在線上做。就像上面所說的,發(fā)布失敗是高概率事件,所以發(fā)布必須要支持回滾,必須拒絕一切沒有回滾方案的更新。必須拒絕!
?
?
11.6???? 總結(jié)
?
?
在微服務(wù)架構(gòu)下可以按功能和職責(zé)充分分解服務(wù),解耦依賴,單個(gè)服務(wù)易于開發(fā)和維護(hù),解鎖了技術(shù)棧,實(shí)現(xiàn)了更短的開發(fā)迭代周期,促進(jìn)敏捷開發(fā)和持續(xù)部署。但我們也要充分認(rèn)識(shí)到微服務(wù)有著分布式架構(gòu)固有特點(diǎn)帶來的復(fù)雜性,大量服務(wù)之間的通信對(duì)應(yīng)用的集成測(cè)試、穩(wěn)定性、運(yùn)維和監(jiān)控提出了更高的要求,CAP 理論的約束對(duì)數(shù)據(jù)的一致性也帶來了更大的挑戰(zhàn)。微服務(wù)架構(gòu)對(duì)基礎(chǔ)設(shè)施的投入很大,簡單應(yīng)用采用單體架構(gòu)更經(jīng)濟(jì)有效,大型復(fù)雜應(yīng)用采用微服務(wù)架構(gòu)才能體現(xiàn)投入的價(jià)值。
特別推薦一個(gè)分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒關(guān)注的小伙伴,可以長按關(guān)注一下:
長按訂閱更多精彩▼
如有收獲,點(diǎn)個(gè)在看,誠摯感謝
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!