服務(wù)網(wǎng)格
微服務(wù)的自然演進(jìn)
引言
服務(wù)網(wǎng)格是當(dāng)前最熱門(mén)的技術(shù)之一嗽冒,服務(wù)網(wǎng)格代表了從集中式架構(gòu)向分布式架構(gòu)過(guò)渡的下一個(gè)創(chuàng)新飛躍。盡管如此乘综,我們認(rèn)為服務(wù)網(wǎng)格的相關(guān)新技術(shù)可能是以新穎的方式包裝了現(xiàn)有技術(shù)桦踊。借助服務(wù)網(wǎng)格懊纳,我們將采用傳統(tǒng) API 網(wǎng)關(guān)的功能,并以全新的模式進(jìn)行部署舔庶。
隨著微服務(wù)白胀、容器化和 serverless 的發(fā)展,我們可能都已經(jīng)非常熟悉了從大型整體服務(wù)谈秫,到更小的扒寄、更敏捷的服務(wù)的轉(zhuǎn)變。盡管如此拟烫,對(duì)于我們大多數(shù)人而言该编,要準(zhǔn)確地了解什么是服務(wù)網(wǎng)格,以及它如此令人興奮的原因硕淑,可能是一個(gè)挑戰(zhàn)课竣。在適當(dāng)?shù)纳舷挛闹欣斫夥?wù)網(wǎng)格需要了解從單體應(yīng)用到微服務(wù)的演變。
從單體應(yīng)用到現(xiàn)代架構(gòu)
為了解決這個(gè)問(wèn)題置媳,我們中許多人開(kāi)始解耦單體應(yīng)用于樟,轉(zhuǎn)而使用以 API 為中心的企業(yè)架構(gòu),公共和私有服務(wù)的粒度也變的越來(lái)越小拇囊。容器的興起使我們可以將服務(wù)抽象到距離虛擬機(jī)更高一層的位置迂曲,這更加加速了這種趨勢(shì),服務(wù)的粒度變的更小寥袭。最終的結(jié)果是我們將單體應(yīng)用解耦為可獨(dú)立運(yùn)行的小組件路捧。
隨著 Docker 和 Kubernetes 等工具的日益普及,我們看到容器化的進(jìn)程越來(lái)越快纠永。
這些工具使分離服務(wù)變的更加容易鬓长,有了它們,我們可以分離服務(wù)的運(yùn)行尝江,并將它們隔離開(kāi)涉波。本質(zhì)上,Docker 和 Kubernetes 提供了足夠的工具支持主流實(shí)現(xiàn),盡管像 Netflix 和 Amazon 這樣的公司在沒(méi)有這些工具的情況下進(jìn)行了轉(zhuǎn)型啤覆,它們解耦單體應(yīng)用的過(guò)程更具挑戰(zhàn)苍日。
從南北向到東西向
在老的單體應(yīng)用架構(gòu)中,我們幾乎只處理南北流量窗声,但是對(duì)于微服務(wù)相恃,我們必須越來(lái)越多地處理數(shù)據(jù)中心內(nèi)部的流量。對(duì)于單體應(yīng)用來(lái)說(shuō)笨觅,不同的組件之間通過(guò)調(diào)用應(yīng)用內(nèi)部的方法來(lái)通信拦耐。邊緣網(wǎng)關(guān)(Edge gateways)抽象了常見(jiàn)的流量協(xié)調(diào)功能,例如身份驗(yàn)證见剩,日志記錄和限流杀糯,但是在單體應(yīng)用范圍內(nèi)進(jìn)行的通信不需要這些活動(dòng)。
由于現(xiàn)在的方法調(diào)用通過(guò)網(wǎng)絡(luò)通信完成苍苞,東西向流量帶來(lái)了更大的挑戰(zhàn)固翰。我們可以使用所需的任何傳輸方法進(jìn)行通信,架構(gòu)內(nèi)的不同服務(wù)彼此間不必了解羹呵,服務(wù)間充滿了很大的靈活性骂际。這提供了很大的優(yōu)勢(shì),例如冈欢,我們是一個(gè)大型組織歉铝,假設(shè)收購(gòu)了另一個(gè)團(tuán)隊(duì),我們就不必?fù)?dān)心他們使用的編程語(yǔ)言和他們的工作方式涛癌。但是犯戏,由于網(wǎng)絡(luò)具有延遲并且本質(zhì)上不可靠送火,因此拳话,網(wǎng)絡(luò)比方法調(diào)用會(huì)產(chǎn)生更多的問(wèn)題。
傳統(tǒng)網(wǎng)關(guān)的挑戰(zhàn)
隨著微服務(wù)產(chǎn)生的東西量流量逐次增加种吸,我們需要具備編排它的能力弃衍,這與我們解決單體應(yīng)用的邊際問(wèn)題類似,我們需要有效地路由流量坚俗,但是現(xiàn)在所有常用功能(如路由镜盯、身份驗(yàn)證和日志記錄)都是菊花鏈(daisy-chained)式的。這種復(fù)雜性導(dǎo)致傳統(tǒng)網(wǎng)關(guān)無(wú)法很好地處理東西向流量猖败,必須使用粒度更細(xì)速缆,更靈活的網(wǎng)關(guān)。
對(duì)于微服務(wù)而言恩闻,每個(gè)服務(wù)有多個(gè)實(shí)例艺糜,這導(dǎo)致我們必須在服務(wù)發(fā)現(xiàn)處理更大的復(fù)雜性。我們的服務(wù)需要知道在哪里發(fā)送請(qǐng)求,網(wǎng)絡(luò)是否可靠破停,如何處理過(guò)多的延遲翅楼,錯(cuò)誤處理以及其他問(wèn)題。我們需要確定我們可以有效地解決這些問(wèn)題真慢,因?yàn)殡S著服務(wù)數(shù)量增加毅臊,挑戰(zhàn)將變得更加復(fù)雜。
代理黑界、網(wǎng)關(guān)和服務(wù)網(wǎng)格的基礎(chǔ)
為了使我們的服務(wù)粒度越來(lái)越細(xì)管嬉,我們?cè)黾恿藢?duì)東西向流量的需求,從業(yè)人員開(kāi)始尋找解決方案朗鸠。最初宠蚂,我們?cè)S多人認(rèn)為可以為每個(gè)微服務(wù)使用相同的客戶端庫(kù),但是童社,這個(gè)方案很快就放棄了求厕,該解決方案失敗的主要原因是,它大大削減了微服務(wù)的內(nèi)在價(jià)值扰楼。使用客戶端庫(kù)呀癣,每次更新服務(wù)時(shí)都需要重新部署服務(wù),這降低了部署速度并增加了故障風(fēng)險(xiǎn)弦赖。更糟糕的是项栏,我們需要限制每個(gè)團(tuán)隊(duì)使用的技術(shù)棧,因?yàn)槲覀冎皇褂脝蝹€(gè)客戶端庫(kù)蹬竖≌由颍可以想象,我們也可以使用其他語(yǔ)言構(gòu)建客戶端庫(kù)币厕,但這很快就變的不切實(shí)際列另,因?yàn)檫@會(huì)相當(dāng)難以維護(hù)。
由于高延遲會(huì)導(dǎo)致體系結(jié)構(gòu)失敗旦装,所以但客戶端解決方案不可行页衙。
為了解決這些問(wèn)題,我們可以簡(jiǎn)單地添加一個(gè)代理阴绢。該解決方案將關(guān)注點(diǎn)從工程轉(zhuǎn)移到了 DevOps店乐,這樣工程團(tuán)隊(duì)可以專注于改善服務(wù)。代理進(jìn)程與每一項(xiàng)服務(wù)同時(shí)運(yùn)行呻袭,并抽象出關(guān)鍵的流量管理功能眨八,每當(dāng)我們發(fā)出請(qǐng)求時(shí),請(qǐng)求都會(huì)通過(guò)我們的代理左电,并且代理會(huì)處理可能出現(xiàn)的任何問(wèn)題廉侧。如果我們的網(wǎng)絡(luò)不可靠或延遲太高含长,代理將確保我們可以重試或修復(fù)不起作用的服務(wù)。
這使我們可以從代碼庫(kù)和開(kāi)發(fā)團(tuán)隊(duì)中抽象出流量路由和管理功能伏穆。而服務(wù)開(kāi)發(fā)團(tuán)隊(duì)不需要擔(dān)心網(wǎng)絡(luò)問(wèn)題拘泞,因?yàn)榇砜梢蕴幚磉@些問(wèn)題,在部署代碼時(shí)枕扫,需要將代理注入我們的服務(wù)中陪腌。
服務(wù)網(wǎng)格的構(gòu)成 - Sidecar
為了降低將代理注入到服務(wù)的復(fù)雜性,即創(chuàng)建了 sidecar 模式烟瞧。Sidecar 利用了由容器編排工具(如 Kubernetes)創(chuàng)建的抽象層诗鸭,這個(gè)抽象層存在于我們的容器與運(yùn)行容器的虛擬機(jī)之間,它使我們的虛擬機(jī)看起來(lái)像一個(gè)單一的結(jié)構(gòu)参滴,使用 Kubernetes 時(shí)强岸,我們可以讓一個(gè)容器成為另一個(gè)容器的 Sidecar 代理,從而使 Sidecar 能夠獨(dú)立與運(yùn)行服務(wù)的容器處理網(wǎng)絡(luò)通信砾赔,這構(gòu)成了我們服務(wù)網(wǎng)格的基礎(chǔ)蝌箍。
隨著網(wǎng)格不斷增長(zhǎng),Sidecar 代理可以隨著我們不斷增長(zhǎng)的微服務(wù)數(shù)量一同有效擴(kuò)展顯得至關(guān)重要暴心。在容器化的世界中妓盲,我們正在不斷縮小服務(wù)粒度,這要求 Sidecar 代理必須輕巧和快速专普。由于我們迫使 Kubernetes 將兩個(gè)容器都推送到同一臺(tái)主機(jī)上悯衬,以最大程度減少服務(wù)容器與 Sidecar 代理之間發(fā)生通信問(wèn)題的可能性。如果代理服務(wù)太大檀夹,則將使基礎(chǔ)虛擬機(jī)負(fù)載過(guò)重筋粗,如果代理服務(wù)太慢,則會(huì)帶來(lái)延遲的風(fēng)險(xiǎn)炸渡,過(guò)渡到服務(wù)網(wǎng)格需要進(jìn)行微調(diào)優(yōu)化性能娜亿,因此我們必須能夠準(zhǔn)確診斷可能出現(xiàn)潛在問(wèn)題的位置,
了解服務(wù)網(wǎng)格
隨著服務(wù)之間東西向 API 調(diào)用的數(shù)量呈指數(shù)級(jí)增長(zhǎng)偶摔,我們了解延遲性能的能力變的至關(guān)重要暇唾。幸運(yùn)的是,服務(wù)網(wǎng)格的體系結(jié)構(gòu)非常適合跟蹤性能辰斋。每個(gè) Sidecar 代理都充當(dāng)代理和反向代理,分別是用于主站通信的代理和用于入站的反向代理瘸味,由于我們的 Sidecar 同時(shí)具有兩種功能宫仗,因此它知道何時(shí)發(fā)送通信以及何時(shí)接收通信,從而為我們提供了開(kāi)箱即用的遙測(cè)技術(shù)旁仿。這使我們能夠在流量離開(kāi)或者進(jìn)入某一項(xiàng)服務(wù)時(shí)對(duì)其進(jìn)行篩選藕夫。
控制服務(wù)網(wǎng)格
與任何架構(gòu)創(chuàng)新一樣孽糖,服務(wù)網(wǎng)格在盡顯優(yōu)勢(shì)的同時(shí)也帶來(lái)了新的挑戰(zhàn)。我們必須解決的第一個(gè)問(wèn)題是如何配置所有代理毅贮,例如我們想將訂單與發(fā)票之間的服務(wù)通信時(shí)間從10秒改為5秒办悟,我們?nèi)绾卧诓恢匦虏渴?Sidecar 代理的每個(gè)實(shí)例的情況下做到這一點(diǎn),答案在于我們?nèi)绾畏蛛x數(shù)據(jù)層(data plane)和控制層(control plane)滩褥。
以最簡(jiǎn)單的形式說(shuō)明病蛉,數(shù)據(jù)層和控制層可以這么理解:數(shù)據(jù)層是在服務(wù)執(zhí)行路徑上,服務(wù)至服務(wù)請(qǐng)求間的任何內(nèi)容瑰煎;控制層將配置推送到數(shù)據(jù)層铺然。就我們的服務(wù)網(wǎng)格而言,我們將在控制層對(duì)給定的配置進(jìn)行更改酒甸,并且將更改推送到我們的 Sidecar 代理中魄健。由于我們的控制層可以識(shí)別與每一項(xiàng)服務(wù)相關(guān)聯(lián)的代理實(shí)例,因此我們可以快速對(duì)我們的每一個(gè)代理配置進(jìn)行大規(guī)模的更改插勤,但不會(huì)中斷我們的服務(wù)沽瘦。
總結(jié)
服務(wù)網(wǎng)格為我們提供了與傳統(tǒng)部署方式的子集,使我們可以更好地處理微服務(wù)架構(gòu)中所產(chǎn)生的東西向流量农尖。我們的服務(wù)網(wǎng)格代理可以收集遙測(cè)其垄,處理路由和錯(cuò)誤處理,并以傳統(tǒng)網(wǎng)關(guān)多年來(lái)處理南北流量的方式來(lái)限制對(duì)我們的訪問(wèn)卤橄。本質(zhì)上绿满,我們使用的是相同的技術(shù)和功能,只是部署在不同的實(shí)現(xiàn)中窟扑。
對(duì)于傳統(tǒng)企業(yè)來(lái)說(shuō)喇颁,不可能有一個(gè)單一的主導(dǎo)實(shí)施范例。過(guò)渡到新架構(gòu)模式有固有的風(fēng)險(xiǎn)和破壞性嚎货,不是瞬間就能切換到共有云橘霎,或者采用服務(wù)網(wǎng)格的。但是殖属,隨著分布式的場(chǎng)景越來(lái)越多姐叁,網(wǎng)格網(wǎng)格的泛用性越來(lái)越高。盡管如此洗显,最有可能發(fā)生的情況是外潜,當(dāng)我們過(guò)渡到分布式體系結(jié)構(gòu)時(shí),我們?nèi)詫⒁揽渴褂脗鹘y(tǒng)體系結(jié)構(gòu)構(gòu)建的應(yīng)用程序來(lái)提供服務(wù)挠唆。這使得打造一個(gè)舊式架構(gòu)和現(xiàn)代架構(gòu)有效結(jié)合的 API 管理平臺(tái)成為數(shù)字化轉(zhuǎn)型過(guò)程中的關(guān)鍵一步处窥。