一文搞懂火遍大廠的ServiceMesh模式

微服務(wù)架構(gòu)的缺陷

網(wǎng)絡(luò)通信

分布式計算的8個謬論
Fallacies of Distributed Computing Explained:
網(wǎng)絡(luò)是可靠的
網(wǎng)絡(luò)延遲是0
帶寬是無限的
網(wǎng)絡(luò)是安全的
網(wǎng)絡(luò)拓?fù)鋸牟桓淖?/span>
只有一個管理員
傳輸成本是0
網(wǎng)絡(luò)是同構(gòu)的
為啥會有這些明顯不符合現(xiàn)實的悖論呢?因為我們開發(fā)人員就是這樣,很少考慮網(wǎng)絡(luò)問題,這都是我們開發(fā)時對網(wǎng)絡(luò)現(xiàn)狀的極度幻想!
管控服務(wù)間的通信

服務(wù)注冊、發(fā)現(xiàn)
路由,流量轉(zhuǎn)移
彈性能力(熔斷、超時、重試)
安全
可監(jiān)控

Service Mesh演進史

遠(yuǎn)古 - 控制邏輯和業(yè)務(wù)邏輯耦合

人們沒有形成對網(wǎng)絡(luò)控制邏輯的完整思路,導(dǎo)致總是在業(yè)務(wù)邏輯中添加一些網(wǎng)絡(luò)控制邏輯,導(dǎo)致邏輯耦合,代碼難以維護!

服務(wù)發(fā)現(xiàn)(Service discovery )是自動找到滿足給定查詢請求的服務(wù)實例的過程。例如名為Teams的服務(wù)需要查找將屬性環(huán)境設(shè)置為生產(chǎn)的名為Players的服務(wù)的實例。您將調(diào)用一些服務(wù)發(fā)現(xiàn)過程,該過程將返回合適的服務(wù)器列表。對于更多的整體架構(gòu),這是一個簡單的任務(wù),通常使用DNS,負(fù)載均衡器以及一些關(guān)于端口號的約定來實現(xiàn)(例如,所有服務(wù)將其HTTP服務(wù)器綁定到端口8080)。
在更加分散的環(huán)境中,任務(wù)開始變得越來越復(fù)雜,以前可以盲目地依靠其DNS查找來找到依賴關(guān)系的服務(wù)現(xiàn)在必須處理諸如客戶端負(fù)載平衡,多個不同環(huán)境(例如,登臺與生產(chǎn)) ),地理位置分散的服務(wù)器等。如果之前只需要一行代碼來解析主機名,那么現(xiàn)在您的服務(wù)就需要很多樣板代碼來處理更高版本所帶來的各種情況。
斷路器是Michael Nygard在他的書Release It中分類的一種模式。Martin Fowler對該模式的總結(jié):
斷路器的基本原理非常簡單。將受保護的方法調(diào)用包裝在斷路器對象,該對象將監(jiān)視故障。一旦故障達到閾值,斷路器將跳閘,并且所有對該斷路器的進一步調(diào)用都會返回錯誤,而根本不會進行受保護的調(diào)用。通常,如果斷路器跳閘,您還需要某種監(jiān)視器警報。
這些非常簡單的設(shè)備可為你的服務(wù)之間的交互增加更多的可靠性。但隨分布水平提高,它們往往會變得更加復(fù)雜。系統(tǒng)中出現(xiàn)問題的可能性隨著分布的增加而呈指數(shù)級增長,因此,即使諸如“斷路器跳閘時出現(xiàn)某種監(jiān)視器警報”之類的簡單事情也不一定變得簡單明了。一個組件中的一個故障會在許多客戶端和客戶端的客戶端之間造成一連串的影響,從而觸發(fā)數(shù)千個電路同時跳閘。過去僅需幾行代碼,現(xiàn)在又需要樣板代碼來處理僅在這個新世界中存在的情況。
實際上,上面列出的兩個示例很難正確實現(xiàn),以至于大型,復(fù)雜的庫(如Twitter的Finagle和Facebook的Proxygen)非常受歡迎,因為它避免在每個服務(wù)中重寫相同邏輯。
公共庫

公共庫把這些網(wǎng)絡(luò)管控的功能整合成一個個單獨的工具包,獨立部署,解決了耦合。
該模型被大多數(shù)開創(chuàng)了微服務(wù)架構(gòu)的組織所采用,例如Netflix,Twitter和SoundCloud。
好處
解耦
消除重復(fù)
但隨著系統(tǒng)中服務(wù)數(shù)量的增加,發(fā)現(xiàn)了此模型的
缺點
組織仍需要花費其工程團隊的時間來建立將庫與其他生態(tài)系統(tǒng)聯(lián)系起來的粘合劑。有時,這筆費用是明確的,因為工程師被分配到了專門負(fù)責(zé)構(gòu)建工具的團隊中,但是價格標(biāo)簽通常是不可見的,因為隨著您花費時間在產(chǎn)品上工作,價格標(biāo)簽會逐漸顯現(xiàn)出來
限制了可用于微服務(wù)的工具,運行時和語言。微服務(wù)庫通常是為特定平臺編寫的,無論是編程語言還是運行時(如JVM)。如果組織使用的平臺不是庫支持的平臺,則通常需要將代碼移植到新平臺本身。這浪費了寶貴的工程時間。工程師不必再致力于核心業(yè)務(wù)和產(chǎn)品,而必須再次構(gòu)建工具和基礎(chǔ)架構(gòu)。這就是為什么諸如SoundCloud和DigitalOcean之類的中型組織決定僅支持其內(nèi)部服務(wù)的一個平臺的原因,分別是Scala和Go
治理。庫模型可以抽象化解決微服務(wù)體系結(jié)構(gòu)需求所需的功能的實現(xiàn),但是它本身仍然是需要維護的組件。確保成千上萬的服務(wù)實例使用相同或至少兼容的庫版本并非易事,并且每次更新都意味著集成,測試和重新部署所有服務(wù)-即使該服務(wù)本身未遭受任何損害更改。
下一代架構(gòu)

與我們在網(wǎng)絡(luò)棧中看到的類似,非常需要將大規(guī)模分布式服務(wù)所需的功能提取到基礎(chǔ)平臺中。
人們使用HTTP等高級協(xié)議編寫應(yīng)用程序和服務(wù),而無需考慮TCP如何控制其網(wǎng)絡(luò)上的數(shù)據(jù)包。這種情況正是微服務(wù)所需要的,工程師可以專注業(yè)務(wù)邏輯,避免浪費時間編寫自己的服務(wù)基礎(chǔ)結(jié)構(gòu)代碼或管理整個團隊中的庫和框架。
不幸的是,更改網(wǎng)絡(luò)棧以添加此層并不可行。
許多從業(yè)人員發(fā)現(xiàn)的解決方案是將其作為一組代理來實現(xiàn)。即服務(wù)不會直接連接到其下游依賴,而是所有流量都將通過一小段軟件透明地添加所需的功能。
在該領(lǐng)域中最早記錄在案的發(fā)展使用了sidecar的概念。sidecar是在你的應(yīng)用旁邊運行并為其提供附加功能的輔助進程。2013年,Airbnb撰寫了有關(guān)Synapse和Nerve的開源文件,其中包括Sidecar的開源實現(xiàn)。一年后,Netflix推出了Prana,這是一種輔助工具,致力于允許非JVM應(yīng)用程序從其NetflixOSS生態(tài)系統(tǒng)中受益。
sidecar


其實這種模式很早就出現(xiàn)了,比如 k8s 的 pod部署多個容器,其一就是處理日志的filebeat,其本質(zhì)就是個 sidecar,只不過我們一般都是部署一個處理網(wǎng)絡(luò)請求的 sidecar。
至此,已經(jīng)很接近 service mesh 了。
盡管有許多此類開源代理實現(xiàn),但它們往往旨在與特定的基礎(chǔ)結(jié)構(gòu)組件一起使用。例如服務(wù)發(fā)現(xiàn),Airbnb的Nerve&Synapse假定服務(wù)已在Zookeeper中注冊,而對于Prana,則應(yīng)使用Netflix自己的Eureka服務(wù)注冊表。
隨著微服務(wù)架構(gòu)的日益普及,我們最近看到了新一輪的代理浪潮,這些代理足夠靈活以適應(yīng)不同的基礎(chǔ)架構(gòu)組件和偏好。這個領(lǐng)域的第一個廣為人知的系統(tǒng)是Linkerd,它是由Buoyant根據(jù)工程師在Twitter微服務(wù)平臺上的先前工作創(chuàng)建的。很快,Lyft的工程團隊發(fā)布了Envoy,它遵循類似的原則。
戰(zhàn)至終章 - Service Mesh

在這種模型中,你的每個服務(wù)都將有一個伴隨代理服務(wù)。鑒于服務(wù)僅通過Sidecar代理相互通信,因此我們最終得到了類似于下圖的部署,可以說就是 sidecar 的網(wǎng)絡(luò)拓?fù)浣M合。

Buoyant的首席執(zhí)行官威廉·摩根(William Morgan)指出,代理之間的互連形成了網(wǎng)狀網(wǎng)絡(luò)(mesh network)。
2017年初,William為該平臺編寫了一個定義,并將其稱為Service Mesh:
服務(wù)網(wǎng)格是用于處理服務(wù)到服務(wù)通信的專用基礎(chǔ)結(jié)構(gòu)層。它負(fù)責(zé)通過構(gòu)成現(xiàn)代云原生應(yīng)用程序的復(fù)雜服務(wù)拓?fù)淇煽康貍鬟f請求。實際上,服務(wù)網(wǎng)格通常被實現(xiàn)為輕量級網(wǎng)絡(luò)代理的陣列,這些輕量級網(wǎng)絡(luò)代理與應(yīng)用程序代碼一起部署,而無需了解應(yīng)用程序。
他的定義中最有力的方面可能是,它擺脫了將代理視為獨立組件的想法,并認(rèn)識到它們形成的網(wǎng)絡(luò)本身就是有價值的東西。
你以為結(jié)束了?其實才剛開始-Service Mesh V2

隨著組織將其微服務(wù)部署移至更復(fù)雜的運行時(如Kubernetes和Mesos),人們已開始使用這些平臺提供的工具來正確實現(xiàn)網(wǎng)狀網(wǎng)絡(luò)的想法。他們正從一組獨立工作的獨立代理轉(zhuǎn)移到一個適當(dāng)?shù)模悬c集中的控制平面。
縱觀我們的鳥瞰圖,我們看到實際的服務(wù)流量仍然直接從代理流向代理,但是控制平面知道每個代理實例。控制平面使代理可以實現(xiàn)訪問控制和指標(biāo)收集之類的事情,這需要合作:

最近開源的Istio項目是此類系統(tǒng)的最突出示例。

總結(jié)


全面理解ServiceMesh在大規(guī)模系統(tǒng)中的影響還為時過早。總之這種方法有兩個好處
不必編寫定制軟件來處理微服務(wù)體系結(jié)構(gòu)的最終商品代碼,這將使許多小型組織可以享受以前僅大型企業(yè)才能使用的功能,從而創(chuàng)建各種有趣的用例
這種體系結(jié)構(gòu)可能使我們最終實現(xiàn)使用最佳工具/語言完成工作的夢想,而不必?fù)?dān)心每個平臺的庫和模式的可用性
參考
https://philcalcado.com/2017/08/03/pattern_service_mesh.html
https://medium.com/airbnb-engineering/smartstack-service-discovery-in-the-cloud-4b8a080de619
https://netflixtechblog.com/prana-a-sidecar-for-your-netflix-paas-based-applications-and-services-258a5790a015
https://buoyant.io/2020/10/12/what-is-a-service-mesh/
