云原生时代微服务的高可用架构设计
簡介:?在8月20日“阿里巴巴技術質量精品課”上,來自螞蟻的經國分享了對云原生時代微服務的高可用架構設計的全面解析,為大家介紹了應用架構演進路徑、云原生時代的技術福利、高可用架構的設計原則以及經典案例的設計。
演講嘉賓簡介:
經國,螞蟻金服資深技術專家,畢業于浙江大學。2014年加入螞蟻金服,先后負責過支付寶的單元化、彈性、去ORACLE等架構升級,擔任多年支付寶雙十一、雙十二、新春紅包大型活動等技術保障負責人,現為螞蟻金服數字金融線擔任技術風險架構師,負責高可用架構、技術風險平臺、應急快反等技術底盤的建設。
**以下內容根據演講視頻以及PPT整理而成。
本次分享主要圍繞以下五個方面:
? 應用架構演進路徑
? 云原生時代的技術福利
? 高可用架構的設計原則
? 經典案例的設計
? 未來思考**
微服務是當下非常熱門的一種架構,阿里目前正在從SOA架構體系向微服務架構遷移。同時整個軟件應用研發開始進入云原生時代。在這些技術演進背景下討論如何更好地實現穩定且高可用的架構方案,保證應用持續可用非常有必要。
一、應用架構演進路徑
支付寶最開始是一個單體應用。隨著業務不斷發展,支付寶拆分成了多個服務,衍生出了若干代架構。微服務是服務化后的進一步演進,服務的粒度比服務化更細,具有很好的流量管控機制,中間件和編程模型。云原生的發展使Serverless也得到了發展,FAAS是Serverless的一種典型實現,能夠以非常小的成本搭建小程序。另外,低代碼和無代碼現在也非常流行。
基礎設施同樣也得到了很好的發展。最開始,單體架構是托管式的,通常將應用程序托管給電信運營商的某個機房,在物理機上運行單體應用。后來,基礎設施開始向虛擬化演進,比如VMware等公司在物理機上構建虛擬化層和虛擬機,在虛擬機上運行操作系統。再后來,云化結合虛擬化技術和基礎設施,在虛擬機上運行Docker進程,在Docker進程中運行應用程序。現在,根據云通未來的理念,包括螞蟻在內的很多公司都在實現上云。螞蟻的基礎設施已經完全實現了云化,包括公有云和私有云。從架構角度來看,螞蟻的基礎設施就是在云底座上運行一層K8S,在Pod里運行APP,其上層對應著FAAS、網格化、Service mesh、微服務等應用程序。
作為一個復雜的業務應用,如何實現技術支撐對螞蟻非常關鍵。螞蟻目前正在嘗試許多FAAS相關的技術選型,但從更大的范圍來看,微服務仍然是主流的選擇。螞蟻所使用的微服務架構本身也在不斷演進,比如把和業務無關的功能下沉到Sidecar,將數據庫的一些中間件mesh化等。盡管從應用研發的角度看,螞蟻所使用的架構風格相比于原來發生了很大的變化,但從整體趨勢來看,最主要的變化仍在于將和業務能力無關并且和基礎設施相關的能力下沉。
二、云原生時代的技術紅利
云原生已經演化成了一個非常龐大的生態。這張圖囊括了云原生里非常多的內容。從設計高可用且穩定性高的應用的角度來看,相關的內容包括數據庫技術、云原生存儲、Service mesh、可觀測性、Serverless等。
數據庫技術
應用開發不僅需要關注業務邏輯,還需要關注數據,將領域模型、業務流程、配置等數據以Online形式存儲。近幾年,數據庫技術發生了很大的變化,HBase等分布式數據庫提供的強一致保證給云原生應用的設計和開發帶來了許多好處。此前,應用設計需要考慮讀寫分離,需要連接不同的數據源處理讀寫分離的結果,并且這些功能都需要寫入應用程序代碼。而現在,這些功能可以直接利用數據庫的水平擴展能力來實現,數據庫技術的發展極大地避免了我們直接和數據層交互。
云原生存儲
螞蟻的大部分業務已經實現云盤存儲,也就是將日志存儲到遠方磁盤。此前,單體應用通常將數據存儲于本機磁盤,并且不提供其它冗余備份;而云盤則默認提供數據冗余,這在基于日志不可靠假設進行應用設計時帶來了很多變化。
可觀測性
應用程序存在著許多監控操作。隨著Sidecar將很多能力下沉,包括訪問RPC和DB,此前以中間件形式實現的監控操作,現在則以切面形式來實現,二者有很大的區別。
云原生時代的技術紅利
云原生時代帶來的最大變化在于基礎設施和業務邏輯的真正解耦。此前,中間件邏輯存在于應用程序的進程中,而現在壓測、限流等都可以在Sidecar中實現,從而解耦了基礎設施和業務邏輯。然而,這種解耦是不斷進行著的,即使在未來也很難做到業務完全不需要關注基礎設施。比如,業務流量應該多大,DB節點應該設置多少個,業務流量和DB的設計是否符合要求。比如,同步的關鍵業務對應的流量鏈路和異步化任務可能運行在同一個節點中,那么如何實現二者流量隔離就是一個難題。再比如,如何結合基礎設施和業務要求進行部署,保證內存和CPU合理分配。在基礎設施對這些內容無感知的前提下,如何自動化地進行混布和限流。從應用研發的視角來看,此前需要寫很多代碼來實現業務邏輯和基礎設施交互;而現在相應的代碼量會減少很多。
三、高可用架構設計的設計原則
三個架構設計原則:可觀測、可灰度、可回滾
高可用設計主要有三個原則,包括可觀測、可灰度、可回滾。大部分云研發場景并不需要關注可演變,但在一些特殊場景下可演變仍然是一個問題。比如,螞蟻的金融業務需要和一些機構進行信息交換,由于金融領域的RPC交互常常使用標準化文件,在文件場景下如何保證可演變也是高可用設計需要關注的內容。典型的用于提高架構可用性的設計原則包括四種:解耦、冗余、異構和異步。
解耦
在數據庫方面,如何解耦核心和非核心業務的DB。在業務鏈路方面,由于微服務具有復雜的業務場景和節點,這些業務場景和節點間如何混合,業務節點如何支撐業務鏈路,容量不足時哪些業務場景應優先通過,限流時應優先限流哪些業務等也是解耦需要關注的內容。總體而言,解耦原則要求將最核心的業務鏈路隔離出來,使其與其它業務間的耦合盡可能小。
冗余
應用程序可能有多個機房,如果多個機房間存在數據冗余,那么一個位置的錯誤就能夠由另一個位置的數據來彌補,從而保證系統的持續可用。讀寫分離也是一種冗余設計,緩存和DB間存在數據冗余,當緩存宕機時,可以從DB回源到緩存。
異構
如果多個DB間是同構的,那么可能存在一些情況使得中心化的內容同時掛掉;但如果DB是異構的,比如使用的數據庫版本不同,那么這些數據庫同時掛掉的情況則非常少。
異步
異步要求將業務流程的核心部分抽象出來,使其不與非核心的內容耦合。從理論上看,核心部分越精煉,系統出錯誤的概率越小。比如,支付寶的支付業務背后有一百多個業務處理節點,在微服務時代,其背后可能有幾百個甚至上千個業務節點,假設每個節點的可用率都是5個9,把幾百個甚至幾千個節點的可用率乘起來就會使得整體的可用率非常小。但通過移除和核心業務無關的內容,從而減小節點數量后,系統的可用率就會大幅增高。上圖的左右兩邊從不同角度對微服務的高可用設計進行了分析。左邊是微服務設計應具有的能力,右邊是設計高可用微服務架構時應遵循的原則。另外,有三塊內容實際支撐著一個微服務系統:代碼、配置和數據。其中,代碼和配置是相輔相成的,代碼執行的間歇可能需要修改系統配置;業務數據也非常重要。對這三塊內容進行分析是微服務架構高可用設計的重要方面。比如,配置文件的可回滾和可灰度能力。與代碼相比,配置文件的可灰度能力不夠標準化,尤其是和業務或者運營相關的配置文件;數據也是如此,由于一些數據有多種來源,這些數據的可觀測和可演練能力比代碼差。從整體而言,代碼的相關體系比配置文件和數據更完備。
不過度設計
架構設計的另一個重要原則是不過度設計,高可用架構設計應基于業務需求進行。這是因為高可用設計通常極為復雜。比如,將鏈路中的一些重要業務解耦出來單獨部署,無論其業務流量多大,都為這些業務分配一百個節點,從而降低單節點宕機帶來的影響。從本質上來看,這些差異化配置通過付出成本和效率來換取高可用,這就存在著權衡難題。從目前來看,很少有軟件系統的高可用能力能夠實現5個9,大部分都還停留在理論上達到5個9的狀態。
四、經典案例的設計
接下來,以具體的業務場景為例分析典型業務的高可用設計。
手機掃碼場景
手機掃碼場景要求在手機斷網時正常顯示其二維碼。在這個場景里,真正的業務鏈路從POS鏈路開始,有的POS鏈路需要經過商戶的處理系統,有的則直接進入支付寶自身的業務系統。在支付寶端,該鏈路將從一個統一的網關接入,攜帶著訂單相關信息,比如商戶ID等。此后,鏈路進入一個收單系統,由該系統處理這些相關信息。再往后,鏈路開始進入交易系統,通過調用交易系統的核心模塊完成該業務支付。此外,為了實現掃碼,POS系統還需要和支付寶簽約以建立授權關系,并且同步商戶信息。這個微服務系統所涵蓋的高可用需求包括:
其一,該系統主要面向線下場景,商家在未獲取現金時不會將商品交給用戶。因此,不可用問題對商家的影響很大,比如用戶不能正常支付。
其二,該系統的一些節點還需要支撐整個支付寶的業務體系,比如會員信息節點,它需要支持成百上千個與螞蟻森林相同體量的業務功能,對可用性的要求非常高。
這意味著,在這個微服務系統中,不同業務對可用性的要求不同,因此需要不同的手段實現該系統的可用性需求。
灰度設計
首先,簽約業務是異步的,在設計時不應被納入系統的核心鏈路。另外,簽約服務需要與網關和商戶服務進行信息同步,仍可能導致網關和商戶服務宕機,比如修改商戶的鑒權信息可能使簽約不成功。因此,簽約服務需要實現灰度設計。
異構設計
其次,如果將一個非常重要的業務從鏈路中隔離出來,那么為了處理隔離后的節點的宕機事件,就需要一個異構設計使得當其宕機時整個系統還能繼續運轉,包括數據存儲方面和計算能力方面的異構。值得一提的是,現在的分布式數據庫能夠實現RPO等于0,使得當數據出問題時不發生數據丟失,其基本原理就是存儲多個數據副本,并且當數據出現故障時,可以在多個副本間切換,數據恢復速度非常快。然而,這并不意味著高可用設計只需依賴數據庫,而不需要額外的容災能力。事實上,這與系統所要求的高可用級別相關。比如,假設系統所要求的高可用能力級別為5個9,那么即使數據庫僅發生一次宕機并且數據恢復失敗,那么就無法實現所要求的5個9的高可用能力。高可用設計的一個原則是,核心業務的設計不應信任其所依賴的基礎設施。這樣,為了提高系統高可用能力,就需要實現應用層容災。應用層的容災可能會FO到一個數據庫中,數據庫版本不同,數據存儲類型不同,那么二者同時出現故障的概率就會變得更低。因此,應用層的容災非常重要。
防熱點、讀寫分離
在service mesh場景下,應用層不再需要關注防熱點、讀寫分離等。幾年前,應用層還需要對緩存熱點做特殊處理以建設高可用能力,比如在一個緩存節點掛掉時對其進行預熱操作。而現在,大多數分布式架構本身就提供了緩存熱點能力。此外,大多數分布式數據庫本身就使用了讀寫分離架構,只需稍加配置就可以將數據路由到只讀節點。這些都是云原生時代帶來的紅利之一。
近端
近端在不同場合下可能有不同的名稱。比如,如果將會員信息的全部請求都發給應用層,那么其所需要的集群數量將會非常龐大。由于會員信息的查詢遵循了較為固定的范式,因此可以將會員信息的查詢功能前置到收單服務,從而使收單服務不需要訪問會員信息,而可以直接訪問會員信息所依賴的服務。這本質上也是通過應用層設計來減小高可用的成本。
總的來說,對于一個給定的業務場景,高可用設計需要分析它的業務特點,可用性的要求,從而設計對應高可用設計的節點。比如,如何設計以查詢功能為主的節點,特別是當其所依賴的數據庫不被信任時。在微服務架構中進行高可用設計時,應該針對每個節點的特征進行有針對的設計。另外,即使在云原生場景下,也需要通過應用層設計實現防抖、業務隔離、配置灰度設計和應用層容災。比如,使用FASS能夠很容易地實現系統功能,但當系統的可用性要求、業務體量增大時,任何一個抖動都可能影響到整個軟件系統的可用能力。高可用設計并不存在標準配置。實際上,高可用設計需要根據業務重要性、能力和效率的分層等進行分層次的設計,最核心業務需要通過一些高復雜度的設計來提高它們的可用性。
業務隔離
線下業務和淘寶業務實際上使用同一個版本進行應用開發和發布,它們的隔離僅僅體現在流量和部署層面。比如,它們所使用的交易服務在開發層面就是完全相同的,僅僅在部署層面將它們的流量分離到不同的服務中。這樣,在以業務維度做跨節點的流量綁定時,就需要將幾個服務及其節點圈出來進行分流。
首先,需要識別某流量是否與該業務相關;其次,需要將該流量接入到某個特定區域中;然后,該區域還需要將所有與完成該業務相關的節點都包含進來。這種設計需要一定的先驗知識,因此需要定義一些元信息,比如流量入口。在確定流量入口后所有和其相關的后續處理節點都應被打標或者以其它方式圈定起來。門面系統后對應著內部系統,包括一系列Http組。在定義好這些后,某個組件會在流量接入后識別門面系統,進而找到該門面系統對應的圈定區域,也就是內部系統,從而完成一個整體上的流量綁定過程。
值得一提的是,這并不是微服務體系下流量綁定的標準配置,而是阿里的應用開發人員和中間件人員提出的業務隔離設計。隨著上云等措施,這種設計逐漸內置到基礎設施中,成為一個典型的業務隔離設計。
防抖設計
圖中的業務場景對應著買家向賣家支付。由于實際支付時,支付操作后置一段時間并不會引發大問題,因此大部分系統在實際運行時,買家向賣家支付的錢都不會即時到賬,而需要經過一段時間的累積后再批量到賬。本質上,這是一種信息流和業務流的解耦。從業務角度看,錢需要即時從買家流動到賣家,中間還可能有聚合支付等操作。而在實際運行時,系統無需關注具體的支付細節,而只需要通知買家支付成功,通知賣家錢已到賬。在不同處理模式下,資金流和信息流的處理流程可能有很大的不同。
防抖設計架構抽象
在具體設計時,一個邏輯支付處理單元實際上被拆分成信息處理單元和資金處理單元。中間的T+x表示,信息處理單元和資金處理單元間可以存在一個較大的時間差。在信息受理時,即使不需要進行實際的資金流處理,也需要明確買家和賣家信息,而這些信息來自會員系統和商家系統。那么,當會員系統宕機時,為了使防抖設計機制可用,就需要異構的設計。實際資金流處理所依賴的數據需要異構出一份以供信息流處理,而不是直接用原來的數據。異構設計使得一份數據宕機不影響整個系統功能的正常運行。除了數據需要進行異構處理外,一些計算規則也需要遷移到信息流處理中,比如商家的店鋪信息處理等。數據和計算規則的異構使我們能夠實現解耦,這種設計對應著一個標準化的范式。幾乎在所有的業務場景都能看到這種設計。
總的來說,將業務最頂端跟信息流相關的邏輯抽象出來,并且將這部分邏輯所依賴的數據異構一部分出來,這就能夠使所有的業務實現不依賴于實際的處理邏輯,從而保證底層的任意一個節點發生宕機時整個系統的可用性。
防抖設計架構延展
理論上,這種架構設計是可以擴展的。信息流處理和業務流處理被解耦后就可以被部署在不同的節點中。比如,在國際支付時可以將信息流處理邏輯部署在支付方所在的區域中,這就使得支付操作不需要依賴原來的處理邏輯所部署的機房。需要注意的是,在將數據部署在其它機房時,通常需要一些額外的處理,比如信息安全等內容。
配置灰度設計
某節點的配置數據發生變更可能影響其它與之相關的節點,因此這就需要對這些節點做灰度設計,帶來了一個鏈路級的配置灰度設計問題。
分布式事務中通常有一個發起者和多個參與者。發起者發起一個預提交,在所有參與者確認后,該任務才被執行。這對應著一個二階段確認過程,即先發起、再確認、后執行。配置灰度設計和分布式事務處理非常類似。首先,簽約節點發起一個灰度設計,此后和簽約節點相關的節點需要參與進來,一同完成灰度。假設灰度的內容是某倉庫信息,此時所有參與節點都需要對本節點下的相關數據進行灰度。在實際進行灰度時,每個節點實現灰度的方式可能不同。比如,商家需要修改DB數據,而會員節點除了需要修改DB數據外,還需要修改對應節點中的緩存。需要注意的是,無論每個節點如何進行具體的灰度操作,各個節點間需要實現灰度的同進同退。
值得注意的是,這是一個最復雜的配置灰度設計,實際上的灰度設計比這個場景要簡單地多。
容災設計
狀態型數據和流水型數據
螞蟻通常按照特性將數據分為狀態型數據和流水型數據。所謂流水型數據,即每出現一條數據都將其存入數據庫中。比如,訂單數據就是一種流水型數據,每出現一條新訂單都被存入數據庫。流水型數據的大部分業務類型是將數據插入到數據庫。另一種數據是狀態型數據,通常可以被修改,并且具有生命周期特征,比如會員信息。
狀態型數據的容災設計
這兩種數據在進行應用層容災設計時需要不同的處理方式,狀態型數據的容災設計通常比較困難。比如,會員信息在出現錯誤時通常不能再寫該數據,也不能讓該用戶重新注冊一次支付寶。狀態型數據的容災設計需要以數據庫不可靠為前提。數據庫通常存在主備庫,這兩個庫通常使用異步復制的方式來保證兩個庫之間的同步。然而,這種同步通常具有時延特征。當主庫宕機時,如果FO庫的版本比較舊,就不能直接將FO庫作為主庫,因為原來的主庫上已經有用戶修改的內容。如果此時將FO庫作為主庫繼續進行修改,那么最終得到的數據必然不是用戶所預期的。一個處理方式是將持續往黑名單庫里寫差異。當主庫宕機時,首先將FO庫拉起來,此時,這些差異可能使得FO庫中某一部分數據是禁寫的。對用戶信息這樣的業務而言,每天只有很少的數據會發生更改,并且用戶信息發生宕機的概率很低,因此這種處理帶來的禁寫對業務的影響非常小。通過這種方式強一致地寫黑名單庫,能夠近似地實現無損的容災設計。回切數據庫時也是如此。由于FO庫已經有很多新的數據內容,因此在回切數據庫時需要將這部分數據merge回主庫中。
即使在云原生時代,一個業務場景的高可用架構設計也仍然需要許多操作來共同實現。未來,這些與業務無關的設計可能被組件化地沉淀下來,成為基礎設施。
五、未來思考
根據業務場景實現個性化高可用設計
高可用設計通常是靜態的,它能夠被內嵌到架構設計中,被內嵌到基礎設施或者中間件中。高可用設計應根據業務場景實現個性化設計。這要求我們不僅需要關注系統當下的業務特點,還需要預測其未來的業務特點,通過各種特性來刻畫該業務對用戶的可用性影響。這就需要結合各種原子手段以實現業務在當前階段所需要的高可用能力。未來,可能存在非常智能的系統,能夠使用最低成本刻畫業務的當前特征,然后自動化地組合一些原子高可用能力最大化系統高可用能力。
5個9的高可用設計
未來還可能實現5個9的高可用。首先,假設存在一個和螞蟻非常類似但又異構的環境,它們之間完全是去中心化的;其次,這兩個環境下的數據規則同步應該是可舍棄的,能夠實現FO以及全自動的切換;另外,還需要實現監控,監控也應該是異構的,需要有一個外部系統來觀測本系統的行為。
?
原文鏈接
本文為阿里云原創內容,未經允許不得轉載。
總結
以上是生活随笔為你收集整理的云原生时代微服务的高可用架构设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一篇小文带你走进RabbitMQ的世界
- 下一篇: 每次都需要解释大量指令?使用 Polar