架構不止-嚴選Service Mesh架構的持續演進

在這裏插入圖片描述

Maslow/王育鬆(網易嚴選技術團隊)node

同嚴選的業務同樣,在下層承載它的IT系統架構同樣要生存、呼吸、增加和發展,不然過期的、僵化的IT系統架構會使咱們的組織和業務陷入停頓,沒法面對新的機遇和挑戰。 這些年業界的服務端架構理念一直在持續演進,從單體模塊化架構,到SOA,再到微服務,最後到Service Mesh。嚴選服務端架構的演化正是它的一個縮影,在某些方面咱們甚至還領先於業界的發展。nginx

前言

同嚴選的業務同樣,在下層承載它的IT系統架構同樣要生存、呼吸、增加和發展,不然過期的、僵化的IT系統架構會使咱們的組織和業務陷入停頓,沒法面對新的機遇和挑戰。docker

這些年業界的服務端架構理念一直在持續演進,從單體模塊化架構,到SOA,再到微服務,最後到Service Mesh。嚴選服務端架構的演化正是它的一個縮影,在某些方面咱們甚至還領先於業界的發展。安全

架構成熟度

雖然業界沒有一種通用的架構成熟度模型能夠用來度量,但從單體模塊化、到SOA、再到微服務、最後到Service Mesh的架構成熟度級別毋容置疑是逐步上升的。性能優化

每一個級別都有一系列本身的問題,這些問題須要在下一級別來解決。markdown

不一樣級別有不一樣的複雜性,不一樣級別也有不一樣的側重點。網絡

  • 單體模塊化架構架構

    強調業務邏輯按模塊劃分,高內聚低耦合。模塊間通訊經過同進程內的方法調用進行。併發

  • 面向服務的架構(SOA)負載均衡

    強調業務邏輯在應用粒度的複用,收口和歸一散落的業務邏輯,能夠理解爲是業務邏輯的水平拆分。服務間通訊經過企業服務總線進行,總線上會耦合少許業務邏輯。

  • 微服務架構

    強調業務邏輯在應用粒度的解耦,能夠理解爲高內聚低耦合業務邏輯的垂直拆分。服務間通訊經過RPC進行。

  • Service Mesh

    強調業務邏輯與服務治理邏輯的分層及解耦,這是另一種層面的分層和解耦,在業務邏輯和基礎實施邏輯間劃分出清晰的邊界。Service Mesh架構下,服務間通訊經過網格進行代理。

    全部這些架構模式無一不在強調解耦和複用,而Service Mesh是全部架構模式中解耦和複用最完全的,它不只僅強調業務邏輯的解耦和複用,更強調基礎設施的解耦和複用。

什麼是Service Mesh

先來看Service Mesh的定義,這個定義是Service Mesh的先驅公司Linkerd的CEO William提出來的。

Service Mesh是一個基礎設施層,用於處理服務間通信。雲原生應用有着複雜的服務拓撲,服務網格負責在這些拓撲中實現請求的可靠傳遞。在實踐中,服務網格一般實現爲一組輕量級網絡代理,它們與應用程序部署在一塊兒,而對應用程序透明。

這個是Service Mesh比較早期的定義,如今Service Mesh涵蓋的範圍更大更廣。在微服務體系裏面,除了服務自己以外,其它的服務相關的可管理可治理的的部分均可以理解爲是Service Mesh的範疇。

因此Service Mesh歸根結底是一個服務治理平臺,它基本上包含了服務治理的全部方面。

這些經過Spring Cloud這種全家桶的方式也能實現,可是與業務邏輯耦合在一塊兒,部署、運維都耦合了微服務自己的操做。好比一個RPC框架的bugfix會引起全部微服務曠日長久的升級發佈,同時帶來業務開發人員開發、測試、迴歸、發佈的巨大重複工做量。

Service Mesh經過將與業務邏輯無關的服務治理邏輯下沉,讓業務開發人員與基礎技術開發人員關注點分離,各司其職,大大提高了研發效能。

業務開發人員更關注的是對業務的理解、建模,他們的核心價值體如今業務實現上。Spring Cloud/Service Mesh之類的服務治理平臺對於他們來講只是工具和手段,而不是終極目標。在這些工具的學習和使用上耗費大量時間和精力成本對他們來講得不償失。

基礎技術開發也能專一於本身的技術領域,不須要爲了推進技術的升級換代而去理解、學習業務,不須要耗費大量時間精力去協調和推進業務的變動,不須要共擔業務線上變動的風險和壓力。

第一代-基於Consul+Nginx的嚴選版Service Mesh

嚴選/郵件版Service Mesh(也即Consul+Nginx,後簡稱cNginx)誕生之時,Service Mesh的概念尚未提出,你們也沒想到當初作的那些事情居然讓他們成爲Service Mesh的先行者。

當初的想法很簡單:爲跨語言業務應用提供無侵入性的基於Consul的服務路由功能。並利用 Nginx 的原生特性,在高性能的前提下提供負載均衡、集羣容錯等機制。

當時所作的主要工做是對consul與nginx的擴展開發,把這2個組件的能力融合在一塊兒,以解決咱們遇到的問題。

嚴選版Service Mesh總體架構

  • 數據面

    以consul client+cNginx 組成咱們的sidecar,這裏的sidecar模式是單向的client sidecar模式,當時咱們關注的問題單sidecar的模式已經徹底能解決。

    在數據面實現的服務治理能力主要以nginx爲基礎。

    • 負載均衡

    • timeout治理

    • 重試

    • FailOver

  • 控制面

    控制面也即咱們的consul admin管理平臺,有3大模塊,分別實現各自職責邊界內的服務治理能力。

    • 流量調度

      對流量進行調度、路由、流量權重、泳道隔離等操做。

    • 服務註冊/發現

      對服務實例進行上線、下線、剔除、健康檢查等操做

    • 限速&熔斷

      對服務調出在調用方進行速率限制或直接熔斷。

架構收益

經過融合Consul+Nginx的功能,咱們建設了簡單服務治理能力,落地了簡版的Servcie Mesh。

cNginx對業務應用透明,由基礎技術團隊統一開發、部署和運維,其實現的服務治理功能不須要各個業務方重複去建設或從第三方引入,能夠將更多時間專一於本身的業務邏輯。

同時在跨語言的多個應用之間,咱們建設了統一的通訊層,保證了通訊策略的一致性落地。

成本方面,咱們也節省了框架性中間件(好比RPC框架)的研發和投入,下降了中間件與業務代碼之間額外的耦合成本。

第二代-基於istio的Service Mesh

隨着業務的快速發展,cNginx實現的簡版服務治理能力已經不能知足咱們日益增加的需求。

而云基礎設施的成熟讓雲原生架構愈來愈具備普適性,嚴選也在基於輕舟落地咱們的容器雲戰略,cNginx沒法與k8s、docker等雲基礎設施有效融合,必須選擇新的Service Mesh平臺進行替換。

毫無疑問,咱們的最終的選擇的是istio,當前Service Mesh的事實標準。

istio總體架構

istio在架構上一樣分爲數據面和控制面兩大塊。

  • 數據面

    數據面控制服務全部進出流量,並植入服務治理邏輯。數據面同時負責控制面制定的策略的執行,並上報遙感數據至控制面。

    istio數據面默認的sidecar爲envoy,envoy是L4/L7的高性能網絡代理組件。

  • 控制面

    控制面由Pilot、Mixer、Citadel、Galley四部分組成。

    • Pilot

      提供服務發現、流量動態路由和服務間的彈性能力(超時、重試、速率限制、熔斷等)。

    • Mixer

      承擔ACL、策略執行、黑白名單等職責,並收集服務遙感數據。

    • Citadel

      提供安全證書下發和管理的能力。

    • Galley

      Galley提供抽象的、統一的配置校驗能力。

一些重要決策

1.Client Sidecar模式

istio自己提供了3種sidecar的模式:Client Sidecar、Server Sidecar、Both Sidecar,通過權衡,咱們最終決定暫時使用Client Sidecar的模式,只在服務調用方啓用sidecar,緣由以下所述。

  • 模式上的繼承性

    嚴選第一代Service Mesh的實現cNginx也是 Client Sidecar的模式,而第二代istio原本就是一個很新很前沿的的東西,爲了下降你們理解上和使用上的複雜性,同時讓業務進行無縫對接,咱們對第二代Sidecar模式的變動暫時採起了保守的態度。

  • 性能考慮

    從咱們的壓測結果來看,istio client sidecar 模式與cnginx相比略微差一點,而both sidecar的模式因爲網絡上多了一跳性能也有更多的折損,爲了避免讓業務方在響應性、吞吐量等感知上出現過多的變化,咱們暫時選擇了client sidecar模式。

  • 治理能力的差異

    Client模式與Both模式在治理能力上的差別部分,咱們現有的基礎設施都可以補足。好比服務可觀察性,咱們有完善的APM平臺和日誌平臺。因此在治理能力上咱們並不Care Server端是否啓用了sidecar。

2.按需使用

istio就像一把瑞士軍刀,它提供的功能很是很是多,初次使用它你可能會陷入迷茫。

嚴選對istio的使用一直秉承按需的原則,咱們初期只要求使用和cnginx對等功能,後面再逐步覆蓋其它功能。

對於一些目前版本istio的實現上有性能問題的功能,咱們是堅定棄用的。好比Mixer的策略執行功能,由於每一次調用envoy都會同步調用Mixer進行一次策略檢查,致使性能降低的很是迅速。關於這一點,社區也已經意識到並着手進行優化了,優化完成後咱們會考慮使用。

做爲Mixer的策略執行的替代品,istio的rbac也是能夠知足一部分功能的,好比服務白名單咱們就是經過rbac來實現的,這樣就避免了Mixer的性能陷阱。

3.與k8s融合

Service Mesh自己是平臺獨立的,但與k8s融合有很是多的優勢,已經逐步成爲了業界主流的標準(也即雲原生架構),嚴選也採用了這種方式。

  • sidecar自動注入,自動接管流量
  • 一致的服務發現,統一基於K8S數據作服務發現
  • 治理規則基於K8S CRD,無需專門管理服務
  • 服務發現無需主動註冊,聲明爲k8s service便可自動注入

過渡期架構方案

過渡期會存在cNginx(雲外)與istio(雲內)兩種類型的Service Mesh共存的狀況,爲了讓業務無感知,咱們設計了過渡期的架構方案。

  • 對於雲內服務來講,若是服務提供方沒有在雲內部署,則自動兜底路由到雲外服務。
  • 對於雲外服務來講,雲內服務提供者統一抽象成雲外服務的一個邏輯服務實例,往雲內的導流經過cNginx控制這個邏輯服務實例流量權重便可。

性能陷阱

Service Mesh最受人誤解而詬病的是它的性能問題,不少人認爲調用路徑上網絡多了一跳/兩跳就以爲Mesh性能會不好。從咱們的實踐和壓測來看,只要咱們作好抉擇和裁剪,Mesh的性能問題並無那麼恐怖。

  • 1600rps+40個併發(主機配置均爲8C16G)

從壓測數據來看,在40個併發基礎上,rps在1600(注:單機1600rps對於嚴選的業務來講,容量的冗餘已經很是充分了)時,istio(client模式)的RT overhead是0.6ms左右,cnginx的RT overhead在0.4ms左右。istio和cnginx的性能差異很是小,基本上能夠等價。

並且Spring Cloud/dubbo這種框架自己也會引入資源開銷、性能開銷,因此替換成Service Mesh只是對性能開銷進行了轉移支付,性能影響相較而言就更小了。

嚴選使用的istio是杭研版的istio,當前杭研同窗正在對istio的性能作更深一步的優化。目前性能優化後初步測試結論以下。

  • 方案1:採用eBPF/xDP(sockops),優化路徑爲SVC <-> Envoy,延遲性能提高10-20%。Envoy部署方式per-pod,跟社區方向一致,也是目前嚴選採用的部署方案。
  • 方案2:採用DPDK+Fstack用戶態協議棧,優化路徑爲Envoy <-> Envoy,延遲性能提高0.8-1倍。Envoy部署方式爲per-node,功能和運維層面的限制還在評估當中。

固然性能問題依然是個很核心的問題,因此咱們會建設咱們的常態化壓測機制,對任何變動都進行壓測迴歸。

總結

從cnginx到istio,咱們的服務治理能力和治理體系化實現了與時俱進和現代化。

架構落地的收益最終都是經過研發效能來體現,經過Service Mesh架構持續實踐和落地,咱們解耦了業務邏輯和基礎設施邏輯,進一步解放和發展了生產力,驅動了業務更好更快的發展。

網易技術熱愛者隊伍持續招募隊友中!網易嚴選,由於熱愛因此選擇, 期待志同道合的你加入咱們, Java開發簡歷可發送至郵箱:lizhuo01@corp.netease.com

相關文章
相關標籤/搜索