Go 語言版 Service Mesh Sidecar 剖析系列之 SOFAMosn 的誕生和特性總覽

GitHub:github.com/alipay/sofa…git

文檔地址:www.sofastack.tech/sofa-mosn/d…github

SOFAMosn 的誕生

雲原生時代,Service Mesh 做爲一個專用的基礎設施層,用於提供安全、快速、可靠、智能的服務間通信,可爲微服務的鏈接、管理和監控帶來巨大的便利,從而加速微服務的落地。算法

做爲國內領先的金融服務提供商,螞蟻金服對系統架構的性能、穩定性、安全性要求極高,且面對的運維架構複雜。爲了達到高可用和快速迭代的目的,螞蟻金服正全面擁抱微服務,雲原生, 故 Service Mesh 成爲助力螞蟻 SOFA5,以及兼容 K8S 的容器平臺 Sigma等微服務化關鍵組件落地的重要推手。編程

在 Service Mesh 落地的方案挑選中, Istio 做爲 Service Mesh 的集大成者,不管在功能實現,穩定性,擴展性,以及社區關注度等方面都是不二選擇,其數據平面 Envoy 更是具備優秀的設計,可擴展的 XDS API,以及較高的性能等特色,螞蟻一開始便將 Istio 做爲重點的關注對象。後端

然而,因爲 Envoy 使用 C++ 語言開發,不符合螞蟻技術棧的發展方向且沒法兼容如今的運維體系,以及螞蟻內部有許多業務定製化的訴求,致使咱們沒法直接使用 Istio。通過調研發現,做爲雲計算時代主流語言的 Golang 一樣具備較高的轉發性能,這促使咱們考慮開發 Golang 版本高性能的 sidecar 來替換 Envoy 與 Istio 作集成。api

今天,咱們就來介紹它:「SOFAMosn」 。安全

初識 SOFAMosn

SOFA MOSN 架构图

簡單來講,SOFAMosn 是一款採用 Golang 開發的 Service Mesh 數據平面代理,由螞蟻金服系統部網絡團隊、螞蟻金服中間件團隊、UC 大文娛團隊共同開發,功能和定位相似 Envoy,旨在提供分佈式,模塊化,可觀察,智能化的代理能力。它經過模塊化,分層解耦的設計,提供了可編程,事件機制,擴展性,高吞吐量的能力。網絡

當前, SOFAMosn 已支持 Envoy 和 Istio 的 API,實現並驗證了 Envoy 的經常使用功能(全量功能在開發中),經過 XDS API 與 Pilot 對接,SOFAMosn 可獲取控制面推送的配置信息,來完成代理的功能。在實踐中,你可使用 SOFAMosn 替代 Envoy 做爲轉發平面與 Istio 集成來實現 Service Mesh 組件,也能夠單獨使用 SOFAMosn 做爲業務網關,經過使用 SOFAMosn 你將在以下幾個方面得到收益:架構

  1. SOFAMosn 使用 Golang 做爲開發語言,開發效率高,在雲原生時代可與 k8s 等技術無縫對接,有利於加速微服務的落地;併發

  2. SOFAMosn 可代理 Java,C++,Golang,PHP,Python 等異構語言之間組件的互相調用,避免多語言版本組件的重複開發,可提升業務開發效率,目前 SOFAMosn 已經在螞蟻金服中做爲跨語言 RPC 調用的橋樑被使用;

  3. SOFAMosn 可提供靈活的流量調度能力,有助於運維體系的支撐,包括:藍綠升級、容災切換等;

  4. SOFAMosn 提供TLS、服務鑑權等能力,可知足服務加密與安全的訴求;

當前 SOFAMosn 已經在 Github 上開源,咱們歡迎全部感興趣的同窗參與進來,與咱們一塊兒共建一個精品的 Golang Sidecar,項目地址爲:https://github.com/alipay/sofa-mosn

爲了幫助你們更好的理解 SOFAMosn,本文做爲開篇文章,會總體性的介紹 SOFAMosn 的特性以期給你們一個完整的印象,具體的細節這裏不作展開,若是您對細節感興趣,歡迎關注後續文章。

本文介紹的內容將包括 :

  • SOFAMosn 是如何工做的

  • SOFAMosn 內部是如何完成代理功能的

  • SOFAMosn 如何提升Golang的轉發性能

  • SOFAMosn 作了哪些內存優化

  • SOFAMosn 如何作到系統的高可用

  • SOFAMosn 如何支持擴展

  • SOFAMosn 如何作到安全

SOFAMosn 是如何工做的

SOFAMosn 本質是一個 4-7 層代理,因此它能夠以獨立進程的形式做爲 sidecar 與用戶程序部署在相同的物理機或者VM中,固然也能夠以獨立網關的形式單獨運行在一臺主機或者虛擬機中。

如下圖爲例,MOSN (注: SOFAMosn 有時也簡稱爲 MOSN) 與 Service 部署在同一個 Pod 上,MOSN 監聽在固定的端口,一個正向的請求鏈路包括以下步驟:

  • ServiceA 做爲客戶端可以使用任意語言實現,可以使用目前支持的任意的協議類型,好比HTTP1.x,HTTP2.0,SOFARPC 等,將 sub/pub、request 信息等發送給MOSN

  • MOSN 可代理 ServiceA 的服務發現,路由,負載均衡等能力,經過協議轉換,轉發 ServiceA 的請求信息到上游的 MOSN

  • 上游 MOSN 將接收到的請求經過協議轉換,發送到代理的 ServiceB 上

反向鏈路相似,經過上述的代理流程,MOSN 代理了 Service A 與 Service B 之間的請求。

這裏有一些須要注意的是:

  1. 你可使用 MOSN 只代理 Client 的請求,MOSN 能夠直接訪問 Server,鏈路:Client -> MOSN -> Server,反之亦然

  2. MOSN 上下游協議可配置爲當前支持的協議中的任意一種

SOFAMosn 內部是如何完成代理功能的

瞭解 SOFAMosn 的代理能力,咱們須要窺探它的實現框架以及數據在其內部的流轉。這裏咱們先介紹組成 SOFAMosn 的模塊,再介紹 SOFAMosn 的分層設計

SOFAMosn 的組成模塊

在上圖中,藍色框中的模塊爲當前已經支持的模塊,紅色虛線模塊爲開發中模塊,其中:

  • Starter 用於啓動 MOSN,包括從配置文件或者以 XDS 模式啓動,其中Config 用於配置文件的解析等,XDS 用於和 Istio 交互,獲取 Pilot 推送的配置等

  • MOSN 解析配置後,會生成 Server以及Listener ,在 Listener 中有監聽端口、 ProxyFilter 、Log 等信息;Server 包含 Listener ,爲 MOSN 運行時的抽象,Server 運行後,會開啓 Listener 監聽,接受鏈接等

  • MOSN 運行起來後,還會生成 Upstream相關信息,用於維護後端的 Cluster和 Host信息

  • MOSN 在轉發請求時,會在 Upstream 的 Cluster 中經過 Router 以及 LoadBalancer 挑選 Host

  • Router 爲 MOSN 的路由模塊,當前支持根據 label 作路由等

  • LoadBalance 爲 MOSN 的負載均衡模塊,支持 WRR,Subset LB

  • Metrics 模塊用於對協議層的數據作記錄和追蹤

  • Hardware 爲 MOSN 後期規劃的包括使用加速卡來作 TLS 加速以及 DPDK 來作協議棧加速的一些硬件技術手段

  • Mixer 用於對請求作服務鑑權等,爲開發中模塊

  • FlowControl 用來對後端作流控,爲開發中模塊

  • LabAdmin 模塊爲實驗性待開發模塊

SOFAMosn 的分層設計

爲了轉發數據,實現一個4-7層的 proxy,在分層上,SOFAMosn 將總體功能分爲 "網絡 IO 層","二進制協議處理層","協議流程處理層"以及"轉發路由處理層" 等四層進行設計,每一層實現的功能高度內聚可用於完成獨立的功能,且層與層之間可相互配合實現完整的 proxy 轉發。

以下圖所示:SOFAMosn 對請求作代理的時候,在入口方向,會依次通過網絡 IO 層(NET/IO),二進制協議處理層(Protocol),協議流程處理層(Streaming),轉發路由處理層(Proxy);出向與入向過程基本相反

下面咱們簡單介紹每一層的做用,關於每一層的特性,請參考:

https://github.com/alipay/sofa-mosn/blob/master/docs/design/MOSNLayerFeature.md

  • NET/IO 層提供了 IO 讀寫的封裝以及可擴展的 IO 事件訂閱機制;

  • Protocol 層提供了根據不一樣協議對數據進行序列化/反序列化的處理能力;

  • Streaming 層提供向上的協議一致性,負責 stream 的生命週期,管理 Client / Server 模式的請求流行爲,對 Client 端stream 提供池化機制等;

  • Proxy 層提供路由選擇,負載均衡等的能力,作數據流之間的轉發;

下面是將此圖打開後的示意圖

  1. MOSN 在 IO 層讀取數據,經過 read filter 將數據發送到 Protocol 層進行 Decode

  2. Decode 出來的數據,根據不一樣的協議,回調到 stream 層,進行 stream 的建立和封裝

  3. stream 建立完畢後,會回調到 Proxy 層作路由和轉發,Proxy 層會關聯上下游間的轉發關係

  4. Proxy 挑選到後端後,會根據後端使用的協議,將數據發送到對應協議的 Protocol 層,對數據從新作 Encode

  5. Encode 後的數據會發通過 write filter 並最終使用 IO 的 write 發送出去

SOFAMosn 如何提升 Golang 的轉發性能

Golang 的轉發性能比起 C++ 是稍有遜色的,爲了儘量的提升 MOSN 的轉發性能,咱們在線程模型上進行優化,當前 MOSN 支持兩種線程模型,用戶可根據場景選擇開啓適用的模型。

模型一

以下圖所示,模型一使用 Golang 默認的 epoll 機制,對每一個鏈接分配獨立的讀寫協程進行阻塞讀寫操做, proxy 層作轉發時,使用常駐 worker 協程池負責處理 Stream Event


  • 此模型在 IO上使用 Golang 的調度機制,適用於鏈接數較少的場景,例如:SOFAMosn 做爲 sidecar、與 client 同機部署的場景

模型二

以下圖所示,模型二基於 NetPoll 重寫 epoll 機制,將 IO 和 PROXY 均進行池化,downstream connection將自身的讀寫事件註冊到netpoll的epoll/kqueue wait 協程,epoll/kqueue wait 協程接受可讀事件時,觸發回調,從協程池中挑選一個執行讀操做

  • 使用自定義 Netpoll IO 池化操做帶來的好處是:

    • 當可讀事件觸發時,從協程池中獲取一個 goroutine 來執行讀處理,而不是新分配一個 goroutine,以此來控制高併發下的協程數量

    • 當收到連接可讀事件時,才真正爲其分配 read buffer 以及相應的執行協程。這樣能夠優化大量空閒連接場景緻使的額外協程和 read buffer 開銷

  • 此模型適用於鏈接數較多,可讀的鏈接數有限,例如:SOFAMosn 做爲 api Gateway 的場景

SOFAMosn 作了哪些內存優化

Golang 相比於 C++,在內存使用效率上依賴於 GC,爲了提升 Golang 的內存使用率,MOSN 作了以下的嘗試來減小內存的使用,優化 GC 的效率:

  • 經過自定義的內存複用接口實現了通用的內存複用框架,可實現自定義內存的複用

  • 經過優化 []byte 的獲取和回收,進一步優化全局內存的使用;

  • 經過優化 socket 的讀寫循環以及事件觸發機制,減少空閒鏈接對內存分配的使用,進一步減小內存使用;

  • 使用 writev 替代 write, 減小內存分配和拷貝,減小鎖力度;

SOFAMosn 如何作到系統的高可用

  • MOSN 在運行時,會開啓 crontab 進行監控,在程序掛掉時,會及時拉起;

  • 同時,MOSN 在 進行升級或者 reload 等場景下作鏈接遷移時, 除了經典的傳遞 listener fd 加協議層等待方式之外,還支持對存量連接進行協議無關的遷移來實現平滑升級,平滑 reload 等功能;

  • 在對存量鏈接進行遷移時,mosn 經過 forkexec 生成New mosn,以後依次對存量的請求數據作遷移,對殘留響應作遷移來完成;

SOFAMosn 如何支持擴展

MOSN 當前支持 「協議擴展」 來作到對多協議的支持,支持 「NetworkFilter 擴展」 來實現自定義 proxy 的功能,支持 「StreamFilter 擴展」 來對數據作過濾:

1. 協議擴展

MOSN 經過使用同一的編解碼引擎以及編/解碼器核心接口,提供協議的 plugin 機制,包括支持

  • SOFARPC

  • HTTP1.x, HTTP2.0

  • Dubbo

等協議,後面還會支持更多的協議

2. NetworkFilter 擴展

MOSN 經過提供 Network Filter 註冊機制以及統一的 packet read/write filter 接口,實現了Network Filter 擴展機制,當前支持:

  • TCP Proxy

  • Layer-7 Proxy

  • Fault Injection

3. StreamFilter 擴展

MOSN 經過提供 Stream Filter 註冊機制以及統一的 stream send/receive filter 接口,實現了 Stream Filter 擴展機制,包括支持:

  • 支持配置健康檢查等

  • 支持故障注入功能

SOFAMosn 如何作到安全

SOFAMosn 中,經過使用 TLS 加密傳輸和服務鑑權來保證消息的安全可靠,在將來還會經過使用 keyless 等方案來提升加解密的性能,下面咱們介紹SOFAMosn 在 TLS 上的一些實踐

1. TLS 選型

  • 在 SOFAMosn 中使用 TLS 有兩種選擇,1) 使用 Golang 原生的 TLS , 2) 使用 cgo 調用 Boring SSL

  • 咱們經過壓測發現,在 ECDHE-ECDSA-AES256-GCM-SHA384 這種經常使用的加密套件下,Go 自身的 TLS 在性能上優於 Boring SSL,與 Openssl 相差很少

  • 通過調研發現,Go 對 p256,AES-GCM 對稱加密,SHA,MD5 等算法上均有彙編優化,於是咱們選擇使用 Golang 自帶的 TLS 來作 SOFAMosn 的 TLS 通訊

2. TLS 方案

  • SOFAMosn 間使用 Golang 原生的 TLS 加密,支持 listener 級別的 TLS 配置,配置包括證書鏈與證書列表等,用來作監聽時使用;支持 cluster 級別的 TLS 配置,cluster 配置對全部的 host 生效,用來向後端發起鏈接時使用;host 中有一個配置用來標明本身是否支持 TLS

  • SOFAMosn server 經過使用 Listener 的 Inspector 功能,可同時處理客戶端的 TLS 和 非 TLS 請求

  • SOFAMosn client 在發起鏈接的時候,根據挑選的 host 是否支持 TLS 來決定是否使用 TLS 發起鏈接

歡迎加入參與 SOFAMosn 源碼解析

相關連接:

SOFA 文檔: www.sofastack.tech/

SOFA: github.com/alipay

SOFAMosn: github.com/alipay/sofa…

相關文章
相關標籤/搜索