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

支付寶技術團隊發表於2019-12-25

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

揭秘 2019 Service Mesh 雙十一大考

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

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

Service Mesh 基礎概念

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

Service Mesh 帶來的好處不再贅述,我們來看下螞蟻金服的資料面和控制面產品:

  1. 資料面:SOFAMosn。螞蟻金服使用 Golang 研發的高效能網路代理,作為 Service Mesh 的資料面,承載了螞蟻金服雙十一海量的核心應用流量。
  2. 控制面:SOFAMesh。Istio 改造版,落地過程中精簡為 Pilot 和 Citadel,Mixer 直接整合在資料面中避免多一跳的開銷。

雙十一落地情況概覽

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

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

雙十一落地資料

在如此大規模的接入場景下,我們面對的是極端複雜的場景,同時需要多方全力合作,更要保障資料面的效能穩定性滿足大促訴求,整個過程極具挑戰。

同時,Service Mesh 的落地也是一個跨團隊合作的典範案例,集合了核心、RPC、訊息、無線閘道器、控制面、安全、運維、測試等團隊的精誠合作,接下來我們會按照以上幾個模組來解析 Service Mesh 的雙十一落地情況,更多解析關注本語雀。

本文為《螞蟻金服 Service Mesh 落地實踐系列》第一篇 - 核心篇,作者:田陽(花名:烈元),螞蟻金服技術專家,專注於高效能網路伺服器研發,Tengine 開源專案核心成員,螞蟻金服開源 SOFAMosn 專案核心成員。

基礎能力建設

SOFAMosn 的能力大圖

SOFAMosn 主要劃分為如下模組,包括了網路代理具備的基礎能力,也包含了 XDS 等雲原生能力。

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

業務支援

SOFAMosn 作為底層的 高效能安全網路代理,支撐了 RPC,MSG,GATEWAY 等業務場景。


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

IO 模型

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

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

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


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

協程模型

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

  • 一條 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 團隊後續會有更多的最佳化,我們也會有一些最佳化計劃。

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

  • 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%,但是我們已經有了後續的一些最佳化計劃,敬請期待。

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

平滑升級能力

為了讓 SOFAMosn 的釋出對應用無感知,我們調研開發了平滑升級方案,類似 Nginx 的二進位制熱升級能力,但是有個最大的區別就是 SOFAMosn 老程式的連線不會斷,而是遷移給新的程式,包括底層的 socket FD 和上層的應用資料,保證整個二進位制釋出過程中業務不受損,對業務無感知。除了支援 SOFARPC、Dubbo、訊息等協議,我們還支援 TLS 加密鏈路的遷移。

容器升級

基於容器平滑升級 SOFAMosn 給了我們很多挑戰,我們會先注入一個新的 SOFAMosn,然後他會透過共享卷的 UnixSocket 去檢查是否存在老的 SOFAMosn,如果存在就和老的 SOFAMosn 進行連線遷移,然後老的 SOFAMosn 退出。這一塊的細節較多,涉及 SOFAMosn 自身和 Operator 的互動。

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

SOFAMosn 的連線遷移

連線遷移的核心主要是核心 Socket 的遷移和應用資料的遷移,連線不斷,對使用者無感知。

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

SOFAMosn 的 metric 遷移

我們使用了共享記憶體來共享新老程式的 metric 資料,保證在遷移的過程中 metric 資料也是正確的。

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

記憶體複用機制


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

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

線上複用率可以達到90%以上,當然 sync.Pool 並不是銀彈,也有自己的一些問題,但是隨著 Runtime 對 sync.Pool 的持續最佳化,比如 go1.13 就使用 lock-free 結構減少鎖競爭和增加了 victim cache 機制,以後會越來越完善。

XDS(UDPA)

支援雲原生統一資料面 API,全動態配置更新。

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


前期準備

效能壓測和最佳化

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

從線下環境到灰度環境,我們遇到了很多線下沒有的大規模場景,比如單例項數萬後端節點,數千路由規則,不僅佔用記憶體,對路由匹配效率也有很大影響,比如海量高頻的服務釋出註冊也對效能和穩定性有很大挑戰。

整個壓測最佳化過程歷時五個月,從最初的 CPU 整體增加20%,RT 每跳增加 0.8ms, 到最後 CPU 整體增加 6%,RT 每跳增加了 0.2ms,記憶體佔用峰值最佳化為之前的 1/10 。

          整體增加CPU                  每跳RT                    記憶體佔用峰值

最佳化前        20%                      0.8ms                       2365M

最佳化後        6%                       0.2ms                        253M

  • 部分最佳化措施

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


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

在 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表現,減少對業務的延遲影響。

Go 1.9.2

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

Go 1.12.6

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

  • 記憶體回收策略

在 Go1.12,修改了記憶體回收策略,從預設的 MADV_DONTNEED 修改為了 MADV_FREE,雖然是一個效能最佳化,但是在實際使用中,透過測試並沒有大的效能提升,但是卻佔用了更多的記憶體,對監控和問題判斷有很大的干擾,我們透過 GODEBUG=madvdontneed=1 恢復為之前的策略,然後在 issue 裡面也有相關討論,後續版本可能也會改動這個值。

runtime: use MADV_FREE on Linux if available

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

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

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

Go Runtime Bug 修復

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


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

我們給 Go 官方提交了 Bugfix,已合入 Go 1.13最新版。

internal/poll: avoid memory leak in Writev

後序

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

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

SOFAMosn:

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


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69904796/viewspace-2670383/,如需轉載,請註明出處,否則將追究法律責任。

相關文章