GitHub:github.com/alipay/sofa…git
文檔地址:www.sofastack.tech/sofa-mosn/d…github
雲原生時代,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 是一款採用 Golang 開發的 Service Mesh 數據平面代理,由螞蟻金服系統部網絡團隊、螞蟻金服中間件團隊、UC 大文娛團隊共同開發,功能和定位相似 Envoy,旨在提供分佈式,模塊化,可觀察,智能化的代理能力。它經過模塊化,分層解耦的設計,提供了可編程,事件機制,擴展性,高吞吐量的能力。網絡
當前, SOFAMosn 已支持 Envoy 和 Istio 的 API,實現並驗證了 Envoy 的經常使用功能(全量功能在開發中),經過 XDS API 與 Pilot 對接,SOFAMosn 可獲取控制面推送的配置信息,來完成代理的功能。在實踐中,你可使用 SOFAMosn 替代 Envoy 做爲轉發平面與 Istio 集成來實現 Service Mesh 組件,也能夠單獨使用 SOFAMosn 做爲業務網關,經過使用 SOFAMosn 你將在以下幾個方面得到收益:架構
SOFAMosn 使用 Golang 做爲開發語言,開發效率高,在雲原生時代可與 k8s 等技術無縫對接,有利於加速微服務的落地;併發
SOFAMosn 可代理 Java,C++,Golang,PHP,Python 等異構語言之間組件的互相調用,避免多語言版本組件的重複開發,可提升業務開發效率,目前 SOFAMosn 已經在螞蟻金服中做爲跨語言 RPC 調用的橋樑被使用;
SOFAMosn 可提供靈活的流量調度能力,有助於運維體系的支撐,包括:藍綠升級、容災切換等;
SOFAMosn 提供TLS、服務鑑權等能力,可知足服務加密與安全的訴求;
當前 SOFAMosn 已經在 Github 上開源,咱們歡迎全部感興趣的同窗參與進來,與咱們一塊兒共建一個精品的 Golang Sidecar,項目地址爲:https://github.com/alipay/sofa-mosn
爲了幫助你們更好的理解 SOFAMosn,本文做爲開篇文章,會總體性的介紹 SOFAMosn 的特性以期給你們一個完整的印象,具體的細節這裏不作展開,若是您對細節感興趣,歡迎關注後續文章。
本文介紹的內容將包括 :
SOFAMosn 是如何工做的
SOFAMosn 內部是如何完成代理功能的
SOFAMosn 如何提升Golang的轉發性能
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 之間的請求。
這裏有一些須要注意的是:
你可使用 MOSN 只代理 Client 的請求,MOSN 能夠直接訪問 Server,鏈路:Client -> MOSN -> Server,反之亦然
MOSN 上下游協議可配置爲當前支持的協議中的任意一種
瞭解 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
用來對後端作流控,爲開發中模塊
Lab
和 Admin
模塊爲實驗性待開發模塊
爲了轉發數據,實現一個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 層提供路由選擇,負載均衡等的能力,作數據流之間的轉發;
下面是將此圖打開後的示意圖
MOSN 在 IO 層讀取數據,經過 read filter 將數據發送到 Protocol 層進行 Decode
Decode 出來的數據,根據不一樣的協議,回調到 stream 層,進行 stream 的建立和封裝
stream 建立完畢後,會回調到 Proxy 層作路由和轉發,Proxy 層會關聯上下游間的轉發關係
Proxy 挑選到後端後,會根據後端使用的協議,將數據發送到對應協議的 Protocol 層,對數據從新作 Encode
Encode 後的數據會發通過 write filter 並最終使用 IO 的 write 發送出去
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 的場景
Golang 相比於 C++,在內存使用效率上依賴於 GC,爲了提升 Golang 的內存使用率,MOSN 作了以下的嘗試來減小內存的使用,優化 GC 的效率:
經過自定義的內存複用接口實現了通用的內存複用框架,可實現自定義內存的複用
經過優化 []byte 的獲取和回收,進一步優化全局內存的使用;
經過優化 socket 的讀寫循環以及事件觸發機制,減少空閒鏈接對內存分配的使用,進一步減小內存使用;
使用 writev 替代 write, 減小內存分配和拷貝,減小鎖力度;
MOSN 在運行時,會開啓 crontab 進行監控,在程序掛掉時,會及時拉起;
同時,MOSN 在 進行升級或者 reload 等場景下作鏈接遷移時, 除了經典的傳遞 listener fd 加協議層等待方式之外,還支持對存量連接進行協議無關的遷移來實現平滑升級,平滑 reload 等功能;
在對存量鏈接進行遷移時,mosn 經過 forkexec 生成New mosn,以後依次對存量的請求數據作遷移,對殘留響應作遷移來完成;
MOSN 當前支持 「協議擴展」 來作到對多協議的支持,支持 「NetworkFilter 擴展」 來實現自定義 proxy 的功能,支持 「StreamFilter 擴展」 來對數據作過濾:
MOSN 經過使用同一的編解碼引擎以及編/解碼器核心接口,提供協議的 plugin 機制,包括支持
SOFARPC
HTTP1.x, HTTP2.0
Dubbo
等協議,後面還會支持更多的協議
MOSN 經過提供 Network Filter 註冊機制以及統一的 packet read/write filter 接口,實現了Network Filter 擴展機制,當前支持:
TCP Proxy
Layer-7 Proxy
Fault Injection
MOSN 經過提供 Stream Filter 註冊機制以及統一的 stream send/receive filter 接口,實現了 Stream Filter 擴展機制,包括支持:
支持配置健康檢查等
支持故障注入功能
SOFAMosn 中,經過使用 TLS 加密傳輸和服務鑑權來保證消息的安全可靠,在將來還會經過使用 keyless 等方案來提升加解密的性能,下面咱們介紹SOFAMosn 在 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 通訊
SOFAMosn 間使用 Golang 原生的 TLS 加密,支持 listener 級別的 TLS 配置,配置包括證書鏈與證書列表等,用來作監聽時使用;支持 cluster 級別的 TLS 配置,cluster 配置對全部的 host 生效,用來向後端發起鏈接時使用;host 中有一個配置用來標明本身是否支持 TLS
SOFAMosn server 經過使用 Listener 的 Inspector 功能,可同時處理客戶端的 TLS 和 非 TLS 請求
SOFAMosn client 在發起鏈接的時候,根據挑選的 host 是否支持 TLS 來決定是否使用 TLS 發起鏈接
相關連接:
SOFA 文檔: www.sofastack.tech/
SOFA: github.com/alipay
SOFAMosn: github.com/alipay/sofa…