- 鳳凰架構(gòu):構(gòu)建可靠的大型分布式系統(tǒng)
- 周志明
- 3024字
- 2021-06-24 11:30:50
1.5 后微服務(wù)時代
上節(jié)提到的分布式架構(gòu)中出現(xiàn)的問題,如注冊發(fā)現(xiàn)、跟蹤治理、負(fù)載均衡、傳輸通信等,其實在SOA時代甚至從原始分布式時代起就已經(jīng)存在了,只要是分布式架構(gòu)的系統(tǒng),就無法完全避免,但我們不妨換個思路來想一下,這些問題一定要由軟件系統(tǒng)自己來解決嗎?
如果不局限于采用軟件的方式,這些問題幾乎都有對應(yīng)的硬件解決方案。譬如,某個系統(tǒng)需要伸縮擴(kuò)容,通常會購買新的服務(wù)器,部署若干副本實例來分擔(dān)壓力;如果某個系統(tǒng)需要解決負(fù)載均衡問題,通常會布置負(fù)載均衡器,選擇恰當(dāng)?shù)木馑惴▉矸至鳎蝗绻枰鉀Q傳輸安全問題,通常會布置TLS傳輸鏈路,配置好CA證書以保證通信不被竊聽篡改;如果需要解決服務(wù)發(fā)現(xiàn)問題,通常會設(shè)置DNS服務(wù)器,讓服務(wù)訪問依賴穩(wěn)定的記錄名而不是易變的IP地址,等等。隨著計算機(jī)科學(xué)多年的發(fā)展,這些問題大多有了專職化的基礎(chǔ)設(shè)施去解決,而在微服務(wù)時代,人們之所以選擇在軟件的代碼層面而不是硬件的基礎(chǔ)設(shè)施層面去解決這些分布式問題,很大程度上是因為由硬件構(gòu)成的基礎(chǔ)設(shè)施跟不上由軟件構(gòu)成的應(yīng)用服務(wù)的靈活性的無奈之舉。軟件可以只使用鍵盤命令就拆分出不同的服務(wù),只通過拷貝、啟動就能夠?qū)崿F(xiàn)伸縮擴(kuò)容服務(wù),硬件難道就不可以通過鍵盤命令變出相應(yīng)的應(yīng)用服務(wù)器、負(fù)載均衡器、DNS服務(wù)器、網(wǎng)絡(luò)鏈路這些設(shè)施嗎?
至此,估計大家已經(jīng)聽出下面要說的是虛擬化技術(shù)和容器化技術(shù)了。微服務(wù)時代所取得的成就,本身就離不開以Docker為代表的早期容器化技術(shù)的巨大貢獻(xiàn)。在此之前,筆者從來沒有提過“容器”二字,這并不是刻意冷落,而是早期的容器只被簡單地視為一種可快速啟動的服務(wù)運行環(huán)境,目的是方便程序的分發(fā)部署,在這個階段,針對單個應(yīng)用進(jìn)行封裝的容器并未真正解決分布式架構(gòu)問題。盡管2014年微服務(wù)開始崛起的時候,Docker Swarm(2013年)和Apache Mesos(2012年)就已經(jīng)存在,更早之前也出現(xiàn)了軟件定義網(wǎng)絡(luò)(Software-Defined Networking,SDN)、軟件定義存儲(Software-Defined Storage,SDS)等技術(shù),但是,被業(yè)界廣泛認(rèn)可、普遍采用的通過虛擬化基礎(chǔ)設(shè)施去解決分布式架構(gòu)問題的開端,應(yīng)該要從2017年Kubernetes取得容器戰(zhàn)爭的勝利開始算起。
2017年是容器生態(tài)發(fā)展歷史中具有里程碑意義的一年。在這一年,長期作為Docker競爭對手的RKT容器一派的領(lǐng)導(dǎo)者CoreOS宣布放棄自己的容器管理系統(tǒng)Fleet,并將會在未來把所有容器管理的功能移至Kubernetes之上去實現(xiàn)。在這一年,容器管理領(lǐng)域的獨角獸Rancher Labs宣布放棄其內(nèi)置了數(shù)年的容器管理系統(tǒng)Cattle,提出“All-in-Kubernetes”戰(zhàn)略,把1.x版本就能夠支持多種容器編排系統(tǒng)的管理工具Rancher,從2.0版本開始“反向升級”為完全綁定于Kubernetes這一系統(tǒng)。在這一年,Kubernetes的主要競爭者Apache Mesos在9月正式宣布了“Kubernetes on Mesos”集成計劃,由競爭關(guān)系轉(zhuǎn)為對Kubernetes提供支持,使其能夠與Mesos的其他一級框架(如HDFS、Spark和Chronos等)進(jìn)行集群資源動態(tài)共享、分配與隔離。在這一年,Kubernetes的最大競爭者Docker Swarm的母公司Docker,終于在10月被迫宣布Docker要同時支持Swarm與Kubernetes兩套容器管理系統(tǒng),也即在事實上承認(rèn)了Kubernetes的統(tǒng)治地位。這場已經(jīng)持續(xù)了三年時間,以Docker Swarm、Apache Mesos與Kubernetes為主要競爭者的“容器編排戰(zhàn)爭”終于有了明確的結(jié)果。Kubernetes登基加冕是容器發(fā)展中一個時代的終章,也將是軟件架構(gòu)發(fā)展下一個紀(jì)元的開端。筆者在表1-1中列出了針對同一個分布式服務(wù)問題,Kubernetes中提供的基礎(chǔ)設(shè)施層面的解決方案與傳統(tǒng)Spring Cloud中提供的應(yīng)用層面的解決方案的對比,盡管因為各自出發(fā)點不同,解決問題的方法和效果都有所差異,但這無疑是提供了一條全新的、前途更加廣闊的解題思路。
表1-1 Kubernetes與傳統(tǒng)Spring Cloud提供的解決方案對比

“前途廣闊”不僅僅是一句恭維贊賞的客氣話,當(dāng)虛擬化的基礎(chǔ)設(shè)施從單個服務(wù)的容器擴(kuò)展至由多個容器構(gòu)成的服務(wù)集群、通信網(wǎng)絡(luò)和存儲設(shè)施時,軟件與硬件的界限便已模糊。一旦虛擬化的硬件能夠跟上軟件的靈活性,那些與業(yè)務(wù)無關(guān)的技術(shù)性問題便有可能從軟件層面剝離,悄無聲息地在硬件基礎(chǔ)設(shè)施之內(nèi)解決,讓軟件得以只專注業(yè)務(wù),真正圍繞業(yè)務(wù)能力構(gòu)建團(tuán)隊與產(chǎn)品。如此,DCE中未能實現(xiàn)的“透明的分布式應(yīng)用”成為可能,Martin Flower設(shè)想的“鳳凰服務(wù)器[1]”成為可能,Chad Fowler提出的“不可變基礎(chǔ)設(shè)施[2]”也成為可能。從軟件層面獨立應(yīng)對分布式架構(gòu)所帶來的各種問題,發(fā)展到應(yīng)用代碼與基礎(chǔ)設(shè)施軟、硬一體,合力應(yīng)對架構(gòu)問題,這個新的時代現(xiàn)在常被媒體冠以“云原生”這個頗為抽象的名字加以宣傳。云原生時代追求的目標(biāo)與此前微服務(wù)時代追求的目標(biāo)并沒有本質(zhì)改變,都是在服務(wù)架構(gòu)演進(jìn)的歷史進(jìn)程中,所以筆者更愿意稱云原生時代為“后微服務(wù)時代”。
Kubernetes成為容器戰(zhàn)爭勝利者標(biāo)志著后微服務(wù)時代的開啟,但Kubernetes仍然沒能完美解決全部的分布式問題——“不完美”的意思是,僅從功能上看,單純的Kubernetes反而不如之前的Spring Cloud方案。這是因為有一些問題處于應(yīng)用系統(tǒng)與基礎(chǔ)設(shè)施的邊緣,使得很難完全在基礎(chǔ)設(shè)施層面中精細(xì)化地處理。舉個例子,如圖1-4所示,微服務(wù)A調(diào)用了微服務(wù)B的兩個服務(wù),稱為B1和B2,假設(shè)B1表現(xiàn)正常但B2出現(xiàn)了持續(xù)的500錯,那在達(dá)到一定閾值之后就應(yīng)該對B2進(jìn)行熔斷,以避免產(chǎn)生雪崩效應(yīng)。如果僅在基礎(chǔ)設(shè)施層面來處理,這會遇到一個兩難問題,切斷A到B的網(wǎng)絡(luò)通路會影響B(tài)1的正常調(diào)用,不切斷則會持續(xù)受B2的錯誤影響。

圖1-4 是否要熔斷對服務(wù)B的訪問
以上問題在通過Spring Cloud這類應(yīng)用代碼實現(xiàn)的微服務(wù)中并不難處理,既然是使用程序代碼來解決問題,只要合乎邏輯,想要實現(xiàn)什么功能,只受限于開發(fā)人員的想象力與技術(shù)能力,但基礎(chǔ)設(shè)施是針對整個容器來管理的,粒度相對粗獷,只能到容器層面,對單個遠(yuǎn)程服務(wù)則很難有效管控。類似的,在服務(wù)的監(jiān)控、認(rèn)證、授權(quán)、安全、負(fù)載均衡等方面都有可能面臨細(xì)化管理的需求,譬如服務(wù)調(diào)用時的負(fù)載均衡,往往需要根據(jù)流量特征,調(diào)整負(fù)載均衡的層次、算法等,而DNS雖然能實現(xiàn)一定程度的負(fù)載均衡,但通常并不能滿足這些額外的需求。
為了解決這一類問題,虛擬化的基礎(chǔ)設(shè)施很快完成了第二次進(jìn)化,引入了今天被稱為“服務(wù)網(wǎng)格”(Service Mesh)的“邊車代理模式”(Sidecar Proxy),如圖1-5所示。所謂“邊車”是一種帶垮斗的三輪摩托車,筆者小時候還算常見,現(xiàn)在基本就只在影視劇中才會看到了。在虛擬化場景中的邊車指的是由系統(tǒng)自動在服務(wù)容器(通常是指Kubernetes的Pod)中注入一個通信代理服務(wù)器,相當(dāng)于那個挎斗,以類似網(wǎng)絡(luò)安全里中間人攻擊的方式進(jìn)行流量劫持,在應(yīng)用毫無感知的情況下,悄然接管應(yīng)用所有對外通信。這個代理除了實現(xiàn)正常的服務(wù)間通信外(稱為數(shù)據(jù)平面通信),還接收來自控制器的指令(稱為控制平面通信),根據(jù)控制平面中的配置,對數(shù)據(jù)平面通信的內(nèi)容進(jìn)行分析處理,以實現(xiàn)熔斷、認(rèn)證、度量、監(jiān)控、負(fù)載均衡等各種附加功能。通過邊車代理模式,便實現(xiàn)了既不需要在應(yīng)用層面加入額外的處理代碼,也提供了幾乎不亞于程序代碼的精細(xì)管理能力。
我們很難從概念上判定清楚一個與應(yīng)用系統(tǒng)運行于同一資源容器之內(nèi)的代理服務(wù)到底應(yīng)該算軟件還是基礎(chǔ)設(shè)施,但它對應(yīng)用是透明的,不需要改動任何軟件代碼就可以實現(xiàn)服務(wù)治理,這便足夠了。服務(wù)網(wǎng)格在2018年才火起來,今天它仍然是個新潮的概念,未完全成熟,甚至連Kubernetes也還算是個新生事物。但筆者相信,未來Kubernetes將會成為服務(wù)器端的標(biāo)準(zhǔn)運行環(huán)境,如同現(xiàn)在的Linux系統(tǒng);服務(wù)網(wǎng)格也將會成為微服務(wù)之間通信交互的主流模式,把“選擇什么通信協(xié)議”“怎樣調(diào)度流量”“如何認(rèn)證授權(quán)”之類的技術(shù)問題隔離于程序代碼之外,取代今天Spring Cloud全家桶中大部分組件的功能。微服務(wù)只需要考慮業(yè)務(wù)本身的邏輯,這才是最理想的智能終端解決方案。

圖1-5 邊車代理流量示意[3]
業(yè)務(wù)與技術(shù)完全分離,遠(yuǎn)程與本地完全透明,也許這就是最好的時代了吧?
[1] 鳳凰服務(wù)器:https://martinfowler.com/bliki/PhoenixServer.html。
[2] 不可變基礎(chǔ)設(shè)施:http://chadfowler.com/2013/06/23/immutable-deployments.html。
[3] 圖來自Istio的配置文檔,圖中的Mixer在Istio 1.5之后已經(jīng)取消,這里僅作示意。
- 全屋互聯(lián):智能家居系統(tǒng)開發(fā)指南
- 操作系統(tǒng)實用教程(Linux版)
- Linux設(shè)備驅(qū)動開發(fā)詳解(第2版)
- Linux網(wǎng)絡(luò)管理與配置(第2版)
- 高性能Linux服務(wù)器構(gòu)建實戰(zhàn):運維監(jiān)控、性能調(diào)優(yōu)與集群應(yīng)用
- 深入Linux內(nèi)核架構(gòu)與底層原理(第2版)
- 數(shù)據(jù)中心系統(tǒng)工程及應(yīng)用
- Linux內(nèi)核觀測技術(shù)BPF
- Delphi Programming Projects
- 從實踐中學(xué)習(xí)Kali Linux無線網(wǎng)絡(luò)滲透測試
- NetDevOps入門與實踐
- Raspberry Pi入門指南
- Linux內(nèi)核分析及應(yīng)用
- Mastering Sass
- 15分鐘!畫出我的漫畫角色:賣萌篇