新錘子駕到,通通閃開—Service Mesh

微服務方興未艾如火如荼之際,除 Spring cloud 等經典框架之外,新一代的微服務開發技術正在悄然興起,那就是Service Mesh(服務網格)。2018 年是Service Mesh 元年,其被譽爲是下一代微服務架構。

這兩年,服務網格已成爲雲原生應用技術棧裏的關鍵組件。Paypal,Ticketmaster和Credit Karma 等這些擁有大流量的公司,都爲其生產環境應用添加了服務網格。2017年1月,Linkerd(某個雲原生應用程序服務網格的開源項目)已經成爲雲原生計算基金會的官方項目。但究竟什麼是服務網格呢?爲什麼它突然顯得如此重要?

本文將會討論服務網格,並通過過去十多年應用程序架構的變化來追溯其演變;此外,將會把服務網格與API網關、邊緣代理和企業服務總線等相關、但不同的概念區分開來。在最後,我們試圖預測服務網格的發展方向。


服務網格是什麼?

服務網格是專門用來處理服務與服務之間通訊的基礎設施層,用以可靠地傳遞服務請求。這是通過採用複雜的服務拓撲完成的,這些服務構成了現代的雲原生應用。實際上,服務網格的常見實施是通過一系列輕量級的網絡代理形成的陣列來實現的,這些代理和應用代碼一起運行,但是應用通常並不知道它們的存在(有時候也有些區別)。

作爲單獨的一層,服務網格這個概念與雲原生應用的興起息息相關。在雲原生模型中,單個應用程序可能包含數百個服務; 每個服務可能有數千個實例; 並且每個實例可能處於不斷變化的狀態中,因爲它們經由諸如Kubernetes這樣的編排器動態調度。在這種情況下,服務間的通訊不僅極其複雜,而且是應用runtime裏普遍存在和最基本的一部分。管理好這些服務間的通訊對於確保端到端的性能和可靠性至關重要。


服務網格是個網絡模型嗎?

服務網格的確是種網絡模型,它是基於TCP / IP之上的一層抽象層。它的前提條件是下層存在第三第四層網絡,並且能夠從一點到另一點傳送數據。(它還假設三四層網絡以及其他的相關環境並不可靠,因此服務網格也必須能夠處理網絡故障。)

從某種意義上說,服務網格類似於TCP / IP。正如TCP技術棧抽象了在網絡端點之間可靠傳遞數據一樣,服務網格抽象了在服務之間可靠地傳遞請求的機制。與TCP一樣,服務網格並不關心實際載荷以及編碼方式。應用程序本身有一個更高級別的目標,而服務網格的工作,和TCP類似的,是在出現任何網絡故障的實現這一目標。

而與TCP不同的是,服務網格除了 “僅僅確保應用正常”這個目標以外,還有一個非常重要的工作:它提供了一個統一的、在整個應用程序範圍內的可見性和可控性。服務間的通訊通常是不可見的,存在於隱形的基礎設施層;而服務網格把這些通訊顯性化,令其成爲應用生態系統的關鍵部分,並且可以對其進行監控,管理和控制。


服務網格到底做了什麼?

在雲原生應用程序中,服務請求的傳遞非常複雜。像Linkerd 這樣的服務網格,使用了一系列技術手段來管理這種複雜性:鏈路中斷,延遲感知負載均衡,最終一致(“建議”)服務發現,重發,截止時間等等。這些功能必須全部協同工作,這些功能與其運行的複雜環境之間的相互作用可能非常微妙。

例如,當通過Linkerd向服務發出請求時,一個非常簡化的事件時間表如下:

  • Linkerd採用動態路由規則來確定請求者想要的服務。請求是否應該路由到生產環境或測試環境?到本地數據中心或雲數據中心?採用正在測試的服務的最新版本,還是在生產中經過審查的較舊版本?所有這些路由規則都是動態可配置的,並且可以全局應用,也可以應用於任意流量切片。
  • 找到正確的目的地後,Linkerd從相關的服務發現端點檢索相應的實例池,其中可能有幾個。如果這些信息與Linkerd自己發現的信息不同,那麼Linkerd會決定信任哪些信息來源。
  • Linkerd根據各種因素選擇最有可能返回快速響應的實例,這些因素包括觀察到的最近請求的延遲。
  • Linkerd嘗試將請求發送到實例,記錄結果的延遲和響應類型。
  • 如果實例關閉,無響應或無法處理請求,則Linkerd會在另一個實例上重試該請求。
  • 如果實例始終返回錯誤,則Linkerd會將其從負載均衡資源池中剔除,並且稍後定期重試(例如,實例可能正在經歷瞬態故障)。
  • 如果請求的deadline已過,則Linkerd會主動發送請求失敗,而不用進一步重試進而增加負載。
  • Linkerd採用度量和分佈式跟蹤的形式追蹤上述行爲的各個方面,並將其發送到集中式度量系統。

這只是簡化版本 - Linkerd還可以發起和終止TLS,執行協議升級,動態轉換流量以及數據中心之間的業務轉移。

Linkerd服務網格管理服務與服務間的通訊,並將其與應用程序代碼分離

值得注意的是,這些功能不僅提供逐點彈性,也提供了應用程序範疇的彈性。對於大規模分佈式系統,無論它們是如何構建的,都有一個明確的特徵:它們的本地小型故障,有很大的機會升級成全系統性的災難型故障。因此,當底層系統接近其負荷時,服務網格的設計必須能夠通過減少負載和快速失敗,來防止這些演變。

爲什麼服務網格是必要的?

歸根到底,與其說服務網格是一個新功能概念,不如說是功能所在位置的轉變。Web應用程序必須始終管理服務通訊的複雜性,因此服務網格模型的起源,可以追溯到過去的十五年間這些應用程序的演變過程。

現在我們先回顧一下2000年代中型Web應用程序的典型架構:三層應用程序。在這個模型架構中,應用程序邏輯、Web服務邏輯,乃至存儲邏輯都是單獨的層。層與層之間的通訊雖然複雜,但範圍有限 - 畢竟只有兩個躍點(路由)。在這兒沒有“網格”的概念,但是在處理每個層代碼的躍點之間,是存在着通訊邏輯的。

當這種架構方法被應用在非常大的規模時,它開始分裂。像谷歌、Netflix和Twitter這樣的公司,面臨着巨大的流量需求,就採用了本質上是雲原生方法的前身:應用層被分成許多服務(有時我們將之稱爲“微服務”),層成爲拓撲。這些系統中,普遍的通訊層突然變得相關,而在當時大家通常採用的是“胖客戶端”庫形式—推特的Finagle、Netflix的 Hystrix,以及谷歌的Stubby就是例證。

從許多方面來說,像Finagle,Stubby和Hystrix這樣的庫就是第一個服務網格。雖然它們具體涉及周圍環境的細節,並且需要使用特定的語言和框架,但它們是作爲基礎設施的形式來管理服務間通信,並且發現在其原始公司之外使用(就開放源碼的Finagle和Hystrix庫而言)。

把鏡頭快進到現代的雲原生應用程序。雲原生模型將微服務(許多小型服務)方法與兩個額外因素相結合:容器(例如 Docker),提供資源隔離和依賴管理;以及編排層(例如 Kubernetes),它將底層硬件抽象爲同質池。

這三個組件允許應用程序適應負載下的自然機制,並用於處理雲環境中時常存在的局部故障。但是,如果有數百個服務或數千個實例,且業務流程層要對實例從頭到尾進行重新安排,單個請求在服務拓撲中遵循的路徑可能會變得極其複雜;並且由於容器的存在,每個服務都能很容易地用不同的語言來編寫。因此在這種情況下,庫方法就不再可行了。

這種組合的複雜性和關鍵性,更激發了對服務與服務間通訊專用層的需求,該專用層將應用程序代碼分離,並且能夠捕獲底層環境的高度動態性。你可能很容易猜到,這個專用層就是服務網格。


服務網格的未來

儘管在雲原生生態系統中,服務網格的應用量正在迅速增長,但目前還有一個廣闊而令人興奮的未來仍有待我們去探索。無服務器計算的要求(例如亞馬遜的 Lambda)直接就適用於服務網格模型的命名和鏈接,並形成其在雲原生系統中角色的自然延伸。服務身份和訪問策略在雲原生環境中仍然是一個相當新的概念,而服務網格很有可能在這裏扮演重要角色。另外,服務網格(如之前的TCP / IP)將繼續被推送到底層基礎架構中。正如Linkerd從像Finagle這樣的系統發展而來,當前版本的服務網格作爲一個單獨的、用戶空間代理,必須顯性地添加到雲原生技術棧中,才能夠得以持續發展。


結論

服務網格是雲主機堆棧的關鍵組件。Linkerd成立僅一年多,它就是Cloud Native Computing Foundation的一部分,擁有一個蓬勃發展的貢獻者和用戶社區。使用者包括像顛覆英國銀行業的Monzo這樣的創業公司,以及Paypal,Ticketmaster和Credit Karma這種大規模互聯網公司,還有像Houghton Mifflin Harcourt這樣經營了數百年的公司。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章