MOSN 子項(xiàng)目 Layotto:開啟服務(wù)網(wǎng)格+應(yīng)用運(yùn)行時新篇章
作者簡介:
馬振軍,花名古今,在基礎(chǔ)架構(gòu)領(lǐng)域耕耘多年,對 Service Mesh 有深度實(shí)踐經(jīng)驗(yàn),目前在螞蟻集團(tuán)中間件團(tuán)隊(duì)負(fù)責(zé) MOSN、Layotto 等項(xiàng)目的開發(fā)工作。
Layotto 官方 GitHub 地址:
https://github.com/mosn/layotto
Service Mesh 在微服務(wù)領(lǐng)域已經(jīng)非常流行,越來越多的公司開始在內(nèi)部落地,螞蟻從 Service Mesh 剛出現(xiàn)的時候開始,就一直在這個方向上大力投入,到目前為止,內(nèi)部的 Mesh 方案已經(jīng)覆蓋數(shù)千個應(yīng)用、數(shù)十萬容器并且經(jīng)過了多次大促考驗(yàn),Service Mesh 帶來的業(yè)務(wù)解耦,平滑升級等優(yōu)勢大大提高了中間件的迭代效率。
在大規(guī)模落地以后,我們又遇到了新的問題,本文主要對 Service Mesh 在螞蟻內(nèi)部落地情況進(jìn)行回顧總結(jié),并分享對 Service Mesh 落地后遇到的新問題的解決方案。
一、Service Mesh 回顧與總結(jié)
A、Service Mesh 的初衷

在微服務(wù)架構(gòu)下,基礎(chǔ)架構(gòu)團(tuán)隊(duì)一般會為應(yīng)用提供一個封裝了各種服務(wù)治理能力的 SDK,這種做法雖然保障了應(yīng)用的正常運(yùn)行,但缺點(diǎn)也非常明顯,每次基礎(chǔ)架構(gòu)團(tuán)隊(duì)迭代一個新功能都需要業(yè)務(wù)方參與升級才能使用,尤其是 bugfix 版本,往往需要強(qiáng)推業(yè)務(wù)方升級,這里面的痛苦程度每一個基礎(chǔ)架構(gòu)團(tuán)隊(duì)成員都深有體會。
伴隨著升級的困難,隨之而來的就是應(yīng)用使用的 SDK 版本差別非常大,生產(chǎn)環(huán)境同時跑著各種版本的 SDK,這種現(xiàn)象又會讓新功能的迭代必須考慮各種兼容,就好像帶著枷鎖前進(jìn)一般,這樣隨著不斷迭代,會讓代碼維護(hù)非常困難,有些祖?zhèn)鬟壿嫺且徊恍⌒木蜁艨永铩?/span>
同時這種“重”SDK 的開發(fā)模式,導(dǎo)致異構(gòu)語言的治理能力非常薄弱,如果想為各種編程語言都提供一個功能完整且能持續(xù)迭代的 SDK 其中的成本可想而知。
18 年的時候,Service Mesh 在國內(nèi)持續(xù)火爆,這種架構(gòu)理念旨在把服務(wù)治理能力跟業(yè)務(wù)解耦,讓兩者通過進(jìn)程級別的通信方式進(jìn)行交互。在這種架構(gòu)模式下,服務(wù)治理能力從應(yīng)用中剝離,運(yùn)行在獨(dú)立的進(jìn)程中,迭代升級跟業(yè)務(wù)進(jìn)程無關(guān),這就可以讓各種服務(wù)治理能力快速迭代,并且由于升級成本低,因此每個版本都可以全部升級,解決了歷史包袱問題,同時 SDK 變“輕”直接降低了異構(gòu)語言的治理門檻,再也不用為需要給各個語言開發(fā)相同服務(wù)治理能力的 SDK 頭疼了。
B、Service Mesh 落地現(xiàn)狀

螞蟻很快意識到了 Service Mesh 的價值,全力投入到這個方向,用 Go 語言開發(fā)了 MOSN 這樣可以對標(biāo) envoy 的優(yōu)秀數(shù)據(jù)面,全權(quán)負(fù)責(zé)服務(wù)路由,負(fù)載均衡,熔斷限流等能力的建設(shè),大大加快了公司內(nèi)部落地 Service Mesh 的進(jìn)度。
現(xiàn)在 MOSN 在螞蟻內(nèi)部已經(jīng)覆蓋了數(shù)千個應(yīng)用、數(shù)十萬容器,新創(chuàng)建的應(yīng)用默認(rèn)接入 MOSN,形成閉環(huán)。而且在大家最關(guān)心的資源占用、性能損耗方面 MOSN 也交出了一份讓人滿意的答卷:
1. RT 小于 0.2ms
2. CPU 占用增加 0%~2%
3. 內(nèi)存消耗增長小于 15M
由于 Service Mesh 降低了異構(gòu)語言的服務(wù)治理門檻,NodeJS、C++等異構(gòu)技術(shù)棧也在持續(xù)接入到 MOSN 中。
在看到 RPC 能力 Mesh 化帶來的巨大收益之后,螞蟻內(nèi)部還把 MQ,Cache,Config 等中間件能力都進(jìn)行了 Mesh 化改造,下沉到 MOSN,提高了中間件產(chǎn)品整體的迭代效率。
C、新的挑戰(zhàn)
1. 應(yīng)用跟基礎(chǔ)設(shè)施強(qiáng)綁定

一個現(xiàn)代分布式應(yīng)用,往往會同時依賴 RPC、Cache、MQ、Config 等各種分布式能力來完成業(yè)務(wù)邏輯的處理。
當(dāng)初看到 RPC 下沉的紅利以后,其他各種能力也都快速下沉。初期,大家都會以自己最熟悉的方式來開發(fā),這就導(dǎo)致沒有統(tǒng)一的規(guī)劃管理,如上圖所示,應(yīng)用依賴了各種基礎(chǔ)設(shè)施的 SDK,而每種 SDK 又以自己特有的方式跟 MOSN 進(jìn)行交互,使用的往往都是由原生基礎(chǔ)設(shè)施提供的私有協(xié)議,這直接導(dǎo)致了復(fù)雜的中間件能力雖然下沉,但應(yīng)用本質(zhì)上還是被綁定到了基礎(chǔ)設(shè)施,比如想把緩存從 Redis 遷移到 Memcache 的話,仍舊需要業(yè)務(wù)方升級 SDK,這種問題在應(yīng)用上云的大趨勢下表現(xiàn)的更為突出,試想一下,如果一個應(yīng)用要部署在云上,由于該應(yīng)用依賴了各種基礎(chǔ)設(shè)施,勢必要先把整個基礎(chǔ)設(shè)施搬到云上才能讓應(yīng)用順利部署,這其中的成本可想而知。
因此如何讓應(yīng)用跟基礎(chǔ)設(shè)施解綁,使其具備可移植能力,能夠無感知跨平臺部署是我們面臨的第一個問題。
2. 異構(gòu)語言接入成本高

事實(shí)證明 Service Mesh 確實(shí)降低了異構(gòu)語言的接入門檻,但在越來越多的基礎(chǔ)能力下沉到 MOSN 以后,我們逐漸意識到為了讓應(yīng)用跟 MOSN 交互,各種 SDK 里都需要對通信協(xié)議,序列化協(xié)議進(jìn)行開發(fā),如果再加上需要對各種異構(gòu)語言都提供相同的功能,那維護(hù)難度就會成倍上漲,
Service Mesh 讓重 SDK 成為了歷史,但對于現(xiàn)在各種編程語言百花齊放、各種應(yīng)用又強(qiáng)依賴基礎(chǔ)設(shè)施的場景來說,我們發(fā)現(xiàn)現(xiàn)有的 SDK 還不夠薄,異構(gòu)語言接入的門檻還不夠低,如何進(jìn)一步降低異構(gòu)語言的接入門檻是我們面臨的第二個問題。
二、Multi Runtime 理論概述
A、什么是 Runtime?

20 年初的時候,Bilgin lbryam 發(fā)表了一篇名為
Multi-Runtime Microservices Architecture
的文章,里面對微服務(wù)架構(gòu)下一階段的形態(tài)進(jìn)行了討論。
如上圖所示,作者把分布式服務(wù)的需求進(jìn)行了抽象,總共分為了四大類:
1. 生命周期(Lifecycle)
2. 網(wǎng)絡(luò)(Networking)
可靠的網(wǎng)絡(luò)是微服務(wù)之間進(jìn)行通信的基本保障,Service Mesh 正是在這方面做了嘗試,目前 MOSN、envoy 等流行的數(shù)據(jù)面的穩(wěn)定性、實(shí)用性都已經(jīng)得到了充分驗(yàn)證。
3. 狀態(tài)(State)
分布式系統(tǒng)需要的服務(wù)編排,工作流,分布式單例,調(diào)度,冪等性,有狀態(tài)的錯誤恢復(fù),緩存等操作都可以統(tǒng)一歸為底層的狀態(tài)管理。
4. 綁定(Binding)
在分布式系統(tǒng)中,不僅需要跟其他系統(tǒng)通信,還需要集成各種外部系統(tǒng),因此對于協(xié)議轉(zhuǎn)換,多種交互模型、錯誤恢復(fù)流程等功能也都有強(qiáng)依賴。
明確了需求以后,借鑒了 Service Mesh 的思路,作者對分布式服務(wù)的架構(gòu)演進(jìn)進(jìn)行了如下總結(jié):

第一階段就是把各種基礎(chǔ)設(shè)施能力從應(yīng)用中剝離解耦,通通變成獨(dú)立 sidecar 模型伴隨著應(yīng)用一起運(yùn)行。
第二階段是把各種 sidecar 提供的能力統(tǒng)一抽象成若干個 Runtime,這樣應(yīng)用從面向基礎(chǔ)組件開發(fā)就演變成了面向各種分布式能力開發(fā),徹底屏蔽掉了底層實(shí)現(xiàn)細(xì)節(jié),而且由于是面向能力,除了調(diào)用提供各種能力的 API 之外,應(yīng)用再也不需要依賴各種各樣基礎(chǔ)設(shè)施提供的 SDK 了。
作者的思路跟我們希望解決的問題一致,我們決定使用 Runtime 的理念來解決 Service Mesh 發(fā)展到現(xiàn)在所遇到的新問題。
B、Service Mesh vs Runtime

為了讓大家對 Runtime 有一個更加清晰的認(rèn)識,上圖針對 Service Mesh 跟 Runtime 兩種理念的定位、交互方式、通信協(xié)議以及能力豐富度進(jìn)行了總結(jié),可以看到相比 Service Mesh 而言,Runtime 提供了語義明確、能力豐富的 API,可以讓應(yīng)用跟它的交互變得更加簡單直接。
三、MOSN 子項(xiàng)目 Layotto
A、dapr 調(diào)研

dapr 是社區(qū)中一款知名的 Runtime 實(shí)現(xiàn)產(chǎn)品,活躍度也比較高,因此我們首先調(diào)研了 dapr 的情況,發(fā)現(xiàn) dapr 具有如下優(yōu)勢:
1. 提供了多種分布式能力,API 定義清晰,基本能滿足一般的使用場景。
2. 針對各種能力都提供了不同的實(shí)現(xiàn)組件,基本涵蓋了常用的中間件產(chǎn)品,用戶可以根據(jù)需要自由選擇。
當(dāng)考慮如何在公司內(nèi)部落地 dapr 時,我們提出了兩種方案,如上圖所示:
1. 替換:廢棄掉現(xiàn)在的 MOSN,用 dapr 進(jìn)行替換,這種方案存在兩個問題:
a. dapr 雖然提供了很多分布式能力,但目前并不具備 Service Mesh 包含的豐富的服務(wù)治理能力。
b. MOSN 在公司內(nèi)部已經(jīng)大規(guī)模落地,并且經(jīng)過了多次大促考驗(yàn),直接用 dapr 來替換 MOSN 穩(wěn)定性有待驗(yàn)證。
2. 共存:新增一個 dapr 容器,跟 MOSN 以兩個 sidecar 的模式進(jìn)行部署。這種方案同樣存在兩個問題:
a. 引入一個新的 sidecar,我們就需要考慮它配套的升級、監(jiān)控、注入等等事情,運(yùn)維成本飆升。
b. 多維護(hù)一個容器意味著多了一層掛掉的風(fēng)險,這會降低現(xiàn)在的系統(tǒng)可用性。
同樣的,如果你目前正在使用 envoy 作為數(shù)據(jù)面,也會面臨上述問題。
因此我們希望把 Runtime 跟 Service Mesh 兩者結(jié)合起來,通過一個完整的 sidecar 進(jìn)行部署,在保證穩(wěn)定性、運(yùn)維成本不變的前提下,最大程度復(fù)用現(xiàn)有的各種 Mesh 能力。此外我們還希望這部分 Runtime 能力除了跟 MOSN 結(jié)合起來之外,未來也可以跟 envoy 結(jié)合起來,解決更多場景中的問題,Layotto 就是在這樣的背景下誕生。
B、Layotto 架構(gòu)

如上圖所示,Layotto 是構(gòu)建在 MOSN 之上,在下層對接了各種基礎(chǔ)設(shè)施,向上層應(yīng)用提供了統(tǒng)一的,具有各種各樣分布式能力的標(biāo)準(zhǔn) API。對于接入 Layotto 的應(yīng)用來說,開發(fā)者不再需要關(guān)心底層各種組件的實(shí)現(xiàn)差異,只需要關(guān)注應(yīng)用需要什么樣的能力,然后調(diào)用對應(yīng)能力的 API 即可,這樣可以徹底跟底層基礎(chǔ)設(shè)施解綁。
對應(yīng)用來說,交互分為兩塊,一個是作為 gRPC Client 調(diào)用 Layotto 的標(biāo)準(zhǔn) API,一個是作為 gRPC Server 來實(shí)現(xiàn) Layotto 的回調(diào),得利于gRPC 優(yōu)秀的跨語言支持能力,應(yīng)用不再需要關(guān)心通信、序列化等細(xì)節(jié)問題,進(jìn)一步降低了異構(gòu)技術(shù)棧的使用門檻。
除了面向應(yīng)用,Layotto 也向運(yùn)維平臺提供了統(tǒng)一的接口,這些接口可以把應(yīng)用跟 sidecar 的運(yùn)行狀態(tài)反饋給運(yùn)維平臺,方便 SRE 同學(xué)及時了解應(yīng)用的運(yùn)行狀態(tài)并針對不同狀態(tài)做出不同的舉措,該功能考慮到跟 k8s 等已有的平臺集成,因此我們提供了 HTTP 協(xié)議的訪問方式。
除了 Layotto 本身設(shè)計以外,項(xiàng)目還涉及兩塊標(biāo)準(zhǔn)化建設(shè),首先想要制定一套語義明確,適用場景廣泛的 API 并不是一件容易的事情,為此我們跟阿里、 dapr 社區(qū)進(jìn)行了合作,希望能夠推進(jìn) Runtime API 標(biāo)準(zhǔn)化的建設(shè),其次對于 dapr 社區(qū)已經(jīng)實(shí)現(xiàn)的各種能力的 Components 來說,我們的原則是優(yōu)先復(fù)用、其次開發(fā),盡量不把精力浪費(fèi)在已有的組件上面,重復(fù)造輪子。
最后 Layotto 目前雖然是構(gòu)建在 MOSN 之上,未來我們希望 Layotto 可以跑在 envoy 上,這樣只要應(yīng)用接入了 Service Mesh,無論數(shù)據(jù)面使用的是 MOSN 還是 envoy,都可以在上面增加 Runtime能力。
C、Layotto 的移植性

如上圖所示,一旦完成 Runtime API 的標(biāo)準(zhǔn)化建設(shè),接入 Layotto 的應(yīng)用天然具備了可移植性,應(yīng)用不需要任何改造就可以在私有云以及各種公有云上部署,并且由于使用的是標(biāo)準(zhǔn) API,應(yīng)用也可以無需任何改造就在 Layotto 跟 dapr 之間自由切換。
D、名字含義

從上面的架構(gòu)圖可以看出,Layotto 項(xiàng)目本身是希望屏蔽基礎(chǔ)設(shè)施的實(shí)現(xiàn)細(xì)節(jié),向上層應(yīng)用統(tǒng)一提供各種分布式能力,這種做法就好像是在應(yīng)用跟基礎(chǔ)設(shè)施之間加了一層抽象,因此我們借鑒了 OSI 對網(wǎng)絡(luò)定義七層模型的思路,希望 Layotto 可以作為第八層對應(yīng)用提供服務(wù),otto 是意大利語中8的意思,Layer otto 就是第八層的意思,簡化了一下變成了 Layotto,同時項(xiàng)目代號 L8,也是第八層的意思,這個代號也是設(shè)計我們項(xiàng)目 LOGO 時靈感的來源。
介紹完項(xiàng)目的整體情況,下面對其中四個主要功能的實(shí)現(xiàn)細(xì)節(jié)進(jìn)行說明。
E、配置原語

首先是分布式系統(tǒng)中經(jīng)常使用的配置功能,應(yīng)用一般使用配置中心來做開關(guān)或者動態(tài)調(diào)整應(yīng)用的運(yùn)行狀態(tài)。Layotto 中配置模塊的實(shí)現(xiàn)包括兩部分,一個是對如何定義配置這種能力的 API 的思考,一個是具體的實(shí)現(xiàn),下面逐個來看。
想要定義一個能滿足大部分實(shí)際生產(chǎn)訴求的配置 API 并不是一件容易的事,dapr 目前也缺失這個能力,因此我們跟阿里以及 dapr 社區(qū)一起合作,為如何定義一版合理的配置 API 進(jìn)行了激烈討論。
目前討論結(jié)果還沒有最終確定,因此 Layotto 是基于我們提給社區(qū)的第一版草案進(jìn)行實(shí)現(xiàn),下面對我們的草案進(jìn)行簡要說明。
我們先定義了一般配置所需的基本元素:
1. appId:表示配置屬于哪個應(yīng)用
2. key:配置的 key
3. content:配置的值
4. group:配置所屬的分組,如果一個 appId 下面的配置過多,我們可以給這些配置進(jìn)行分組歸類,便于維護(hù)。
此外我們追加了兩種高級特性,用來適配更加復(fù)雜的配置使用場景:
1. label,用于給配置打標(biāo)簽,比如該配置屬于哪個環(huán)境,在進(jìn)行配置查詢的時候,我們會使用 label + key 來查詢配置。
2. tags,用戶給配置追加的一些附加信息,如描述信息、創(chuàng)建者信息,最后修改時間等等,方便配置的管理,審計等。
對于上述定義的配置 API 的具體實(shí)現(xiàn),目前支持查詢、訂閱、刪除、創(chuàng)建、修改五種操作,其中訂閱配置變更后的推送使用的是 gRPC 的 stream 特性,而底層實(shí)現(xiàn)這些配置能力的組件,我們選擇了國內(nèi)流行的 apollo,后面也會根據(jù)需求增加其他實(shí)現(xiàn)。
F、Pub/Sub 原語

對于 Pub/Sub 能力的支持,我們調(diào)研了 dapr 現(xiàn)在的實(shí)現(xiàn),發(fā)現(xiàn)基本上已經(jīng)可以滿足我們的需求,因此我們直接復(fù)用了 dapr 的 API 以及 components,只是在 Layotto 里面做了適配,這為我們節(jié)省了大量的重復(fù)勞動,我們希望跟 dapr 社區(qū)保持一種合作共建的思路,而不是重復(fù)造輪子。
其中 Pub 功能是 App 調(diào)用 Layotto 提供的 PublishEvent 接口,而 Sub 功能則是應(yīng)用通過 gRPC Server 的形式實(shí)現(xiàn)了 ListTopicSubscriptions 跟 OnTopicEvent 兩個接口,一個用來告訴 Layotto 應(yīng)用需要訂閱哪些 topic,一個用于接收 topic 變化時 Layotto 的回調(diào)事件。
dapr 對于 Pub/Sub 的定義基本滿足我們的需求,但在某些場景下仍有不足,dapr 采用了 CloudEvent 標(biāo)準(zhǔn),因此 Pub 接口沒有返回值,這無法滿足我們生產(chǎn)場景中要求 Pub 消息以后服務(wù)端返回對應(yīng)的 messageID 的需求,這一點(diǎn)我們已經(jīng)把需求提交給了 dapr 社區(qū),還在等待反饋,考慮到社區(qū)異步協(xié)作的機(jī)制,我們可能會先社區(qū)一步增加返回結(jié)果,然后再跟社區(qū)探討一種更好的兼容方案。
G、RPC 原語

RPC 的能力大家不會陌生,這可能是微服務(wù)架構(gòu)下最最基礎(chǔ)的需求,對于 RPC 接口的定義,我們同樣參考了 dapr 社區(qū)的定義,發(fā)現(xiàn)完全可以滿足我們的需求,因此接口定義就直接復(fù)用 dapr 的,但目前 dapr 提供的 RPC 實(shí)現(xiàn)方案還比較薄弱,而 MOSN 經(jīng)過多年迭代,能力已經(jīng)非常成熟完善,因此我們大膽把 Runtime 跟 Service Mesh 兩種思路結(jié)合在一起,把 MOSN 本身作為我們實(shí)現(xiàn) RPC 能力的一個 Component,這樣 Layotto 在收到 RPC 請求以后交給 MOSN 進(jìn)行實(shí)際數(shù)據(jù)傳輸,這種方案可以通過 istio 動態(tài)改變路由規(guī)則,降級限流等等設(shè)置,相當(dāng)于直接復(fù)用了 Service Mesh 的各種能力,這也說明 Runtime 不是要推翻 Service Mesh,而是要在此基礎(chǔ)上繼續(xù)向前邁一步。
具體實(shí)現(xiàn)細(xì)節(jié)上,為了更好的跟 MOSN 融合,我們在 RPC 的實(shí)現(xiàn)上面加了一層 Channel,默認(rèn)支持dubbo,bolt,http 三種常見的 RPC 協(xié)議,如果仍然不能滿足用戶場景,我們還追加了 Before/After 兩種 Filter,可以讓用戶做自定義擴(kuò)展,實(shí)現(xiàn)協(xié)議轉(zhuǎn)換等需求。
H、Actuator 原語

在實(shí)際生產(chǎn)環(huán)境中,除了應(yīng)用所需要的各種分布式能力以外,PaaS 等運(yùn)維平臺往往需要了解應(yīng)用的運(yùn)行狀態(tài),基于這種需求,我們抽象了一套 Actuator 接口,目前 dapr 還沒有提供這方面的能力,因此我們根據(jù)內(nèi)部的需求場景進(jìn)行了設(shè)計,旨在把應(yīng)用在啟動期、運(yùn)行期等階段各種各樣的信息暴露出去,方便 PaaS 了解應(yīng)用的運(yùn)行情況。
Layotto 把暴露信息分為兩大類:
1. Health:該模塊判斷應(yīng)用當(dāng)前運(yùn)行狀態(tài)是否健康,比如某個強(qiáng)依賴的組件如果初始化失敗就需要表示為非健康狀態(tài),而對于健康檢查的類型我們參考了 k8s,分為:
a. Readiness:表示應(yīng)用啟動完成,可以開始處理請求。
b. Liveness:表示應(yīng)用存活狀態(tài),如果不存活則需要切流等。
2. Info:該模塊預(yù)期會暴露應(yīng)用的一些依賴信息出去,如應(yīng)用依賴的服務(wù),訂閱的配置等等,用于排查問題。
Health 對外暴露的健康狀態(tài)分為以下三種:
1. INIT:表示應(yīng)用還在啟動中,如果應(yīng)用發(fā)布過程中返回該值,這個時候 PaaS 平臺應(yīng)該繼續(xù)等待應(yīng)用完成啟動。
2. UP:表示應(yīng)用啟動正常,如果應(yīng)用發(fā)布過程中返回該值,意味著 PasS 平臺可以開始放入流量。
3. DOWN:表示應(yīng)用啟動失敗,如果應(yīng)用發(fā)布過程中返回該值,意味著 PaaS 需要停止發(fā)布并通知應(yīng)用 owner。
到這里關(guān)于 Layotto 目前在 Runtime 方向上的探索基本講完了,我們通過定義明確語義的 API,使用 gRPC 這種標(biāo)準(zhǔn)的交互協(xié)議解決了目前面臨的基礎(chǔ)設(shè)施強(qiáng)綁定、異構(gòu)語言接入成本高兩大問題。隨著未來 API 標(biāo)準(zhǔn)化的建設(shè),一方面可以讓接入 Layotto 的應(yīng)用無感知的在各種私有云、公有云上面部署,另一方面也能讓應(yīng)用在 Layotto,dapr 之間自由切換,提高研發(fā)效率。
目前 Serverless 領(lǐng)域也是百花齊放,沒有一種統(tǒng)一的解決方案,因此 Layotto 除了在上述 Runtime 方向上的投入以外,還在 Serverless 方向上也進(jìn)行了一些嘗試,下面就嘗試方案進(jìn)行介紹。
四、WebAssembly 的探索
A、WebAssembly 簡介

WebAssembly,簡稱 WASM,是一個二進(jìn)制指令集,最初是跑在瀏覽器上來解決 JavaScript 的性能問題,但由于它良好的安全性,隔離性以及語言無關(guān)性等優(yōu)秀特性,很快人們便開始讓它跑在瀏覽器之外的地方,隨著 WASI 定義的出現(xiàn),只需要一個 WASM 運(yùn)行時,就可以讓 WASM 文件隨處執(zhí)行。
既然 WebAssembly 可以在瀏覽器以外的地方運(yùn)行,那么我們是否能把它用在 Serverless 領(lǐng)域?目前已經(jīng)有人在這方面做了一些嘗試,不過如果這種方案真的想落地的話,首先要考慮的就是如何解決運(yùn)行中的 WebAssembly 對各種基礎(chǔ)設(shè)施的依賴問題。
B、WebAssembly 落地原理
目前 MOSN 通過集成 WASM Runtime 的方式讓 WASM 跑在 MOSN 上面,以此來滿足對 MOSN 做自定義擴(kuò)展的需求。同時,Layotto 也是構(gòu)建在 MOSN 之上,因此我們考慮把二者結(jié)合在一起,實(shí)現(xiàn)方案如下圖所示:

開發(fā)者可以使用 Go/C++/Rust 等各種各樣自己喜歡的語言來開發(fā)應(yīng)用代碼,然后把它們編譯成 WASM 文件跑在 MOSN 上面,當(dāng) WASM 形態(tài)的應(yīng)用在處理請求的過程中需要依賴各種分布式能力時就可以通過本地函數(shù)調(diào)用的方式調(diào)用 Layotto 提供的標(biāo)準(zhǔn) API,這樣直接解決了 WASM 形態(tài)應(yīng)用的依賴問題。
目前 Layotto 提供了 Go 跟 Rust 版 WASM 的實(shí)現(xiàn),雖然只支持 demo 級功能,但已經(jīng)足夠讓我們看到這種方案的潛在價值。
此外,WASM 社區(qū)目前還處于初期階段,有很多地方需要完善,我們也給社區(qū)提交了一些 PR共同建設(shè),為 WASM 技術(shù)的落地添磚加瓦。
C、WebAssembly 落地展望

雖然現(xiàn)在 Layotto 中對 WASM 的使用還處于試驗(yàn)階段,但我們希望它最終可以成為 Serverless 的一種實(shí)現(xiàn)形態(tài),如上圖所示,應(yīng)用通過各種編程語言開發(fā),然后統(tǒng)一編譯成 WASM 文件,最后跑在 Layotto+MOSN 上面,而對于應(yīng)用的運(yùn)維管理統(tǒng)一由 k8s、docker、prometheus 等產(chǎn)品負(fù)責(zé)。
五、社區(qū)規(guī)劃
最后來看下 Layotto 在社區(qū)的做的一些事情。
A、Layotto vs Dapr

上圖列出了 Layotto 跟 dapr 現(xiàn)有的能力對比,在 Layotto 的開發(fā)過程中,我們借鑒 dapr 的思路,始終以優(yōu)先復(fù)用、其次開發(fā)為原則,旨在達(dá)成共建的目標(biāo),而對于正在建設(shè)或者未來要建設(shè)的能力來說,我們計劃優(yōu)先在 Layotto 上落地,然后再提給社區(qū),合并到標(biāo)準(zhǔn) API,鑒于社區(qū)異步協(xié)作的機(jī)制,溝通成本較高,因此短期內(nèi)可能 Layotto 的 API 會先于社區(qū),但長期來看一定會統(tǒng)一。
B、API 共建計劃

關(guān)于如何定義一套標(biāo)準(zhǔn)的 API 以及如何讓 Layotto 可以跑在 envoy 上等等事項(xiàng),我們已經(jīng)在各個社區(qū)進(jìn)行了深入討論,并且以后也還會繼續(xù)推進(jìn)。
C、Roadmap

Layotto 在目前主要支持 RPC、Config、Pub/Sub、Actuator 四大功能,預(yù)計在九月會把精力投入到分布式鎖、State、可觀測性上面,十二月份會支持 Layotto 插件化,也就是讓它可以跑在 envoy 上,同時希望對 WebAssembly 的探索會有進(jìn)一步的產(chǎn)出。
D、正式開源

前面詳細(xì)介紹了 Layotto 項(xiàng)目,最重要的還是該項(xiàng)目今天作為 MOSN 的子項(xiàng)目正式開源,我們提供了詳細(xì)的文檔以及 demo 示例方便大家快速上手體驗(yàn)。
對于 API 標(biāo)準(zhǔn)化的建設(shè)是一件需要長期推動的事情,同時標(biāo)準(zhǔn)化意味著不是滿足一兩種場景,而是盡可能的適配大多數(shù)使用場景,為此我們希望更多的人可以參與到 Layotto 項(xiàng)目中,描述你的使用場景,討論 API 的定義方案,一起提交給社區(qū),最終達(dá)成 Write once, Run anywhere 的終極目標(biāo)!
Gopher China2021大會日程詳情來了!
點(diǎn)擊下方「閱讀原文」即可報名參加大會
