Mecha:將Mesh進行到底

頭條號:

大資料與雲原生

微信公眾號:

大資料與雲原生

Servicemesh 落地實踐三年,效果一直並不理想,到了該反思的時候了。Mecha 作為面向服務的分散式能力抽象層,是 Servicemesh 模式的自然進化版本,預計也將是雲原生化和 Mesh 化的必然趨勢,讓我們將 Mesh 進行到底。

Mecha 介紹

什麼是 Mecha?

Mecha 一詞,相信愛好動漫的同學應該都不陌生。是的,就是大家熟悉的那個 Mecha(機甲):

Mecha:將Mesh進行到底

Mecha 這個詞之所以出現在這裡,主要是因為 Bilgin Ibryam 的這個部落格文章 “Multi-Runtime Microservices Architecture”,提出了微服務架構的一個新的設想:Multiple Runtime。

備註:這篇部落格文章強烈推薦閱讀,我甚至建議在閱讀本文之前先閱讀這篇文章,因為我今天的內容,可以視為對這個文章的深度解讀和思考。為了方便,這裡提供一份中文翻譯版本 多執行時微服務架構。

在這篇部落格中,Bilgin Ibryam 首先分析並總結了分散式應用的四大需求:

Mecha:將Mesh進行到底

生命週期(Lifecycle)

網路(Networking)

狀態(State)

捆綁(Binding)

由於每種需求存在的問題和侷限性,導致傳統解決方案如企業服務匯流排(ESB)及其變體(例如面向訊息的中介軟體,更輕量級的整合框架等)不再適用。隨著微服務架構的發展,以及容器和 Kubernetes 的普及和廣泛使用,雲原生思想開始影響這些需求的實現方式。未來的架構趨勢是透過將所有傳統的中介軟體功能移至其他執行時來全面發展,最後的目標是在服務中只需編寫業務邏輯。

備註:詳情請見原文,為了節約篇幅,這裡只做簡單概述,不完全引用原文內容。

下圖是傳統中介軟體平臺和雲原生平臺的對比,傳統中介軟體以各種 SDK 的方式提供能力,而云原生平臺則透過各種外圍 Runtime(典型如大家熟悉的 Servicemesh/Istio):

Mecha:將Mesh進行到底

因此作者引入了 Multiple Runtime 的概念:

Mecha:將Mesh進行到底

作者提出:很可能在將來,我們最終將使用多個執行時來實現分散式系統。多個執行時,不是因為有多個微服務,而是因為每個微服務都將由多個執行時組成,最有可能是兩個執行時 - 自定義業務邏輯執行時和分散式原語執行時。

對多執行時微服務架構和 Mecha 的說明:

您還記得電影《阿凡達》和科學家們製作的用於去野外探索潘多拉的 Amplified Mobility Platform (AMP)“機車服”嗎?這個多執行時架構類似於這些 Mecha- 套裝,為類人駕駛員賦予超能力。在電影中,您要穿上套裝才能獲得力量並獲得破壞性武器。在這個軟體架構中,您將擁有構成應用核心的業務邏輯(稱為微邏輯 /micrologic)和提供強大的開箱即用的分散式原語的 sidecar mecha 元件。Micrologic 與 mecha 功能相結合,形成多執行時微服務,該服務將程序外功能用於其分散式系統需求。最棒的是,Avatar 2 即將面世,以幫助推廣這種架構。我們最終可以在所有軟體會議上用令人讚歎的機甲圖片代替老式的邊車摩托車;-)。接下來,讓我們看看該軟體架構的詳細資訊。

這是一個類似於客戶端 - 伺服器體系結構的雙元件模型,其中每個元件都是獨立的執行時。它與純客戶端 - 伺服器架構的不同之處在於,這兩個元件都位於同一主機上,彼此之間有可靠的網路連線。這兩個元件的重要性相當,它們可以在任一方向上發起操作並充當客戶端或伺服器。其中的一個元件稱為 Micrologic,擁有非常少的業務邏輯,把幾乎所有分散式系統問題都剝離出去了。另一個伴隨的元件是 Mecha,提供了我們在本文中一直討論的所有分散式系統功能(生命週期除外,它是平臺功能)。

作者在這裡正式提出了 Mecha 的理念:

Mecha:將Mesh進行到底

思路大體是:Smart Runtime, Dumb Pipes。

我對 Mecha 的理解是:業務邏輯在編碼開始階段應該是“裸奔”的,專注於業務邏輯的實現,而儘量不涉及到底層實現邏輯;而在執行時,則應該裝備“機甲”,全副武裝,大殺四方。熟悉的味道是吧?標準而地道的雲原生思想。

Mecha 的本質

作者在原文中探討了 Mecha 執行時的特性:

Mecha 是通用的,高度可配置的,可重用的元件,提供分散式原語作為現成的能力。

Mecha 可以與單個 Micrologic 元件一起部署 (Sidecar 模式),也可以部署為多個共享 (注:我稱之為 Node 模式)。

Mecha 不對 Micrologic 執行時做任何假設。它與使用開放協議和格式(例如 HTTP/gRPC,JSON,Protobuf,CloudEvents)的多語言微服務甚至單體一起使用。

Mecha 以簡單的文字格式(例如 YAML,JSON)宣告式地配置,指示要啟用的功能以及如何將其繫結到 Micrologic 端點。

與其依靠多個代理來實現不同的目的(例如網路代理,快取代理,繫結代理),不如使用一個 Mecha 提供所有這些能力。

下面是我對上述特性的個人理解:

Mecha 提供的是能力,以分散式原語體現的各種能力,而不侷限於單純的網路代理。

Mecha 的部署模型,不侷限於 Sidecar 模式,Node 模式在某些場景下(如 Edge/IoT,Serverless FaaS)可能會是更好的方式。至少,Mecha 下有機會按需選擇,而不是綁死在 Sidecar 模式上

Mecha 和 Micrologic 之間的互動是開放而有 API 標準的,Mecha 和 Micrologic 之間的“協議”體現在 API 上,而不是 TCP 通訊協議。這提供了一個契機:一個統一 Micrologic 和 Mecha 之間通訊方式的契機。

Mecha 可以以宣告式的方式進行配置和控制,這非常符合雲原生的理念,同樣也使得 API 更關注於能力本身,而不是能力如何配置。

應用需要的能力如此之多(參見上面的圖:分散式應用的四大需求),如果每個能力都對應一個代理(不管是 Node 還是 Sidecar),數量會非常誇張,帶來的運維壓力會很可怕。因此,如 Mecha 這個名字暗示的,執行時應該是整套的形式提供能力,而不是分散。

如果用一句話來總結,那麼我認為 Mecha 的本質應該是:“面向應用的分散式能力抽象層”

如 Servicemesh 的本質是服務間通訊的抽象層一樣,Mecha 的本質是應用需要的各種分散式能力和原語,包括但不限於服務間通訊。

從這個角度上說,Mecha 覆蓋的範圍是 Servicemesh 的超集:畢竟 Servicemesh 只覆蓋到應用的部分需求(服務間通訊,還只限於同步 / 一對一 /request-response 模式),還有更多的分散式能力和原語有待覆蓋。

換一句話說,Mecha 的目標應該是:“將 Mesh 進行到底!”

Mecha 的優勢和未來

作者指出:Mecha 的好處是業務邏輯和越來越多的分散式系統問題之間的松耦合。

下圖是業務邏輯和分散式系統問題在不同架構中的耦合:

Mecha:將Mesh進行到底

其實思路和 Servicemesh 是一脈相承的,只是覆蓋的分散式能力更廣泛一些。

有一個問題:Mecha 會不會成為微服務架構的演進的下一個形態?我個人的答案:是,隨著雲原生的推進,分散式能力(以傳統中介軟體為典型代表)下沉是大勢所趨,Mesh 化的範圍必然會繼續擴大,也就離 Mecha 的形態越來越近了。這也就是本文標題的立意所在,Mecha 會是微服務乃至雲原生的下一站。

微軟 Dapr

在介紹完 Mecha/Multiple Runtime 的理念之後,我們來看看目前微軟新推出來的 Dapr 專案 —— 這應該是業界第一個 Multiple Runtime 的開源實踐專案。

專案地址:https://github。com/dapr/dapr。

Dapr 介紹

Dapr 是 Distributed Application Runtime (分散式應用執行時)的縮寫,官方介紹說 Dapr 是“一種可移植的,事件驅動的執行時,用於構建跨雲和邊緣的分散式應用”。

Dapr 的詳細介紹是:

Dapr 是一種可移植的,serverless 的,事件驅動的執行時,它使開發人員可以輕鬆構建彈性,無狀態和有狀態微服務,這些服務執行在雲和邊緣上,幷包含多種語言和開發框架。

Dapr 整理了構建微服務應用為開放,獨立的構建塊的最佳實踐,使您能夠使用自己選擇的語言和框架來構建可移植的應用程式。每個構建塊都是獨立的,您可以在應用中使用其中的一個或多個。

Dapr 的功能和定位,下面這一張圖就可以概括了:

Mecha:將Mesh進行到底

最底下基礎設施是各種雲平臺(主流公有云都支援)或者邊緣環境

其上是 dapr 提供的分散式能力,dapr 稱之為“building block”。

這些 building block 的能力,以統一的 API(支援 HTTP 和 gRPC)對外提供服務

應用可以用各種語言編寫,然後透過 dapr 提供的 API 使用這些能力,dapr 也提供客戶端類庫來簡化對 API 的呼叫,實現了多語言的支援。

Dapr 提供的具體分散式能力(building block)如下圖所示:

Mecha:將Mesh進行到底

每個 building block 提供的具體能力請參加 Dapr 的官方文件:https://github。com/dapr/docs/tree/master/concepts。

Dapr 的 API 例子

我們來看一下應用呼叫 Darp API 的例子,體驗一下使用 Dapr 的方式。

以 Service Invocation / 服務呼叫為例:

Mecha:將Mesh進行到底

部署和呼叫方式與 Servicemesh/Istio 極為相似,但是,差別在於:Dapr 是以提供 API 的方式提供 API 背後的能力,而不是提供提供協議代理的方式。

上圖中 1,是 ServiceA 發起請求來呼叫一個遠端服務。其 HTTP request 如下所示:

POST/GET/PUT/DELETE http://localhost:/v1。0/invoke//method/

其中:

引數 daprPort 是 Dapr Runtime 啟動的監聽埠,用來接受應用的 outbound 請求

引數 appId 是遠端應用在 darp 中的關聯 id,每個註冊到 dapr 的應用都有一個唯一的 appId

引數 method-name 是要呼叫的遠端應用的方法名或者 URL

負載可以存放在 HTTP body 中隨請求傳送,如 json。

注意,雖然都是提供相同的功能,這裡體現了 Dapr(或者說背後的 Mecha)和 Servicemesh 在方式上的差異:暴露 API 還是代理通訊協議。

我們看一個更明顯的例子,dapr 提供的 “publish/subscriptions” 能力,讓應用可以方便的釋出訊息,或者訂閱主題並接收訊息。下圖是應用釋出訊息,請求直接發給 dapr 即可:

Mecha:將Mesh進行到底

例子中,引數 topic 指定了訊息要發往的主題(例子中是 deathStarStatus)。後續 dapr 會完成將訊息入 queue,然後推送到訂閱了該 topic 的應用。接收訊息的方式也類似,不過這次是 darp 主動發起:

Mecha:將Mesh進行到底

dapr 首先會請求應用,諮詢應用需要訂閱那些主題(topic),如例子中應用返回的的 TopicA / TopicB

dapr 實現主題訂閱,在接收到訊息之後,再把訊息傳送給應用,透過 URL 引數的不同來區分不同的主題

注意在這個呼叫期間,無論是收發訊息,應用完全不用理會底層 pub/sub 的實現機制(比如是 kafka,還是 rocketmq,還是其他公有云提供的訊息機制),也完全不用引入該實現機制的客戶端 SDK,只是簡單的使用 darp 定義的 API 即可,從而實現了和底層的解耦,以及“廠商不繫結”。

為了進一步簡化呼叫的過程(畢竟發一個最簡單的 HTTP GET 請求也要應用實現 HTTP 協議的呼叫 / 連線池管理等),dapr 提供了各個語言的 SDK,如 java / go / python / dotnet / js / cpp / rust 。另外同時提供 HTTP 客戶端和 gRPC 客戶端。

我們以 Java 為例,java 的 client API 介面定義如下:

public interface DaprClient { Mono publishEvent(String topic, Object event); Mono invokeService(Verb verb, String appId, String method, Object request); ……}

具體可見:

https://github。com/dapr/java-sdk/blob/master/sdk/src/main/java/io/dapr/client/DaprClient。java

分析和總結

前面介紹了 Multiple Runtime / Mecha 的架構思想,以及參考實現之一的微軟 Dapr 專案。

由於 Multiple Runtime / Mecha 這個思想非常的新,剛剛提出不久,而微軟 Dapr 專案也是一個新出來的專案,不管是理論思想還是實踐都處於非常早期的狀態,也還沒有形成完善的方法論。

特別申明:以下內容更多是我個人當下的理解和感悟,僅代表個人意見,肯定有很多不成熟甚至謬誤的地方,歡迎指正和探討。

Mecha 和 Dapr 的啟示

1。 Mesh 模式應該推向更大的領域

隨著雲原生的深入,應用需要的分散式能力應該全面下沉,而不僅僅侷限於 Servicemesh 提供的服務間通訊能力;應用形態會朝純業務邏輯這個目標更進一步,應用更加的雲原生化。

這是大勢所趨,也是 Mecha 架構出現和發展的原動力。

2。 Mecha 強調是“提供能力”,而不是通訊代理

Mecha 的使用方式和 Servicemesh 有非常大的差異:Mecha 強調的是提供分散式能力給應用使用,這些能力最終以封裝完善的 API 的方式呈現。API 體現的是應用對能力的“需求”和“意願”,不涉及到如何實現,實現是 Mecha 的職責,採用什麼樣的實現也是由 Mecha 來控制。

在 Servicemesh 下,不存在這個需求:Servicemesh 提供的是服務間通訊能力,這個能力是由 sidecar 來提供,沒有其他的更底層的實現,不存在隔離和替換的可能。受服務通訊協議和報文 schema 的限制,Servicemesh 只能做請求的“轉發”,能力聚焦在“如何轉發”上,沒有其他需要隔離和替代的能力。

當 Mecha 把能力擴充套件到 Servicemesh 之外時,很多能力是由外部系統提供:比如 pub-sub 能力可以由不同的 Message Queue 實現;狀態管理能力可以連線不同的 Key-Value 實現。此時能力的隔離性和可替代性就成為關鍵需求:解耦應用和能力實現,容許 Mecha 替換底層實現(進而實現供應商不鎖定等)。

3。 不強求“零侵入”

在 Servicemesh 中,“零侵入”是一個非常強調的特性,為此不惜引入 iptables 等流量劫持方案。“零侵入”在某些特殊場景下會發揮巨大的優勢,如舊有應用不做改造的前提下接入 servicemesh。好處自然不言而喻,但零侵入也有自身的限制:客戶端必須能發出符合伺服器端要求的網路通訊請求,這個過程外部無法插手。

對於服務間通訊,這個不是大問題。但是對於其他能力,由於有和實現解耦的需求,再透過客戶端自行發起原生協議的請求就不合適了。因此,Mecha 中更傾向於採用低侵入的輕量級 SDK 方案,同樣也可以實現跨語言和跨平臺,只是需要付出實現各種語言 SDK 的代價。由於這個 SDK 足夠輕量,因此代價還不算很高。

而這些少量的工作量,少量的侵入,可以換取輕量級 SDK 能提供的各種便利和配合(簡單理解:開後門),可以實現能力的抽象和 API 的封裝。權衡利弊,Mecha 下更傾向於輕量級 SDK 方案。

4。 不限定 Sidecar 部署

Sidecar 部署模式,存在資源佔用、維護成本增加等缺點,在某些情況下可能並不合適:

邊緣網路,IoT 場景:資源非常有限,不適合啟動太多 Sidecar

FaaS 場景:應用自身足夠輕量,甚至比 Sidecar 還要輕量

Serverless 場景:Scale to Zero 時,對冷啟動速度有嚴格要求,Sidecar 的啟動和初始化可能拖累應用啟動速度

Mecha 下,部署模式不限定於 Sidecar ,在合適時容許選擇 Node 模式,甚至 Node 模式和 Sidecar 模式混合使用

5。 API 和配置是關鍵

API 是分散式能力的抽象,需要要對(開發上層業務應用的)客戶友好,簡單好用,穩定不變。這些 API 也需要標準化,被社群廣泛接受和採納,才能實現廠商不鎖定和自由遷移,提升客戶價值。

另外,API 還需要配合配置使用,在把能力抽象為 API 時,是不提供能力的細節控制的。這些控制將在執行時由 Mecha 根據配置實現,可以理解為:“API + 配置 = 完整的能力”。

API 和配置的制訂以及標準化,預計將會是 Mecha 成敗的關鍵。

Mecha 的精髓

Program to an interface, not an implementation。

Design Patterns: Elements of Reusable Object-Oriented Software (GOF, 1994)

Mecha 的精髓,要從上面這句名言開始:在 Mecha 下,為了實現 解耦 和 可替換, Runtime 隔離 了底層實現,因此演變為:“Program to an Runtime, not an implementation。”“

考慮到 Runtime 不管是部署為 Sidecar 模式,還是部署為 Node 模式,都是 Localhost,因此有:“Program to an Localhost, not an implementation。”

為了簡化開發,Mecha 還是會提供輕量級 SDK,提供 API 作為能力的 抽象:“Program to an API, not an implementation。”

考慮到 API 通常是以 interface 的形式提供,因此繞了一圈,Mecha 最後還是回到原點:“Program to an interface, not an implementation。”

個人理解,Mecha 的精髓就在於這幾個關鍵點:隔離 / 抽象 / 解耦 / 可替換。如下圖所示:

Mecha:將Mesh進行到底

在 Mecha 下,MicroLogic(也就是業務邏輯的程式碼實現)不容許直接使用底層實現提供的分散式能力

Mecha Runtime 將為 Micro Logic 提供分散式能力,同時隔離應用和底層實現

為了方便使用,提供輕量級 SDK,其中的 API 層實現了分散式能力的抽象,應用只需面向 API 程式設計

輕量級 SDK 和 Mecah Runtime 配合,完成對底層實現的解耦和可替換。

Mecha 的實現原則

在 Mecha 的實現上,我理解的原則是這樣:

Runtime 是主力,要做厚

輕量級 SDK 主要是給 Runtime 打配合,要做薄

具體的職責劃分:

輕量級 SDK:實現多語言接入,低侵入(但不追求零侵入)

API 介面:由輕量級 SDK 中提供統一,目標社群化 + 標準化,給開發者提供一致的程式設計體驗,同時提供可移植性

應用:輕量級 SDK/Runtime 配合,提供各種分散式能力,應用無感,只需簡單使用 API,不耦合底層實現

在 Mecha 架構中,Runtime 自然是整個架構的核心,扮演類似 Servicemesh 中資料平面的角色

所有分散式能力使用的過程(包括訪問內部生態體系和訪問外部系統)都被 Runtime 接管和遮蔽實現

透過 CRD/ 控制平面實現宣告式配置和管理(類似 Servicemesh)

部署方式上 Runtime 可以部署為 Sidecar 模式,或者 Node 模式,取決於具體需求,不強制

備註:Mecha 有非常多的能力,實現上也有非常多的細節,這裡先做一個 High Level 的概述。細節後面會有一系列文章一一覆蓋,歡迎多交流討論。

Mecha 總結

大概是在 3 月初,當時我第一次閱讀 “Multi-Runtime Microservices Architecture” 這篇文章,有一種豁然開朗的感覺,尤其是有很多之前在反覆考慮和權衡但是下不了結論的問題,在這個文章中得到了清晰的解答。可謂受益匪淺。

在 Servicemesh 探索和實踐的這三年中,遇到很多問題,有很多之前沒有想到過的問題浮現。比如,以前一直覺得 Servicemesh 中引入 Sidecar 帶來的最大麻煩會是效能,但實際上,從目前的實踐看,Sidecar 引入後帶來的維護代價才是更令人頭疼的事情,相比之下 Sidecar 引入帶來的效能損失顯得無傷大雅。

總結一下我個人對 Mecha 架構的核心理解,主要是兩點:

Mecha 是雲原生化和 Mesh 化的必然趨勢:雲原生在繼續發展,應用需要的分散式能力需要繼續下沉,越來越多的能力會以 sidecar 的形式出現,這是大勢所趨。但不可能出現一個應用部署十幾個 sidecar 的局面,這會是運維地獄。因此,必然需要出現新的形態來解決 Sidecar 過多的問題,合併為一個或者多個 Sidecar 就會成為必然。

Mecha 是 Servicemesh 模式的自然進化版本:Servicemesh 落地實踐三年了,效果一直並不理想,到了該反思反省的時候了;而且 Mecha 的範圍也遠不止服務間通訊,新的需求下應該有新的思考和突破。Servicemesh 現有的固定模式,在 Mecha 下可以嘗試打破以探索新的方式:不必拘泥於 Sidecar,試試 Node 模式;不必拘泥於通訊協議轉發,試試 Runtime 提供能力解耦底層實現;不必拘泥於零侵入,試試在應用中保留一個足夠輕的輕量級 SDK。

正如曾有說法,說“微服務是 SOA 實踐中正確的部分(the Good Part)”,我希望在 Mecha 的探索和實踐中,能夠從 Servicemesh 的實踐中吸取成功的經驗和失敗的教訓,希望 Mecha 也能成為 Servicemesh 的 Good Part。希望在雲原生的演進路線中,Mecha 可以繼微服務和 Servicemesh 之後,成為雲原生落地實踐的下一站。

回到現實,目前 Mecha 和 Multi-Runtime 還是一個非常新的想法,Dapr 專案也才剛剛起步,Mecha 要探索的道路還很漫長,一切都還需要摸索著前進。

附錄:參考資料

在文章的最後,特別鳴謝 “Multi-Runtime Microservices Architecture”一文的作者 “Bilgin Ibryam”,我非常認可這篇文章中的思想和理念,分析歸納的非常到位,提煉和昇華的能力令人佩服。

本文參考了 Bilgin Ibryam 出品的如下內容:

Multi-Runtime Microservices Architecture,作者 Bilgin Ibryam,Mecha 的思想來自這篇文章,強烈推薦閱讀。也可以直接看我翻譯的版本 多執行時微服務架構。如前所述,建議在閱讀本文之前先閱讀這篇部落格文章。

The Evolution of Distributed Systems on Kubernetes : 作者 Bilgin Ibryam, 2020 年 3 月在 QCon London 的演講,依然強烈推薦。內容非常精彩,對 Kubernetes 上分散式系統演進做了很好的總結和展望,當然也依然在佈道多執行時微服務架構的理念。本文的很多圖片 援引自這份 PPT。