开启云原生 MOSN 新篇章 — 融合 Envoy 和 Golang 生态
注:本文是王發(fā)康(毅松)在 2021 GopherChina 上演講的文字稿,相關(guān)分享 PPT 可自行到 MOSN meetup 下載。
MOSN meetup 地址:
https://github.com/mosn/meetup
MOSN 官方 Github 地址:
https://github.com/mosn/mosn
GitHub 地址:???????????????????????????????????????https://github.com/sofastack???????????????????????????????????????
?????????????????????????????????????????????
前言
MOSN 在 Service Mesh 領(lǐng)域作為東西向服務(wù)治理網(wǎng)絡(luò)在螞蟻集團(tuán)雙 11 、春節(jié)紅包等活動(dòng)及開(kāi)源社區(qū)都得到了一定實(shí)踐。為了能夠讓社區(qū)用戶更好的享受到這一技術(shù)紅利,MOSN 從 2018 年開(kāi)源以來(lái)在社區(qū)開(kāi)發(fā)者、用戶的共同努力下,使得 MOSN 在云原生演進(jìn)方面做了很多探索和實(shí)踐。比如 Istio 下另一個(gè)數(shù)據(jù)面 — MOSN、WebAssembly 在 MOSN 中的探索與實(shí)踐、MOSN 子項(xiàng)目 Layotto:開(kāi)啟服務(wù)網(wǎng)格+應(yīng)用運(yùn)行時(shí)新篇章、MOSN 基于 Sentinel 的限流實(shí)踐、MOSN 中玩轉(zhuǎn) Dubbo-go 等周邊生態(tài)展開(kāi)合作。
Istio 下另一個(gè)數(shù)據(jù)面 — MOSN 文章鏈接:
https://istio.io/latest/blog/2020/mosn-proxy
MOSN 基于 Sentinel 的限流實(shí)踐文章鏈接:
https://github.com/mosn/mosn/pull/1111
MOSN 中玩轉(zhuǎn) Dubbo-go 等周邊生態(tài)展開(kāi)合作文章鏈接:
https://mosn.io/blog/posts/mosn-dubbo-integrate/
2021 年為了更好的為業(yè)務(wù)提效,MOSN 開(kāi)啟了將云原生進(jìn)行到底的決心。本文介紹了 MOSN 在網(wǎng)絡(luò)擴(kuò)展層的思考和技術(shù)選型,以及最終是如何通過(guò)使用 Envoy 作為 MOSN 的網(wǎng)絡(luò)層擴(kuò)展,從而實(shí)現(xiàn) MOSN 和 Envoy 生態(tài)打通。使得網(wǎng)絡(luò)層具備 C++ 高性能的同時(shí),上層業(yè)務(wù)治理能力也能借助 GoLang 進(jìn)行高效的定制化開(kāi)發(fā)。
面臨的問(wèn)題及挑戰(zhàn)
一、社區(qū)生態(tài),如何最大化求同存異
最近幾年 Service Mesh 技術(shù)在云原生社區(qū)也是百花齊放,雖然 MOSN 在開(kāi)源社區(qū)也是備受開(kāi)發(fā)者的關(guān)注,但是 Envoy 經(jīng)過(guò)長(zhǎng)久的發(fā)展其社區(qū)的活躍度和用戶量的積累這點(diǎn)是不可忽略的。另外選擇 MOSN 的用戶都是看重其二次開(kāi)發(fā)的便捷性以及 GoLang 的生態(tài)豐富,選擇 Envoy 的用戶主要是看重其高性能的網(wǎng)絡(luò)處理能力及社區(qū)的活躍度。那我們是否能夠通過(guò)技術(shù)的手段將其二者優(yōu)勢(shì)融為一體,發(fā)揮各自的特長(zhǎng),不要讓用戶顧此失彼。
二、單一的 Proxy,無(wú)法支撐其架構(gòu)的演進(jìn)
在 Proxy 層面,無(wú)論是 MOSN 還是 Envoy 都是在各自領(lǐng)域中發(fā)揮優(yōu)勢(shì)。隨著云原生技術(shù)的快速發(fā)展和成熟以及業(yè)務(wù)的增長(zhǎng),既要 Proxy 能夠具備高研發(fā)效能,還要具備高處理性能,而單一的 Proxy 已經(jīng)無(wú)法滿足當(dāng)前業(yè)務(wù)架構(gòu)上的持續(xù)演進(jìn)。
東西向和南北向數(shù)據(jù)面 Proxy 逐步統(tǒng)一:兩套數(shù)據(jù)面定位不同但功能上存在一定重疊,導(dǎo)致維護(hù)成本高,未來(lái)需要逐步收斂。這就要求 Proxy 不僅具備易擴(kuò)展性方便業(yè)務(wù)方擴(kuò)展東西向業(yè)務(wù)上的流量治理能力,而且還要具備抗高并發(fā)的能力滿足南北向高流量轉(zhuǎn)發(fā)。
Service Mesh 部署形態(tài)逐步向 Node 化架構(gòu)演進(jìn):Service Mesh 規(guī)模化后,由于多出的 Proxy 勢(shì)必會(huì)導(dǎo)致一定資源上的浪費(fèi),那在中心化和 Mesh 化之間做一次折中,即通過(guò) Node 化部署形態(tài)來(lái)解決。Node 化后就要求 Proxy 能夠高效、穩(wěn)定的承載多個(gè) POD 的流量治理。
Service Mesh 需要同時(shí)具備 Application Runtime 能力:雖然 Service Mesh 解決了微服務(wù)治理的痛點(diǎn),但在實(shí)際業(yè)務(wù)開(kāi)發(fā)中,緩存、數(shù)據(jù)庫(kù)、消息隊(duì)列、配置管理等,仍然需要維護(hù)一套重量級(jí)的 SDK 并且侵入應(yīng)用代碼。目前業(yè)界的解決方案是在 Service Mesh 的基礎(chǔ)上多引入一個(gè) Proxy 如 Dapr 來(lái)解決,這就導(dǎo)致應(yīng)用的 POD 需要維護(hù)多個(gè)容器,所以如何讓 Service Mesh 的 Proxy 具備快速?gòu)?fù)用 Dapr 能力成為解決該問(wèn)題的關(guān)鍵。
我們的思考
針對(duì)上述問(wèn)題分析過(guò)后,其實(shí)背后的原因是有共性的。比如將其統(tǒng)一為一個(gè) sidecar,如果單純的從一個(gè)數(shù)據(jù)面改為另一個(gè),那其中的改造成本是巨大的。那是否可以換個(gè)思路,為 MOSN 的網(wǎng)絡(luò)層增加可擴(kuò)展性,即可以讓 MOSN 的網(wǎng)絡(luò)處理直接下沉至 Envoy,同時(shí)將這個(gè)能力剝離出來(lái)成為 Envoy 在 GoLang 上的一個(gè)標(biāo)準(zhǔn)能力,這樣就能夠讓 Envoy 和 MOSN 互相復(fù)用已有的能力。二者相互融合,各取所長(zhǎng),使其同時(shí)具備高研發(fā)效能和處理性能高,自然而然就解決上述“單一的 Proxy,無(wú)法支撐架構(gòu)的演進(jìn)”和“社區(qū)生態(tài),如何最大化求同存異”所面臨的問(wèn)題。相互融合后,不僅融合了各種的優(yōu)勢(shì),而且也能夠把兩邊的生態(tài)打通,借此 MOSN 社區(qū)和 Envoy 社區(qū)能形成雙贏的局面。
方案調(diào)研與分析
知道當(dāng)前面臨問(wèn)題的原因后,便有了一個(gè)宏觀的解決方向。于是就對(duì)此展開(kāi)了相關(guān)調(diào)研,梳理了業(yè)界針對(duì)此問(wèn)題的一些解決方案,綜合各種方案的優(yōu)劣勢(shì)并結(jié)合螞蟻業(yè)務(wù)現(xiàn)狀以及開(kāi)源社區(qū)用戶的痛點(diǎn)進(jìn)行了分析和評(píng)估。
擴(kuò)展方案調(diào)研
擴(kuò)展方案評(píng)估
通過(guò)上述方案優(yōu)劣勢(shì)的對(duì)比以及評(píng)估,MOE(MOSN on Envoy) 相比 ext-proc 無(wú)需跨進(jìn)程 gRPC 通信,性能高,易管理;相比 Envoy WASM 擴(kuò)展無(wú)需網(wǎng)絡(luò) IO 操作轉(zhuǎn)換成本;相比 Lua 擴(kuò)展生態(tài)好、能復(fù)用現(xiàn)有的 SDK,對(duì)于處理上層業(yè)務(wù)更合適。
同時(shí)我們將 Envoy 中增加 GoLang 擴(kuò)展的這個(gè)方案也在 Envoy 社區(qū)進(jìn)行了討論,也得到了 Envoy 社區(qū) Maintainer 的贊同。其中依賴的技術(shù) CGO 是 GoLang 官方出品,該技術(shù)基本上在 GoLang 每個(gè) release notes 中都有提到,說(shuō)明也一直在維護(hù)的。另外業(yè)界也有很多項(xiàng)目在使用這項(xiàng)技術(shù)(比如:NanoVisor、Cilium、NginxUnit、Dragonboat、Badger、Go withOpenCV etc)其穩(wěn)定性已經(jīng)過(guò)一定的考驗(yàn)了,同時(shí)我們自己也測(cè)試了 CGO 自身的開(kāi)銷在 0.08 ~ 1.626 微秒,而且調(diào)用開(kāi)銷也是屬于線性增長(zhǎng)而非指數(shù)增長(zhǎng)趨勢(shì)。
所以綜合穩(wěn)定性、性能、改造成本以及社區(qū)生態(tài)等因素評(píng)估,MOE 解決方案無(wú)論在當(dāng)前階段還是未來(lái)都具備一定優(yōu)勢(shì)。
方案介紹
一、整體架構(gòu)
如下是 MOE 的整體架構(gòu)圖,最下面是各種高性能數(shù)據(jù)面,目前我們主要適配的是 Envoy。在數(shù)據(jù)面之上剝離了一層 GoLang L7 extension filter 的抽象,用于和底層的數(shù)據(jù)面連通;然后在 MOSN 側(cè)通過(guò) GoLang L7 extension SDK 將 MOSN 連通;最后通過(guò) CGO 這個(gè)通道將 Envoy 和 MOSN 打通。
整體架構(gòu)如上圖所示,其核心包括如下三部分組成:
GoLang L4/L7 extension filter
使用 C++ 實(shí)現(xiàn)的 Envoy 側(cè)的 GoLang L4/L7 filter ,該模塊通過(guò) CGO API 來(lái)調(diào)用 GoLang 實(shí)現(xiàn)的 L4/L7 extension filter。
GoLang L4/L7 extension SDK
GoLang L4/L7 extension SDK 會(huì)導(dǎo)出一些 CGO API,用于 Golang L4/L7 extension filter 和 L4/L7 extension GoLang filter 交互。
L4/L7 extension filter via GoLang
L4/L7 extension filter 是 GoLang 語(yǔ)言開(kāi)發(fā)的,用于對(duì) Envoy 的請(qǐng)求或者響應(yīng)做一些處理,最終是運(yùn)行在 Envoy 工作線程之中。
二、功能職責(zé)
通過(guò)上面對(duì)整體架構(gòu)的介紹,應(yīng)該對(duì) MOE 有了一個(gè)宏觀上的認(rèn)識(shí)。接下來(lái)我們通過(guò)功能職責(zé)方面來(lái)介紹下 MOE 中 MOSN 和 Envoy 是如何各司其職的:整體思路就是充分發(fā)揮 GoLang 的高研發(fā)效能以及 Envoy 在網(wǎng)絡(luò)層的高性能特性,所以在 MOSN 側(cè)來(lái)擴(kuò)展上層業(yè)務(wù)的服務(wù)治理能力,復(fù)用 Envoy 底層高效的 Eventloop 網(wǎng)絡(luò)模型。
MOSN 側(cè)做業(yè)務(wù)擴(kuò)展:擴(kuò)展非 xDS 服務(wù)發(fā)現(xiàn)、擴(kuò)展 L4/L7 filter、擴(kuò)展 Xprotocol 支持、Debug 及 Admin 管理、Metrics 監(jiān)控統(tǒng)計(jì);
Envoy 側(cè)復(fù)用基礎(chǔ)能力:復(fù)用高效 Eventloop 模型、復(fù)用 xDS 服務(wù)元數(shù)據(jù)通道、復(fù)用 L4/L7 filter、復(fù)用 Cluster LB、復(fù)用 State 統(tǒng)計(jì)。
三、工作流程
通過(guò)使用 GoLang 在 Envoy 中實(shí)現(xiàn)的“TraceID 事例”來(lái)介紹 Envoy GoLang extension 的工作流程:
1、請(qǐng)求/響應(yīng)到達(dá) Envoy 后,通過(guò) GoLang L7 extension filter 將請(qǐng)求/響應(yīng)信息通過(guò) API 封裝為特定格式;
2、然后將其封裝后的結(jié)構(gòu)體通過(guò) CGO API 傳遞給 GoLang extension framework;
3、該框架收到數(shù)據(jù)后將會(huì)執(zhí)行 Trace ID filter(GoLang 實(shí)現(xiàn)的 Filter,用于生成一個(gè) trace id 請(qǐng)求 header);
4、當(dāng) GoLang filter 執(zhí)行完成后,會(huì)把處理后的信息通過(guò)特定的結(jié)構(gòu)體返回給 GoLang L7 extension filter;
5、GoLang L7 extension filter 收到返回的特定結(jié)構(gòu)體信息后,將其操作生效到當(dāng)前請(qǐng)求/響應(yīng)。
其中在上述的(1、2、4、5)步驟中涉及到 Envoy 和 GoLang 的交互協(xié)議、(2、4)中涉及到 Envoy 和 GoLang 之間的內(nèi)存如何管理、(2)中阻塞操作處理,接下來(lái)是這些問(wèn)題的解決方案:
交互協(xié)議(1、2、4、5)
將 Envoy 的請(qǐng)求使用 GoLang L7 extension filter 的 proxy_golang API(GoLang L7 extension SDK)進(jìn)行封裝,然后通過(guò) CGO 通知 GoLang 側(cè)的 filter manager 進(jìn)行處理,其流程如下圖所示:
當(dāng) Envoy 側(cè)收到請(qǐng)求后,將請(qǐng)求的 header、body、trailer 封裝為 CGO_Request 類型,然后調(diào)用 proxy_golang_on_request,GoLang filter 處理后的結(jié)果會(huì)封裝為 CGO_Response 返回給 Envoy 繼續(xù)處理。當(dāng) Envoy 側(cè)收到響應(yīng)后,將響應(yīng)的 header、body、trailer 封裝為 CGO_Resquest 類型,然后調(diào)用 proxy_golang_on_response,GoLang filter 處理后的結(jié)果會(huì)封裝為 CGO_Response 返回給 Envoy 繼續(xù)處理。同時(shí)我們也期望可以和 Envoy、Cilium、WASM 社區(qū)合作共建這套 API 規(guī)范,這樣可以使得多個(gè)擴(kuò)展方案底層依賴的 API 能夠標(biāo)準(zhǔn)化。
內(nèi)存管理(2、4)
請(qǐng)求鏈路(CGO Request)
問(wèn)題:將 Envoy 中的請(qǐng)求信息如何高效的傳送給 GoLang,應(yīng)該避免無(wú)效的內(nèi)存拷貝操作。
方案:將 GoLang 中使用的 header、body 等信息直接指向 Envoy 的請(qǐng)求 header、body 的指針,這樣請(qǐng)求從 Envoy 到達(dá) GoLang 就不需要拷貝。
響應(yīng)鏈路(CGO Response)
問(wèn)題:請(qǐng)求在 GoLang 側(cè)執(zhí)行完成后,將處理結(jié)果返回給 Envoy,如果直接使用 GoLang 返回的內(nèi)存是不安全的,因?yàn)?GoLang 中的內(nèi)存可能會(huì)被 GC。
方案:把 GoLang 中生成的 CGO_Response 對(duì)象儲(chǔ)到全局的 map 中,通過(guò)請(qǐng)求 id 進(jìn)行映射,待 Envoy 使用完后,在將其對(duì)應(yīng)的結(jié)構(gòu)體從 map 中刪除。
阻塞處理(2)
首先 Envoy 的事件模型是異步非阻塞的,如果 GoLang 實(shí)現(xiàn)的 HTTP filter 存在阻塞操作需要如何處理?
對(duì)于純計(jì)算(非阻塞)或請(qǐng)求鏈路中的旁路阻塞操作,按照正常流程執(zhí)行即可。對(duì)于阻塞操作,通過(guò) GoLang 的 goroutine(協(xié)程) 結(jié)合 Envoy 的 event loop callback 機(jī)制來(lái)解決:
1、當(dāng)請(qǐng)求傳遞到 GoLang 側(cè)后,如果發(fā)現(xiàn) GoLang 實(shí)現(xiàn)的 filter 中有阻塞操作;
2、則 GoLang 側(cè)會(huì)立刻啟動(dòng)一個(gè) goroutine 用來(lái)執(zhí)行阻塞操作,同時(shí)會(huì)立刻返回,并告知 Envoy 需要異步操作;
3、Envoy 收到該消息后,則會(huì)停止該請(qǐng)求上的 filter 處理,然后繼續(xù)處理其他的請(qǐng)求;
4、當(dāng) Golang 側(cè)的阻塞操作執(zhí)行完成后,則會(huì)通過(guò) dispatcher post 一個(gè)事件告訴 Envoy 繼續(xù)處理該請(qǐng)求。
除了上述我們?cè)?GoLang 側(cè)自身程序出現(xiàn)同步導(dǎo)致的阻塞外,是否還有其他場(chǎng)景?
我們都知道 GoLang 程序是 GMP 模型的,CGO 也是要遵守的,當(dāng) Envoy 通過(guò) CGO 執(zhí)行 MOSN(GoLang),此時(shí) P 的數(shù)量如何管理?M 從哪來(lái)?
M 的問(wèn)題比較好解決,由于宿主程序是 C 系列的,所以會(huì)把當(dāng)前 Envoy 線程通過(guò) GoLang runtime 的 needm 來(lái)偽裝成一個(gè) M。其次就是 P 這個(gè)資源比較關(guān)鍵,如果此時(shí)沒(méi)有空閑的 P 此時(shí)就會(huì)卡主 CGO 執(zhí)行,雖然目前我們生產(chǎn)上還未出現(xiàn)該問(wèn)題,但是還是有這個(gè)可能性的。所以目前我們想到的解決方案就是為 Envoy 每個(gè) worker thread 都預(yù)留對(duì)應(yīng)的 P,保證每次 CGO 的時(shí)候都可以找到 P 資源。
服務(wù)相關(guān)元數(shù)據(jù)如何管理
MOSN 和 Envoy 的相關(guān)服務(wù)元數(shù)據(jù)信息,是如何交互管理的?通過(guò)擴(kuò)展 Envoy 中的 Admin API 使其支持 xDS 同等功能的 API, MOSN 集成的 Service Discovery 組件通過(guò)該 API(rest http) 和 Envoy 交互。使其 MOE 的服務(wù)發(fā)現(xiàn)能力也具備“雙模”能力,可同時(shí)滿足大規(guī)模及云原生的服務(wù)發(fā)現(xiàn)通道。
如何 Debug
MOSN 和 Envoy 相互融合后,在運(yùn)行時(shí)變?yōu)橐粋€(gè)進(jìn)程了,那之前的可觀測(cè)性以及調(diào)試如何保障?關(guān)于可觀測(cè)性方面這塊可以直接復(fù)用 MOSN 和 Envoy 自帶 admin API 及 metrics 功能,關(guān)于兩者之間的交互層我們?cè)黾恿嗣看谓换サ暮臅r(shí)以及異常下的容災(zāi)保護(hù)。最后就是關(guān)于一個(gè)程序即有 C++ 又有 GoLang 如何便捷性調(diào)試的問(wèn)題,對(duì)此我們調(diào)研了相關(guān)方案,通過(guò) net/rpc 網(wǎng)絡(luò)庫(kù)模擬? CGO 的調(diào)用,使得用戶調(diào)試 GoLang 側(cè)和之前 Native GoLang 一樣的方式調(diào)試即可。
方案總結(jié)
MOE 借助 CGO 通道不僅將 Envoy 和 MOSN 二者優(yōu)勢(shì)融為一體,而且將 GoLang 生態(tài)集成進(jìn) Envoy 變成了可能。在研發(fā)效能方面通過(guò)將 MOSN 作為 Envoy 的動(dòng)態(tài)庫(kù),上層業(yè)務(wù)改動(dòng)只需編譯 GoLang 代碼即可,極大的提升了編譯速度,同時(shí)也增強(qiáng)了 Envoy 的自身擴(kuò)展能力,使其能夠方便復(fù)用 MOSN 中現(xiàn)有的服務(wù)治理能力。性能方面,MOE 復(fù)用 Envoy 的高效網(wǎng)絡(luò)通道,之間的數(shù)據(jù)拷貝實(shí)現(xiàn)了 Zero Copy 可為 Dapr、Layotto 等提供高效網(wǎng)絡(luò)通道,同時(shí) Envoy 使用 C++/C 系可方便的集成硬件加速能力。關(guān)于在服務(wù)元數(shù)據(jù)通道方面,MOE 即可復(fù)用 Envoy 原生的 xDS 又可以方便的集成 GoLang Discovery SDK 實(shí)現(xiàn)多種服務(wù)元數(shù)據(jù)通道支持。最后 MOE 不僅單純的將兩個(gè)軟件的優(yōu)勢(shì)做了加法,更重要的是使得 MOSN/GoLang 可以和 Envoy 生態(tài)拉通,實(shí)現(xiàn)多社區(qū)技術(shù)共享。
開(kāi)源共建及展望
秉著借力開(kāi)源,反哺開(kāi)源的思路。當(dāng)我們對(duì) MOE 方案 POC 驗(yàn)證可行性后,我們也將這個(gè)思路在 MOSN 和 Envoy 社區(qū)展開(kāi)了相關(guān)的 A proposal of high-performance L7 network GoLang extension for Envoy 討論。在得到 Envoy maintainer 的認(rèn)可后,我們也在主導(dǎo)關(guān)于使用 GoLang 來(lái)擴(kuò)展 Envoy 的提案:Envoy's GoLang extension proposal ,歡迎大家參與進(jìn)來(lái)討論。
另外,近期我們也在設(shè)計(jì) MOE 具備 L4 的 GoLang 擴(kuò)展能力,這樣可方便使得 Envoy 集成 Layotto 或 Dapr 能力,從而同一個(gè) sidecar 可具備 Service Mesh 與 Application runtime 能力,解決一個(gè)應(yīng)用部署多個(gè) Sidecar 導(dǎo)致的運(yùn)維復(fù)雜性問(wèn)題。
方案實(shí)施效果
踩坑記錄
前面我們對(duì) MOE 從整體架構(gòu)、功能職責(zé)以及工作流程做了詳細(xì)的介紹,看似整體流程是可以跑通了。但是在我們落地實(shí)踐的過(guò)程中也是遇到了不少問(wèn)題。
下面這個(gè)列子就是在 MOE 工程中剝離出來(lái)的一個(gè)問(wèn)題的最小復(fù)現(xiàn)場(chǎng)景,當(dāng)時(shí)我們?cè)?CGO 傳遞數(shù)據(jù)的過(guò)程中,為了方便我們直接在 C++ 側(cè)通過(guò)指針來(lái)保存 header 的長(zhǎng)度,當(dāng)其傳遞到 GoLang 側(cè)的時(shí)候,運(yùn)行著運(yùn)行著就 panic 掉了,如下所示:
通過(guò)分析后,發(fā)現(xiàn)是由于 GoLang 的函數(shù)棧在運(yùn)行時(shí)觸發(fā)了棧擴(kuò)容操作,從而會(huì)觸發(fā) GoLang runtime 對(duì)當(dāng)前函數(shù)棧上的指針做了一系列操作。對(duì)上述問(wèn)題有影響的操作包括兩個(gè):其一是會(huì)對(duì)當(dāng)前棧上的指針指向的地址做判斷,檢查是否是一個(gè)安全的地址;其二是判斷當(dāng)前棧上的指針指向的地址是否位于即將要擴(kuò)容或者縮容的函數(shù)棧空間范圍內(nèi),如果在該范圍,則會(huì)根據(jù)擴(kuò)縮容函數(shù)棧后的偏移量直接修改指針指向的地址。然而在我們的場(chǎng)景中,直接使用指針來(lái)存儲(chǔ)長(zhǎng)度,這將導(dǎo)致 runtime 中的第一個(gè)操作檢查不通過(guò),直接拋異常。雖然當(dāng)時(shí)我們通過(guò)調(diào)整 GoLang runtime invalidPtr 來(lái)繞過(guò)第一個(gè)檢查報(bào)錯(cuò),但一旦我們所記錄的長(zhǎng)度正好和函數(shù)棧地址空間有交集的話,那對(duì)應(yīng)長(zhǎng)度的值也是會(huì)被修改的,所以也是不能滿足的。最后通過(guò)修改了長(zhǎng)度的傳遞存儲(chǔ)方式來(lái)解決該問(wèn)題。
由于篇幅有限,本文就不對(duì)所有問(wèn)題進(jìn)行展開(kāi)了,整體來(lái)說(shuō)遇到的問(wèn)題還是非常有趣的,對(duì)此感興趣或有疑問(wèn)的歡迎找我們交流。
最佳實(shí)踐
從 2021 年 1 月到 3 月期間我們進(jìn)行了 MOE 的方案設(shè)計(jì)到編碼實(shí)現(xiàn),并在 2 月份在 gRPC 網(wǎng)關(guān)集群進(jìn)行了小規(guī)模試點(diǎn),各項(xiàng)指標(biāo)都正常,MOE 雛形方案得到了線上真實(shí)流量的驗(yàn)證。于是 3 月份的時(shí)候我們就找到兄弟團(tuán)隊(duì)相關(guān)同學(xué)討論:今年有一個(gè)目標(biāo)需要全站資源成本優(yōu)化,我們基礎(chǔ)設(shè)施是不是可以做點(diǎn)什么?所以就順利成章的引出了 MOE 合作契機(jī),經(jīng)過(guò)幾輪討論以及簡(jiǎn)單的 POC 驗(yàn)證后決定在經(jīng)濟(jì)體互通網(wǎng)關(guān)場(chǎng)景,將內(nèi)部的一個(gè) Native Go 實(shí)現(xiàn)的網(wǎng)關(guān)基于 MOE 架構(gòu)來(lái)替代螞蟻側(cè)的互通網(wǎng)關(guān)。其部署架構(gòu)如下圖所示(目前互通網(wǎng)關(guān)螞蟻側(cè)已經(jīng)在灰度中):
雙方目標(biāo)達(dá)成一致后,就準(zhǔn)備開(kāi)干了。雖然 MOE 雛形之前已經(jīng)踩過(guò)一些坑了,但是在實(shí)際適配的過(guò)程中還是多多少少遇到了一些問(wèn)題,那最終我們也趕在了 6.18 這個(gè)時(shí)間點(diǎn)前進(jìn)行了灰度上線。如下引自第一個(gè)基于 MOE 架構(gòu)來(lái)替換網(wǎng)關(guān)的實(shí)踐 —《融合 Envoy 和 Go 語(yǔ)言生態(tài)打造高性能網(wǎng)關(guān)》,后續(xù)會(huì)有相關(guān)文章,敬請(qǐng)關(guān)注。
經(jīng)過(guò)這樣一番“折騰”,最終新版本基于 MOE 的網(wǎng)關(guān)在 6.18 活動(dòng)前上線,并承擔(dān)了總體流量的 10%,整體表現(xiàn)平穩(wěn),符合預(yù)期,現(xiàn)在逐步擴(kuò)大引流中(截止 7 月 2 號(hào)引進(jìn)引流到 30% 左右)。從我們的壓測(cè)數(shù)據(jù)上看,相較于老版本,CPU 使用率和請(qǐng)求 RT 都有顯著下降,在TCP 連接數(shù)越高的場(chǎng)景,優(yōu)勢(shì)越明顯,總體上能夠取得 2.6~4.3 倍的 QPS 性能提升。
總結(jié)
MOE 技術(shù)方案使得 MOSN/GoLang 和 Envoy 相互融合成為了可能,打破了 MOSN/GoLang 和 Envoy 割裂的社區(qū)生態(tài)現(xiàn)狀,為將來(lái) Proxy 的持續(xù)演進(jìn)奠定了堅(jiān)實(shí)的技術(shù)基礎(chǔ)。隨著在經(jīng)濟(jì)體互通螞蟻側(cè)網(wǎng)關(guān)的落地實(shí)踐,其 MOE 技術(shù)方案的穩(wěn)定性、可靠性、易用性等方面都得到了一定的考驗(yàn)。同時(shí)秉著對(duì)技術(shù)的高標(biāo)準(zhǔn)要求以及能夠更好的服務(wù)好我們的用戶,我們也會(huì)持續(xù)探索和優(yōu)化 MOE,如果該方案能也夠解決你業(yè)務(wù)上遇到的問(wèn)題,歡迎聯(lián)系我們,最后感謝正在關(guān)注此項(xiàng)技術(shù)的用戶,歡迎和我們交流和討論!MOSN 用戶交流群釘釘群號(hào):33547952。
推薦閱讀
MOSN 多協(xié)議擴(kuò)展開(kāi)發(fā)實(shí)踐
MOSN 子項(xiàng)目 Layotto:開(kāi)啟服務(wù)網(wǎng)格+應(yīng)用運(yùn)行時(shí)新篇
金融級(jí)能力成核心競(jìng)爭(zhēng)力,服務(wù)網(wǎng)格驅(qū)動(dòng)企業(yè)創(chuàng)新
Protocol Extension Base On Wasm——協(xié)議擴(kuò)展篇
總結(jié)
以上是生活随笔為你收集整理的开启云原生 MOSN 新篇章 — 融合 Envoy 和 Golang 生态的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 高并发场景下 disk io 引发的高时
- 下一篇: Go 超时引发大量 fin-wait2