去哪兒網 Service Mesh 落地實踐:100- 容器化打底,業務友好是接入關鍵

作者 | 褚杏娟

自 2011 年引入 Dubbo 框架至今,去哪兒網的微服務架構已經有了十多年的歷史。時至今日,去哪兒網架構已經形成了 Dubbo、HTTP 協議爲主,多語言共存的格局。

根據去哪兒網基礎架構部高級技術總監朱仕智分享的數據,現在去哪兒網 Dubbo 服務接口有 18,000 多個、HTTP 域名超過 3500 個,內部大約有 Java、Golang、Node 和 Python 等 5 種語言的技術棧,其中以 Java 和 Node 爲主。此外,去哪兒網在線運行的應用大約 3000 多個、MQ 應用主題超 13,000 個。

隨着業務的不斷髮展,多語言、多協議給基礎架構團隊帶來了不小的治理問題。

首先,多語言的複雜性主要在於 SDK 的重複實現,每個治理邏輯需要開發不同的語言版本,此後還要一直對其進行維護,這是一份冗餘且負擔很重的工作。

在多協議治理上,一方面,去哪兒網內部有 Cactus 平臺對 Dubbo 進行治理,治理功能相對完善。另一方面,去哪兒網對 HTTP 的治理主要通過 OpenRestry,治理能力相對薄弱,一些必需的治理需求零散分佈在多個平臺,對開發同學很不友好。

Dubbo 和 HTTP 治理能力不統一導致了重複造輪子情況,增加了業務的開發和維護成本。

此外,業務和中間件強耦合,但業務部門與基礎架構部門對升級更新的意願並不同步。基礎架構部門不斷升級更新來完善中間件,但業務研發在不影響使用情況下並不希望頻繁更新。所以每次發佈新版本後,基礎架構團隊要花很長的時間進行推廣,致使整個迭代週期變長。

而 Service Mesh 將服務治理能力下沉到了 sidecar,SDK 只需要負責編解碼、與 sidecar 通信,通用邏輯基本不用修改,只要對 sidecar 修改就可以應用到所有語言和框架,於是在去年,去哪兒網開始組織團隊引入 Service Mesh 來解決自身多語言、多框架的治理難題。

容器化基礎

在去哪兒網資深開發工程師李佳龍看來,容器化下比較適合引入 Service Mesh。

大概從 2014 年起,去哪兒網便開始使用 Docker、Mesos、Kubernetes(以下簡稱 K8s)等來解決測試環境構建困難的問題,也逐漸嘗試基於容器部署 ES、MySQL 等中間件服務。到了 2021 年底,去哪兒網全面實現容器化,業務服務基本完成上雲。從效果數據來看,容器化虛擬比例從 1:17 提升到 1:30,資源利用率提升 76%,宿主運維時間由天變成了分鐘級,環境穩定性差、交付慢、可擴展性差和服務器成本高等問題都得到了有效解決。

經過多年積累,去哪兒網已經爲引入 Service Mesh 打下了堅實的基礎。引入 Service Mesh,本質上也是去哪兒網步入雲原生實踐新階段——多方向探索的體現之一。

在去年加入去哪兒網後,李佳龍主要負責 Service Mesh 的落地工作。團隊基於去哪兒網的現狀,明確了對新服務治理體系的期望:多語言、多協議統一治理、治理能力增強,同時可以將治理能力下沉,實現基礎組件開發週期和業務開發週期解耦。

如何做技術選型

整個實踐過程主要分爲三個階段:調研、開發和推廣。調研階段的主要任務是技術選型。去哪兒網團隊用了兩週左右的時間,調研了其他企業的落地情況。

自 2011 年引入 Dubbo 框架至今,去哪兒網的微服務架構已經有了十多年的歷史。

如何找到適合自己的產品呢?首先,由於業界已經有成熟的產品,因此去哪兒網沒有選擇重複造輪子,而是基於業內已有開源軟件進行選型。其次,去哪兒網團隊還從產品是否成熟、社區活躍度、性能是否滿足公司需求,以及開發和維護難度等方面進行了考察。

最終,去哪兒網選擇了螞蟻開源的 MOSN 作爲數據面。MOSN 經過了阿里雙十一幾十萬容器生產級別驗證,產品自身已經成熟。另外,MOSN 社區比較活躍,迭代也較快,更新週期基本維持在了兩個月左右。

語言也是重要的考慮因素。由於在 C++ 技術棧方面人才儲備有限,團隊放棄了流行的 Envoy。MOSN 的開發語言是 Go,在性能、開發、維護難度和靈活性上有優勢,雖然不是去哪兒網使用的主要語言,但開發人員入門和上手都比較快。MOSN 既可以替代 Envoy,也可以集成 Envoy 在網絡層高性能的優勢,並將其作爲自己的網絡插件使用。

控制面上,去哪兒網選擇了 Istio,並根據自身需要對其進行了二次開發。Istio 使用 XDS 協議與數據面進行交互,是很多企業的首選,去哪兒網選擇緊跟社區的腳步。但原生的 Istio 有個問題,就是和 K8s 耦合非常嚴重:主要體現在 K8s 既是註冊中心又是配置中心,以及 sidecar 注入、啓動配置和網絡模型等。這導致去哪兒網團隊面臨着以下問題:

去哪兒網希望 K8s 更多的用於服務編排,因此在最初商定方案時,選擇解耦 K8s,採用內部使用多年的註冊中心和配置中心。於一些啓動配置,則依賴去哪兒網內部的配置中心(QConfig),同時團隊自研了 McpServer 模塊替代 K8s 來對接 Istio。

整體架構

具體實踐如何?

接入 Mesh 後,業務主要關心的就是性能、治理能力和問題排查。因此在做好技術選型後,去哪兒網團隊便開始設計實踐方案,並花了數月的時間進行研發。

流量管理

目前,業界將流量從 SDK 攔截到 sidecar 的方式主要有兩種:iptables 攔截和流量轉發。但由於 iptables 的可運維性和可觀察性較差,配置較多時還會出現性能下降的問題,因此很多公司選擇了流量轉發的方式,去哪兒網也是如此。

去哪兒網主要使用了兩種流量轉發方式:一是升級 SDK,在 SDK 中直接將請求轉發到本機 sidecar;二是域名攔截,例如使用 dnsMasa 將 xx.qunar.com 的請求轉發到本機 sidecar。

李佳龍提醒道,引入 Service Mesh 後,流量安全值得特別關注,因爲之前兩個服務的調用變成了四個服務間的調用,大大增加了不穩定性。對此,去哪兒網主要採取了四方面的措施來保證流量的安全:

Sidecar 管理

對於 sidecar 的配置、部署、升級、回滾和灰度等,去哪兒網團隊將其整合到了運維面上。

以 sidecar 的升級爲例,Sidecar 的升級可以分爲兩個場景:原地升級和服務部署時升級。前者不需要重新部署服務,但需要確保升級對用戶透明、流量無損。

Sidecar 的注入和升級

對於原地升級,由於 sidecar 容器和業務容器是同屬一個 pod 的兩個獨立容器,基礎架構團隊將 MosnAgent 作爲 sidecar 容器的 1 號進程,用於管理 sidecar 的生命週期,例如啓停、健康狀態檢查和升級等。新版本發佈時,會將 sidecar 鏡像推送到鏡像倉庫,同時將二進制包推送到對象存儲。

基礎架構團隊通過 sidecar 管理平臺,可以對 sidecar 容器發送升級指令,MosnAgent 會拉取對應版本的 mosn 包,之後啓動新版本 mosn,並通過 fd 遷移機制,完成無損升級流程。

而部署時升級,發佈平臺會請求 sidecar 管理平臺來獲取 sidecar 配置,包括是否注入、sidecar 版本、環境變量、配額信息等,然後生成服務的 yaml 配置。注意在部署時,有可能遇到 sidecar 容器、業務容器的啓用順序問題。如果 sidecar 容器未啓動成功或者配置未拉取成功、但業務容器已經 ready,那麼請求就會失敗。基礎架構團隊設置成 sidecar 先於業務容器啓動,並通過配置 K8s 的 postStart 鉤子函數,來保證正確的啓動順序。

需要注意的是,Istio 下發配置時,也可能發生順序異常問題。去哪兒網團隊通過 Istio merkeltree 來跟蹤資源下發進度,通過暴露接口來查詢每個資源是否全量下發到 sidecar。

另外,運維面還負責對接內部系統,如內部配置中心、全鏈路監控系統、報警系統、鏡像倉庫及對象存儲等。

性能優化

在性能優化方面,首先由於業務容器與 sidecar 容器同屬一個 pod,基礎架構團隊選擇了使用 unix domain socket 進行通信,以此規避網絡棧、優化性能。

其次,團隊對 Dubbo 協議進行了優化。sidecar 接收到請求後的第一步是獲取路由信息,用以服務尋址。按照 Dubbo 原來的設計,路由信息 (service/method/group 等) 存放在 body 中,但爲了避免不必要的 body 反序列化,團隊擴展了內部 Dubbo 協議,將路由信息放置到了擴展 header 中。

再者,團隊選擇按需加載 xDS 數據方式。Sidecar 啓動時會請求控制面拉取 xds 數據,但是原生的 Istio 會拉取當前集羣中所有服務數據,導致 sidecar 資源佔用過多以及推送風暴,大大制約了 Service Mesh 的集羣規模,這也是很多公司落地 Service Mesh 要解決的問題。去哪兒網的解決方式是配合內部 Spring Cloud Qunar 框架,在編譯器採集訂閱關係,並擴展 xds 協議,來實現按需加載。

除了按需加載配置,基礎架構團隊也在優化推送性能,統一服務註冊模型等。

治理能力

針對之前治理功能分散、能力不統一的問題,基礎架構團隊將 Dubbo 和 HTTP 統一到了新的 Captain 平臺。

“在設計時,Captain 要儘量做到服務治理與協議無關。” 李佳龍說道。比如,之前 Dubbo 服務需要在項目中配置參數支持調權預熱、HTTP 在發佈平臺配置支持引流預熱或者自定義接口預熱,引入 Service Mesh 後就可以很方便地支持 Dubbo/HTTP 調權、引流兩種預熱模式。

此外,Captain 增強了很多服務治理能力,例如多維度的限流策略,包括基於應用粒度限流和基於優先級限流。業務團隊既可以根據應用的不同來設置不同的限流閾值,也可以根據不同的流量來源設置不同的優先級,優先處理有價值的請求。

如下圖所示,當流量達到設定的閾值時會觸發限流,這時流量會進入到多個優先級隊列,可以按照優先級處理。

此外很多情況下,業務會將超時時間、限流閾值設置得比較大或比較小,這未能起到應盡的作用,基礎架構團隊根據監控數據和合理算法,會智能推薦超時、限流等參數。

如何進行推廣

目前,去哪兒網已經在基礎平臺、機票等部門開始推廣和試行 Service Mesh。

“推廣是最爲關鍵、也是比較容易出現阻塞的地方。因爲對於用戶來說,讓系統最穩定的做法就是不輕易做變動。” 李佳龍說道。

那麼,如何讓業務更容易接受 Service Mesh 呢?去哪兒網團隊先是在內部做了關於 Service  Mesh 基本認識的分享,讓業務瞭解接入 Mesh 後都能得到哪些收益。

然後對於新服務治理平臺,基礎架構團隊也注意保留了很多業務的使用習慣。比如在實際使用中,超時時間等治理參數與路由的相關度較低,業務更習慣作爲服務提供方配置某個接口的超時時間,或者作爲服務調用方配置要調用服務的超時時間。但在 xDS 協議中,超時時間等治理參數配置在服務提供方,並且與路由綁定。因此,基礎架構團隊做了部分擴展,業務可以從服務提供方、調用方兩個角度來進行配置,並以接口爲維度,這些配置包括超時、重試、備份請求、負載均衡策略等。

便捷性對業務來說也是非常重要的,業務希望切到 Mesh 後能夠方便地查詢問題,日誌,trace,監控報警等內部系統的打通也是推廣的前提。

基礎架構團隊現在提供了兩種 Mesh 接入方式:第一種是接入新的開發框架 Spring Cloud Qunar,業務需要做部分改動;第二種是無侵入地一鍵接入,業務不需要修改代碼,這也是接受度較高的一種方式。

另外,去哪兒網提供了按照接口級別的接入方式,業務可以按照百分比來切入 Mesh,而不是一刀切地接入。基礎架構團隊的策略是讓業務先從一個小的接口、小的流量來接入,業務接受了之後再擴大接入範圍。

在李佳龍看來,便捷易用性問題一定程度上確實阻礙了 Service Mesh 的落地。

一方面,從業務角度看,使用者更加在意 Mesh 接入後是不是好用、操作是不是簡單、切換起來是不是安全和方便、需求是不是能夠滿足、能不能保留之前的研發習慣等等。另一方面,從開發角度看,企業開發 Service Mesh 時通常有很多工作,比如進行二次開發並與內部系統打通,還有諸如 xDS 按需下發,sidecar 管理等目前沒有統一標準的工作,這些都需要維護成本。公司基礎設施之間有差異,這些都需要決策者考慮清楚。

結束語

Service Mesh 不是一個很新的概念,它的本質就是解耦,具體實現起來就是語言 SDK 負責編碼以及與 sidecar 的通信,這部分比較固定,不包含治理功能。雖然還是多個實現,但是複雜度降低了一個量級,從而將更多的功能實現,抽離到獨立的 sidecar 進程,只需要實現一次。“所以本質上,解決多語言多協議的複雜問題,是分離了變與不變,這也是去哪兒網進行軟件架構時的常用方式。” 李佳龍說道。

那麼對於企業來說,是不是要容器化後才能夠接入 Service Mesh 呢?李佳龍表示這不一定。

“只能說,Service Mesh 天然比較適合容器化的場景,比如 Istio 方案默認使用者已經具備 K8s 的基礎設施了,但是我們仍然可以有多種方式支持虛機接入服務網格,只要解決掉 sidecar 注入、升級,流量攔截,服務註冊發現等。而且我們設計之初去除了 K8s 的耦合,接入虛機也變得更方便。按照去哪兒的雲原生的發展來看,容器化作爲雲原生架構的底座,在容器之上能更好的支持 Service Mesh、Serverless 等。”

就中小企業而言,李佳龍表示,中小企業首先考慮的更多是業務。業務越來越多、越來越複雜後,纔可能會出現多語言、多框架的問題。只有確實出現這個問題時,才應該開始考慮是否引入 Service Mesh。此外還需要考慮自身的基礎設施、團隊技術儲備等是否支持落地。Service Mesh 是利用低複雜的技術去解決高複雜度的問題,如果本身複雜度不高,引入 Service Mesh 這樣的技術只會增加複雜度,得不償失。

還有一個值得關注的方面就是性價比。引入 Service Mesh 的新增成本包括 sidecar 所佔有的資源,比如每個 sidecar 佔用的 CPU、內存、磁盤以及其他如 trace 存儲、日誌存儲等存儲資源。另外,像請求耗時增加、系統開發維護等會產生相應成本,因此去哪兒網目前對於各類日誌是按需開啓,只打印耗時高的 trace 信息。

” 不過目前看,Service Mesh 確實帶來了很多好處。” 李佳龍說道,“首先便是統一了多語言、多框架的治理能力,提供豐富的治理功能。另外對業務開發透明,減少了業務的使用成本。與業務解耦後,我們的推廣週期也大大縮短。”

“Service Mesh 應該會是未來的一個發展趨勢。” 李佳龍表示,“之後去哪兒網會在可觀察性、性能優化、多語言支持上持續發力。”

 嘉賓介紹

李佳龍,2021 年加入去哪兒網基礎架構部,擔任資深開發工程師,近五年專注於雲原生、基礎架構等領域,負責去哪兒內部 Service Mesh 和新服務治理平臺 Captain 的研發落地等工作。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/pG_eEg_2FpEL7zfu1l9-zg