前言
MOSN 是一款使用 Go 語言開發的 Service Mesh 數據平面代理,2018 年 7 月由螞蟻金服開源,開源地址 https://github.com/sofastack/sofa-mosn,MOSN 旨在爲服務提供分佈式、模塊化、可觀察和智能化的代理能力。MOSN 是 Modular Observable Smart Network 的簡稱。MOSN 可以與任何支持 xDS API 的 Service Mesh 集成,亦可以作爲獨立的四、七層負載均衡使用。未來 MOSN 將支持更多雲原生場景,並支持 Nginx 的核心轉發功能。
本文根據螞蟻金服烈元 2019 年 11 月 30 日在 Gopher China Meetup 北京站上的分享整理而成,查看分享回顧,同時本文已更新到 MOSN 官方文檔上。
MOSN 核心概念
MOSN 主要劃分爲如下模塊,包括了網絡代理具備的基礎能力,也包含了 xDS 等雲原生能力。
xDS(UDPA)支持
MOSN 支持雲原生統一數據面 API(UDPA),支持全動態配置更新。
xDS 是 Envoy 創建的一個關鍵概念,它是一類發現服務的統稱,其包括如下幾類:
- CDS:Cluster Discovery Service
- EDS:Endpoint Discovery Service
- SDS:Secret Discovery Service
- RDS:Route Discovery Service
- LDS:Listener Discovery Service
正是通過對 xDS 的請求來動態更新 Envoy 配置,另外還有個 ADS(Aggregated Discovery Service)通過聚合的方式解決以上 xDS 的更新順序問題。
業務支持
MOSN 作爲底層的高性能安全網絡代理,支撐了 RPC、消息(Messaging)、網關(Gateway)等業務場景。
IO 模型
MOSN 支持以下兩種 IO 模型:
- Golang 經典 netpoll 模型:goroutine-per-connection,適用於在連接數不是瓶頸的情況。
- RawEpoll 模型:也就是 Reactor 模式,I/O 多路複用(I/O multiplexing) 非阻塞 I/O(non-blocking I/O)的模式。對於接入層和網關有大量長鏈接的場景,更加適合於 RawEpoll 模型。
netpoll 模型
MOSN 的 netpoll 模型如上圖所示,協程數量與鏈接數量成正比,大量鏈接場景下,協程數量過多,存在以下開銷:
- Stack 內存開銷
- Read buffer 開銷
- Runtime 調度開銷
RawEpoll 模型
RawEpoll 模型如上圖所示,使用 epoll 感知到可讀事件之後,再從協程池中爲其分配協程進行處理,步驟如下:
- 鏈接建立後,想 Epoll 註冊 oneshot 可讀事件監聽;並且此時不允許有協程調用 conn.read,避免與 runtime netpoll 衝突。
- 可讀事件到達,從 goroutine pool 挑選一個協程進行讀事件處理;由於使用的是 oneshot 模式,該 fd 後續可讀事件不會再觸發。
- 請求處理過程中,協程調度與經典 netpoll 模式一致。
- 請求處理完成,將協程歸還給協程池;同時將 fd 重現添加到 RawEpoll 中。
協程模型
MOSN 的協程模型如下圖所示。
- 一條 TCP 連接對應一個 Read 協程,執行收包、協議解析;
- 一個請求對應一個 worker 協程,執行業務處理,proxy 和 Write 邏輯;
常規模型一個 TCP 連接將有 Read/Write 兩個協程,我們取消了單獨的 Write 協程,讓 workerpool 工作協程代替,減少了調度延遲和內存佔用。
能力擴展
協議擴展
MOSN 通過使用同一的編解碼引擎以及編/解碼器核心接口,提供協議的 plugin 機制,包括支持:
- SOFARPC
- HTTP1.x/HTTP2.0
- Dubbo
NetworkFilter 擴展
MOSN 通過提供 network filter 註冊機制以及統一的 packet read/write filter 接口,實現了 Network filter 擴展機制,當前支持:
- TCP proxy
- Fault injection
StreamFilter 擴展
MOSN 通過提供 stream filter 註冊機制以及統一的 stream send/receive filter 接口,實現了 Stream filter 擴展機制,包括支持:
- 流量鏡像
- RBAC 鑑權
TLS 安全鏈路
通過測試,原生的 Go 的 TLS 經過了大量的彙編優化,在性能上是 Nginx(OpenSSL)的80%,Boring 版本的 Go(使用 cgo 調用 BoringSSL)因爲 cgo 的性能問題, 並不佔優勢,所以我們最後選擇使用原生 Go 的 TLS,相信 Go Runtime 團隊後續會有更多的優化,我們也會有一些優化計劃。
Go vs Nginx 測試結果如下圖所示:
- Go 在 RSA 上沒有太多優化,go-boring(CGO)的能力是 Go 的兩倍。
- p256 在 Go 上有彙編優化,ECDSA 優於go-boring。
- 在 AES-GCM 對稱加密上,Go 的能力是 go-boring 的 20 倍。
- 在 SHA、MD 等 HASH 算法也有對應的彙編優化。
爲了滿足金融場景的安全合規,我們同時也對國產密碼進行了開發支持,這個是 Go Runtime 所沒有的。雖然目前的性能相比國際標準 AES-GCM 還是有一些差距,大概是 50%,但是我們已經有了後續的一些優化計劃,敬請期待。
支持國密的性能測試結果如下圖所示:
MOSN 開源地址:https://github.com/sofastack/sofa-mosn
關於 ServiceMesher 社區
ServiceMesher 社區是由一羣擁有相同價值觀和理念的志願者們共同發起,於 2018 年 4 月正式成立。
社區關注領域有:容器、微服務、Service Mesh、Serverless,擁抱開源和雲原生,致力於推動 Service Mesh 在中國的蓬勃發展。
社區官網:https://www.servicemesher.com