Mecha:將 Mesh 進行到底

內容摘要:Service Mesh 落地實踐三年,效果一直並不理想,到了該反思的時候了。Mecha 做爲面向服務的分佈式能力抽象層,是 Service Mesh 模式的天然進化版本,預計也將是雲原生化和 Mesh 化的必然趨勢,讓咱們將 Mesh 進行到底。java

Mecha 介紹

什麼是 Macha?

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

mecha

Mecha 這個詞之因此出如今這裏,主要是由於 Bilgin Ibryam 的這個博客文章 「Multi-Runtime Microservices Architecture」,提出了微服務架構的一個新的設想:Multiple Runtime。github

備註:這篇博客文章強烈推薦閱讀,我甚至建議在閱讀本文以前先閱讀這篇文章,由於我今天的內容,能夠視爲對這個文章的深度解讀和思考。爲了方便,這裏提供一份中文翻譯版本 多運行時微服務架構

在這篇博客中,Bilgin Ibryam 首先分析並總結了分佈式應用的四大需求:編程

four-needs-of-app

  • 生命週期(Lifecycle)
  • 網絡(Networking)
  • 狀態(State)
  • 捆綁(Binding)

因爲每種需求存在的問題和侷限性,致使傳統解決方案如企業服務總線(ESB)及其變體(例如面向消息的中間件,更輕量級的集成框架等)再也不適用。隨着微服務架構的發展,以及容器和 Kubernetes 的普及和普遍使用,雲原生思想開始影響這些需求的實現方式。將來的架構趨勢是經過將全部傳統的中間件功能移至其餘運行時來全面發展,最後的目標是在服務中只需編寫業務邏輯。json

備註:詳情請見原文,爲了節約篇幅,這裏只作簡單概述,不徹底引用原文內容。

下圖是傳統中間件平臺和雲原平生臺的對比,傳統中間件以各類SDK的方式提供能力,而云原平生臺則經過各類外圍Runtime(典型如你們熟悉的Servicemesh/Istio):緩存

traditional-platform-and-cloudnative-platform

所以做者引入了 Multiple Runtime 的概念:服務器

multi-runtime-microservices

做者提出:極可能在未來,咱們最終將使用多個運行時來實現分佈式系統。多個運行時,不是由於有多個微服務,而是由於每一個微服務都將由多個運行時組成,最有多是兩個運行時-自定義業務邏輯運行時和分佈式原語運行時。網絡

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

您還記得電影《阿凡達》和科學家們製做的用於去野外探索潘多拉的 Amplified Mobility Platform (AMP)「機車服」嗎?這個多運行時架構相似於這些 Mecha-套裝,爲人形駕駛員賦予超能力。在電影中,您要穿上套裝才能得到力量並得到破壞性武器。在這個軟件架構中,您將擁有構成應用核心的業務邏輯(稱爲微邏輯/micrologic)和提供強大的開箱即用的分佈式原語的 Sidecar Mecha 組件。Micrologic 與 Mecha 功能相結合,造成多運行時微服務,該服務將進程外功能用於其分佈式系統需求。最棒的是,Avatar 2 即將面世,以幫助推廣這種架構。咱們最終能夠在全部軟件會議上用使人讚歎的機甲圖片代替老式的邊車摩托車;-)。接下來,讓咱們看看該軟件架構的詳細信息。
這是一個相似於客戶端-服務器體系結構的雙組件模型,其中每一個組件都是獨立的運行時。它與純客戶端-服務器架構的不一樣之處在於,這兩個組件都位於同一主機上,彼此之間有可靠的網絡鏈接。這兩個組件的重要性至關,它們能夠在任一方向上發起操做並充當客戶端或服務器。其中的一個組件稱爲 Micrologic,擁有很是少的業務邏輯,把幾乎全部分佈式系統問題都剝離出去了。另外一個伴隨的組件是 Mecha,提供了咱們在本文中一直討論的全部分佈式系統功能(生命週期除外,它是平臺功能)。

做者在這裏正式提出了 Mecha 的理念:app

multi-runtime-microservices-architecture

思路大致是:Smart Runtime, Dumb Pipes

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

Mecha 的本質

做者在原文中探討了 Mecha 運行時的特性:

  1. Mecha 是通用的,高度可配置的,可重用的組件,提供分佈式原語做爲現成的能力。
  2. Mecha 能夠與單個 Micrologic 組件一塊兒部署(Sidecar 模式),也能夠部署爲多個共享(注:我稱之爲 Node 模式)。
  3. Mecha 不對 Micrologic 運行時作任何假設,它與使用開放協議和格式(例如 HTTP/gRPC、JSON、Protobuf、CloudEvents)的多語言微服務甚至單體一塊兒使用。
  4. Mecha 以簡單的文本格式(例如 YAML、JSON)聲明式地配置,指示要啓用的功能以及如何將其綁定到Micrologic 端點。
  5. 與其依靠多個代理來實現不一樣的目的(例如網絡代理、緩存代理、綁定代理),不如使用一個 Mecha 提供全部這些能力。

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

  1. Mecha 提供的是能力,以分佈式原語體現的各類能力,而不侷限於單純的網絡代理。
  2. Mecha 的部署模型,不侷限於 Sidecar 模式,Node 模式在某些場景下(如 Edge/IoT,Serverless FaaS)可能會是更好的方式。至少,Mecha下有機會按需選擇,而不是綁死在 Sidecar 模式上。
  3. Mecha 和 Micrologic 之間的交互是開放而有 API 標準的,Mecha 和 Micrologic 之間的「協議」體如今 API 上,而不是 TCP 通信協議。這提供了一個契機:一個統一 Micrologic 和 Mecha 之間通信方式的契機。
  4. Mecha 能夠以聲明式的方式進行配置和控制,這很是符合雲原生的理念,一樣也使得 API 更關注於能力自己,而不是能力如何配置。
  5. 應用須要的能力如此之多(參見上面的圖:分佈式應用的四大需求),若是每一個能力都對應一個代理(無論是 Node 仍是 Sidecar),數量會很是誇張,帶來的運維壓力會很可怕。所以,如 Mecha 這個名字暗示的,運行時應該是整套的形式提供能力,而不是分散。

若是用一句話來總結,那麼我認爲 Mecha 的本質應該是:

「面向應用的分佈式能力抽象層」

如 Service Mesh 的本質是服務間通信的抽象層同樣,Mecha 的本質是應用須要的各類分佈式能力和原語,包括但不限於服務間通信。

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

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

Mecha 的優點和將來

做者指出:Mecha 的好處是業務邏輯和愈來愈多的分佈式系統問題之間的鬆耦合。

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

coupling-in-different-architectures

其實思路和 Service Mesh 是一脈相承的,只是覆蓋的分佈式能力更普遍一些。

有一個問題: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 的功能和定位,下面這一張圖就能夠歸納了:

dapr-overview

  • 最底下基礎設施是各類雲平臺(主流公有云都支持)或者邊緣環境;
  • 其上是 Dapr 提供的分佈式能力,Dapr 稱之爲「building block」;
  • 這些 building block 的能力,以統一的 API(支持 HTTP 和 gRPC)對外提供服務;
  • 應用能夠用各類語言編寫,而後經過 Dapr 提供的 API 使用這些能力,Dapr 也提供客戶端類庫來簡化對 API 的調用,實現了多語言的支持;

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

dapr-building-block

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

Dapr 的 API 例子

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

以 Service Invocation / 服務調用爲例:

service-invocation

部署和調用方式與 Service Mesh/ Istio 極爲類似,可是,差異在於:Dapr 是以提供 API 的方式提供 API 背後的能力,而不是提供提供協議代理的方式。

上圖,1 是 ServiceA 發起請求來調用一個遠程服務。其 HTTP request 以下所示:

POST/GET/PUT/DELETE http://localhost:<daprPort>/v1.0/invoke/<appId>/method/<method-name>

其中:

  • 參數 daprPort 是 Dapr Runtime 啓動的監聽端口,用來接受應用的 outbound 請求;
  • 參數 appId 是遠程應用在 Darp 中的關聯 ID,每一個註冊到 Dapr 的應用都有一個惟一的 appId;
  • 參數 method-name 是要調用的遠程應用的方法名或者 URL;

負載能夠存放在 HTTP body 中隨請求發送,如 json。

注意,雖然都是提供相同的功能,這裏體現了 Dapr(或者說背後的 Mecha)和 Service Mesh 在方式上的差別:暴露 API 仍是代理通信協議。

咱們看一個更明顯的例子,Dapr 提供的 「publish/subscriptions」 能力,讓應用能夠方便的發佈消息,或者訂閱主題並接收消息。下圖是應用發佈消息,請求直接發給 Dapr 便可:

publish

例子中,參數 topic 指定了消息要發往的主題(例子中是  deathStarStatus)。後續 Dapr 會完成將消息入 queue,而後推送到訂閱了該 topic 的應用。接收消息的方式也相似,不過此次是 Darp 主動發起:

subscribe

  1. Dapr 首先會請求應用,諮詢應用須要訂閱那些主題(topic),如例子中應用返回的的 TopicA / TopicB;
  2. Dapr 實現主題訂閱,在接收到消息以後,再把消息發送給應用,經過 URL 參數的不一樣來區分不一樣的主題;

注意在這個調用期間,不管是收發消息,應用徹底不用理會底層 pub/sub 的實現機制(好比是 Kafka,仍是RocketMQ,仍是其餘公有云提供的消息機制),也徹底不用引入該實現機制的客戶端 SDK,只是簡單的使用 Darp定義的 API 便可,從而實現了和底層的解耦,以及「廠商不綁定」。

爲了進一步簡化調用的過程(畢竟發一個最簡單的 HTTP GET 請求也要應用實現 HTTP 協議的調用/鏈接池管理等),Dapr 提供了各個語言的 SDK,如 Java / Go / Python / dotNET / JavaScript / cpp / Rust 。另外同時提供 HTTP 客戶端和 gRPC 客戶端。

咱們以 Java 爲例,Java 的 client API 接口定義以下:

public interface DaprClient {  
   Mono<Void> publishEvent(String topic, Object event);
   Mono<Void> 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架構出現和發展的原動力。

  1. Mecha 強調是「提供能力」,而不是通信代理。

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

在Service Mesh 下,不存在這個需求:Service Mesh 提供的是服務間通信能力,這個能力是由 Sidecar 來提供,沒有其餘更底層的實現,不存在隔離和替換的可能。受服務通信協議和報文 schema 的限制,Service Mesh 只能作請求的「轉發」,能力聚焦在「如何轉發」上,沒有其餘須要隔離和替代的能力。

當 Mecha 把能力擴展到 Servic Mesh 以外時,不少能力是由外部系統提供:好比 pub-sub 能力能夠由不一樣的 Message Queue 實現;狀態管理能力能夠鏈接不一樣的 Key-Value 實現。此時能力的隔離性和可替代性就成爲關鍵需求:解耦應用和能力實現,允許 Mecha 替換底層實現(進而實現供應商不鎖定等)。

  1. 不強求「零侵入」 。

在 Service Mesh 中,「零侵入」是一個很是強調的特性,爲此不惜引入 iptables 等流量劫持方案。「零侵入」在某些特殊場景下會發揮巨大的優點,如舊有應用不作改造的前提下接入 Service Mesh。好處天然不言而喻,但零侵入也有自身的限制:客戶端必須能發出符合服務器端要求的網絡通信請求,這個過程外部沒法插手。

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

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

  1. 不限定 Sidecar 部署 。

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

  • 邊緣網絡、IoT 場景:資源很是有限,不適合啓動太多 Sidecar;
  • FaaS 場景:應用自身足夠輕量,甚至比 Sidecar 還要輕量;
  • Serverless 場景:Scale to Zero 時,對冷啓動速度有嚴格要求,Sidecar 的啓動和初始化可能拖累應用啓動速度;

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

  1. 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 的精髓,要從上面這句名言開始:

  1. 在 Mecha 下,爲了實現解耦可替換, Runtime 隔離了底層實現,所以演變爲:"Program to an Runtime, not an implementation."
  2. 考慮到 Runtime 無論是部署爲 Sidecar 模式,仍是部署爲 Node 模式,都是 Localhost,所以有: 「Program to an Localhost, not an implementation.」
  3. 爲了簡化開發,Mecha 仍是會提供輕量級 SDK,提供 API 做爲能力的抽象:「Program to an API, not an implementation.」
  4. 考慮到 API 一般是以 interface 的形式提供,所以繞了一圈,Mecha 最後仍是回到原點:「Program to an interface, not an implementation.」

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

mecha-core

  • 在 Mecha下,MicroLogic(也就是業務邏輯的代碼實現)不允許直接使用底層實現提供的分佈式能力;
  • Mecha Runtime 將爲 Micro Logic 提供分佈式能力,同時隔離應用和底層實現;
  • 爲了方便使用,提供輕量級 SDK,其中的 API 層實現了分佈式能力的抽象,應用只需面向 API 編程;
  • 輕量級 SDK 和 Mecah Runtime 配合,完成對底層實現的解耦和可替換;

Mecha 的實現原則

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

  1. Runtime 是主力,要作厚;
  2. 輕量級 SDK 主要是給 Runtime 打配合,要作薄;

mecha-implementation

具體的職責劃分:

  • 輕量級 SDK:實現多語言接入,低侵入(但不追求零侵入);
  • API 接口:由輕量級 SDK 中提供統一,目標社區化+標準化,給開發者提供一致的編程體驗,同時提供可移植性;
  • 應用:輕量級 SDK/Runtime 配合,提供各類分佈式能力,應用無感,只需簡單使用 API,不耦合底層實現;

在 Mecha 架構中,Runtime 天然是整個架構的核心,扮演相似 Service Mesh 中數據平面的角色:

  • 全部分佈式能力使用的過程(包括訪問內部生態體系和訪問外部系統)都被 Runtime 接管和屏蔽實現;
  • 經過 CRD/控制平面實現聲明式配置和管理(相似 Service Mesh);
  • 部署方式上 Runtime 能夠部署爲 Sidecar 模式,或者 Node 模式,取決於具體需求,不強制;
備註:Mecha 有很是多的能力,實現上也有很是多的細節,這裏先作一個 High Level 的概述。細節後面會有一系列文章一一覆蓋,歡迎多交流討論。

Mecha 總結

大概是在3月初,當時我第一次閱讀 「Multi-Runtime Microservices Architecture」 這篇文章,有一種豁然開朗的感受,尤爲是有不少以前在反覆考慮和權衡可是下不告終論的問題,在這個文章中獲得了清晰的解答。可謂受益不淺。

在 Service Mesh 探索和實踐的這三年中,遇到不少問題,有不少以前沒有想到過的問題浮現。好比,之前一直以爲 Service Mesh 中引入 Sidecar 帶來的最大麻煩會是性能,但實際上,從目前的實踐看,Sidecar 引入後帶來的維護代價纔是更使人頭疼的事情,相比之下 Sidecar 引入帶來的性能損失顯得無傷大雅。

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

  1. Mecha 是雲原生化和 Mesh 化的必然趨勢:雲原生在繼續發展,應用須要的分佈式能力須要繼續下沉,愈來愈多的能力會以 Sidecar 的形式出現,這是大勢所趨。但不可能出現一個應用部署十幾個 Sidecar 的局面,這會是運維地獄。所以,必然須要出現新的形態來解決 Sidecar 過多的問題,合併爲一個或者多個 Sidecar 就會成爲必然。
  2. Mecha 是 Service Mesh 模式的天然進化版本:Service Mesh 落地實踐三年了,效果一直並不理想,到了該反思檢討的時候了;並且 Mecha 的範圍也遠不止服務間通信,新的需求下應該有新的思考和突破。Service Mesh 現有的固定模式,在 Mecha 下能夠嘗試打破以探索新的方式:沒必要拘泥於 Sidecar,試試 Node 模式;沒必要拘泥於通信協議轉發,試試 Runtime 提供能力解耦底層實現;沒必要拘泥於零侵入,試試在應用中保留一個足夠輕的輕量級 SDK。

正如曾有說法,說「微服務是 SOA 實踐中正確的部分(the Good Part)」,我但願在 Mecha 的探索和實踐中,可以從 Service Mesh 的實踐中吸收成功的經驗和失敗的教訓,但願 Mecha 也能成爲 Service Mesh 的 Good Part。但願在雲原生的演進路線中,Mecha 能夠繼微服務和 Service Mesh以後,成爲雲原生落地實踐的下一站。

回到現實,目前 Mecha 和 Multi-Runtime 仍是一個很是新的想法,Dapr 項目也纔剛剛起步,Mecha 要探索的道路還很漫長,一切都還須要摸索着前進。

附錄:參考資料

在文章的最後,特別鳴謝 「Multi-Runtime Microservices Architecture」一文的做者 「Bilgin Ibryam」,我很是承認這篇文章中的思想和理念,分析概括的很是到位,提煉和昇華的能力使人佩服。

做者介紹:
Bilgin Ibryam
Red Hat 的首席架構師,Apache Software Foundation 的 committer 和成員。開源的佈道師,博客做者,偶爾演講,著有書籍 Kubernetes Patterns 和 Camel Design Patterns 。

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

相關文章
相關標籤/搜索