螞蟻金服 Service Mesh 大規模落地系列 - 核心篇

Service Mesh-01.jpg

揭祕 2019 Service Mesh 雙十一大考

螞蟻金服很早開始關注 Service Mesh,並在 2018 年發起 ServiceMesher 社區,目前已有 4000+ 開發者在社區活躍。在技術應用層面,Service Mesh 的場景已經渡過探索期,今年已經全面進入深水區探索。git

2019 年的雙十一是咱們的重要時刻,咱們進行了大規模的落地。做爲技術人能面對世界級的流量挑戰,是很是緊張和興奮的。當 Service Mesh 遇到雙十一又會迸發出怎樣的火花?螞蟻金服的 LDC 架構繼續演進的過程當中,Service Mesh 要承載起哪方面的責任?讓咱們一塊兒來揭祕螞蟻金服 Service Mesh 雙十一實戰。github

Service Mesh 基礎概念

Istio 清晰的描述了 Service Mesh 最核心的兩個概念:數據面與控制面。數據面負責作網絡代理,在服務請求的鏈路上作一層攔截與轉發,能夠在鏈路中作服務路由、鏈路加密、服務鑑權等,控制面負責作服務發現、服務路由管理、請求度量(放在控制面頗受爭議)等。golang

Service Mesh 帶來的好處再也不贅述,咱們來看下螞蟻金服的數據面和控制面產品:算法

  1. 數據面:SOFAMosn。螞蟻金服使用 Golang 研發的高性能網絡代理,做爲 Service Mesh 的數據面,承載了螞蟻金服雙十一海量的核心應用流量。
  2. 控制面:SOFAMesh。Istio 改造版,落地過程當中精簡爲 Pilot 和 Citadel,Mixer 直接集成在數據面中避免多一跳的開銷。

雙十一落地狀況概覽

今年,螞蟻金服的核心應用全面接入 SOFAMosn,生產 Mesh 化容器幾十萬臺,雙十一峯值 SOFAMosn 承載數據規模數千萬 QPS,SOFAMosn 轉發平均處理耗時 0.2ms。後端

雙十一落地數據

在如此大規模的接入場景下,咱們面對的是極端複雜的場景,同時須要多方全力合做,更要保障數據面的性能穩定性知足大促訴求,整個過程極具挑戰。安全

同時,Service Mesh 的落地也是一個跨團隊合做的典範案例,集合了核心、RPC、消息、無線網關、控制面、安全、運維、測試等團隊的精誠合做,接下來咱們會按照以上幾個模塊來解析 Service Mesh 的雙十一落地狀況,更多解析關注本號。性能優化

本文爲《螞蟻金服 Service Mesh 落地實踐系列》第一篇 - 核心篇,做者:田陽(花名:烈元),螞蟻金服技術專家,專一於高性能網絡服務器研發,Tengine 開源項目核心成員,螞蟻金服開源 SOFAMosn 項目核心成員。服務器

基礎能力建設

SOFAMosn 的能力大圖

SOFAMosn 主要劃分爲以下模塊,包括了網絡代理具有的基礎能力,也包含了 XDS 等雲原生能力。網絡

image.png

業務支持

SOFAMosn 做爲底層的高性能安全網絡代理,支撐了 RPC,MSG,GATEWAY 等業務場景。架構

image.png

IO 模型

SOFAMosn 支持兩種 IO 模型,一個是 Golang 經典模型,goroutine-per-connection;一個是 RawEpoll 模型,也就是 Reactor 模式,I/O 多路複用(I/O multiplexing) + 非阻塞 I/O(non-blocking I/O)的模式。

在螞蟻金服內部的落地場景,鏈接數不是瓶頸,都在幾千或者上萬的量級,咱們選擇了 Golang 經典模型。而對於接入層和網關有大量長連接的場景,更加適合於 RawEpoll 模型。

屏幕快照 2019-11-11 下午1.23.31.png

屏幕快照 2019-11-11 下午1.24.04.png

協程模型

image.png

  • 一條 TCP 鏈接對應一個 Read 協程,執行收包,協議解析;
  • 一個請求對應一個 worker 協程,執行業務處理,proxy 和 Write 邏輯;

常規模型一個 TCP 鏈接將有 Read/Write 兩個協程,咱們取消了單獨的 Write 協程,讓 workerpool 工做協程代替,減小了調度延遲和內存佔用。

能力擴展

協議擴展

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

  • SOFARPC;
  • HTTP1.x/HTTP2.0;
  • Dubbo;

NetworkFilter 擴展

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

  • TCP proxy;
  • Fault injection;

StreamFilter 擴展

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

  • 流量鏡像;
  • RBAC鑑權;

TLS 安全鏈路

做爲金融科技公司,資金安全是最重要的一環,鏈路加密又是其中最基礎的能力,在 TLS 安全鏈路上咱們進行了大量的調研測試。

經過測試,原生的 Go 的 TLS 通過了大量的彙編優化,在性能上是 Nginx(OpenSSL)的80%,Boring 版本的 Go(使用 cgo 調用 BoringSSL) 由於 cgo 的性能問題, 並不佔優點,因此咱們最後選型原生 Go 的 TLS,相信 Go Runtime 團隊後續會有更多的優化,咱們也會有一些優化計劃。

image.png

  • go 在 RSA 上沒有太多優化,go-boring(CGO)的能力是 go 的1倍;
  • p256 在 go 上有彙編優化,ECDSA 優於go-boring;
  • 在 AES-GCM 對稱加密上,go 的能力是 go-boring 的20倍;
  • 在 SHA、MD 等 HASH 算法也有對應的彙編優化;

爲了知足金融場景的安全合規,咱們同時也對國產密碼進行了開發支持,這個是 Go Runtime 所沒有的。雖然目前的性能相比國際標準 AES-GCM 仍是有一些差距,大概是 50%,可是咱們已經有了後續的一些優化計劃,敬請期待。

image.png

平滑升級能力

爲了讓 SOFAMosn 的發佈對應用無感知,咱們調研開發了平滑升級方案,相似 Nginx 的二進制熱升級能力,可是有個最大的區別就是 SOFAMosn 老進程的鏈接不會斷,而是遷移給新的進程,包括底層的 socket FD 和上層的應用數據,保證整個二進制發佈過程當中業務不受損,對業務無感知。除了支持 SOFARPC、Dubbo、消息等協議,咱們還支持 TLS 加密鏈路的遷移。

容器升級

基於容器平滑升級 SOFAMosn 給了咱們不少挑戰,咱們會先注入一個新的 SOFAMosn,而後他會經過共享卷的 UnixSocket 去檢查是否存在老的 SOFAMosn,若是存在就和老的 SOFAMosn 進行鏈接遷移,而後老的 SOFAMosn 退出。這一塊的細節較多,涉及 SOFAMosn 自身和 Operator 的交互。

image.png

SOFAMosn 的鏈接遷移

鏈接遷移的核心主要是內核 Socket 的遷移和應用數據的遷移,鏈接不斷,對用戶無感知。

image.png

SOFAMosn 的 metric 遷移

咱們使用了共享內存來共享新老進程的 metric 數據,保證在遷移的過程當中 metric 數據也是正確的。

image.png

內存複用機制

  • 基於 sync.Pool;
  • slice 複用使用 slab 細粒度,提升複用率;
  • 經常使用結構體複用;

image.png

線上複用率能夠達到90%以上,固然 sync.Pool 並非銀彈,也有本身的一些問題,可是隨着 Runtime 對 sync.Pool 的持續優化,好比 go1.13 就使用 lock-free 結構減小鎖競爭和增長了 victim cache 機制,之後會愈來愈完善。

XDS(UDPA)

支持雲原生統一數據面 API,全動態配置更新。

image.png

前期準備

性能壓測和優化

在上線前的準備過程當中,咱們在灰度環境針對核心收銀臺應用進行了大量的壓測和優化,爲後面的落地打下了堅實的基礎。

從線下環境到灰度環境,咱們遇到了不少線下沒有的大規模場景,好比單實例數萬後端節點,數千路由規則,不只佔用內存,對路由匹配效率也有很大影響,好比海量高頻的服務發佈註冊也對性能和穩定性有很大挑戰。

整個壓測優化過程歷時五個月,從最初的 CPU 總體增長20%,RT 每跳增長 0.8ms, 到最後 CPU 總體增長 6%,RT 每跳增長了 0.2ms,內存佔用峯值優化爲以前的 1/10 。

總體增長CPU  每跳RT 內存佔用峯值
優化前 20% 0.8ms 2365M
優化後 6% 0.2ms 253M
  • 部分優化措施

image.png

image.png

在 618 大促時,咱們上線了部分核心鏈路應用,CPU 損耗最多增長 1.7%,有些應用因爲邏輯從 Java 遷移到 Go,CPU 損耗還下降了,有 8% 左右。延遲方面平均每跳增長 0.17ms,兩個合併部署系統全鏈路增長 5~6ms,有 7% 左右的損耗。

在後面單機房上線 SOFAMosn,在全鏈路壓測下,SOFAMosn 的總體性能表現更好,好比交易付款帶 SOFAMosn 比不帶 SOFAMosn 的 RT 還下降了 7.5%。

SOFAMosn 作的大量核心優化和 Route Cache 等業務邏輯優化的下沉,更快帶來了架構的紅利。

Go 版本選擇

版本的升級都須要作一系列測試,新版本並非都最適合你的場景。咱們項目最開始使用的 Go 1.9.2,在通過一年迭代以後,咱們開始調研當時 Go 的最新版 1.12.6,咱們測試驗證了新版不少好的優化,也修改了內存回收的默認策略,更好的知足咱們的項目需求。

  • GC 優化,減小長尾請求

新版的自我搶佔(self-preempt)機制,將耗時較長 GC 標記過程打散,來換取更爲平滑的GC表現,減小對業務的延遲影響。
https://go-review.googlesource.com/c/go/+/68574/
https://go-review.googlesource.com/c/go/+/68573/

Go 1.9.2
image.png

Go 1.12.6
image.png

  • 內存回收策略

在 Go1.12,修改了內存回收策略,從默認的 MADV_DONTNEED 修改成了 MADV_FREE,雖然是一個性能優化,可是在實際使用中,經過測試並無大的性能提高,可是卻佔用了更多的內存,對監控和問題判斷有很大的干擾,咱們經過 GODEBUG=madvdontneed=1 恢復爲以前的策略,而後在 issue 裏面也有相關討論,後續版本可能也會改動這個值。

runtime: use MADV_FREE on Linux if available

image.png

使用 Go1.12 默認的 MADV_FREE 策略 ,Inuse 43M, 可是 Idle 卻有 600M,一直不能釋放。

image.png

Go Runtime Bug 修復

在前期灰度驗證時,SOFAMosn 線上出現了較嚴重的內存泄露,一天泄露了1G 內存,最終排查是 Go Runtime 的 Writev 實現存在缺陷,致使 slice 的內存地址被底層引用,GC 不能釋放。

image.png

咱們給 Go 官方提交了 Bugfix,已合入 Go 1.13最新版。
internal/poll: avoid memory leak in Writev

後序

SOFAMosn 在螞蟻金服經歷了雙十一的大考,後續咱們還有更多的技術演進和支撐場景,歡迎有興趣的同窗加入咱們。

image.png

SOFAMosn:https://github.com/sofastack/sofa-mosn

更多關於螞蟻金服 Service Mesh 的雙十一落地狀況解析,請繼續關注本號喲~

公衆號:金融級分佈式架構(Antfin_SOFA)

相關文章
相關標籤/搜索