導語 | service mesh 致力於做微服務時代的 TCP,以 TCP 的方式解決微服務的通信問題。那麼它解決的是微服務時代的什麼問題?以及以何種方式解決這些問題呢?本文就來和大家一同探究這個話題,文章作者:吳蘆峰,騰訊後臺研發工程師。
service mesh 致力於做微服務時代的 TCP, 它解決的是微服務架構時代的通信問題。管理和控制網絡間通信問題,解放業務團隊,提升整體研發效率。
1. 微服務時代的 TCPTCP 是網際網路的基石,首先來回顧下 TCP 對網絡的作用,再來看看微服務時代下通信面臨的問題以及 service mesh 該解決的問題,以及如何像 TCP 一樣通用化的解決這些問題。從而成為作為微服務時代的 TCP。
(1)端到端時代的 TCP網際網路能發展至今,TCP 協議功不可沒。它讓計算機真正的能夠互連互通。TCP 是提供了可靠的端到端的連接、數據傳輸方式。TCP 通過提供了
握手協議、ACK 機制、超時重傳、滑動窗口、擁塞控制算法、數據分片、數據校驗等等,實現面向連接、可靠的端到端網絡通信。TCP 不僅解決了這些問題,它還成為所有應用程式互聯的通用標準。網際網路的應用幾乎都使用 TCP 協議進行通信,可以說,沒有 TCP 就沒有今天的網際網路。TCP 協議由作業系統處理,絕大多數網絡業務進程無需處理端到端通信,對網絡協議的優化也無需更新各個應用程式的版本,只需要優化作業系統的協議即可,做到了標準化和解耦。極大的釋放了應用程式的業務迭代能力,豐富的應用程式也進一步的促進了計算機作業系統進入千家萬戶。
(2)分布式微服務時代的 TCP —— service mesh在網際網路迅速融入社會後,業務也越來越複雜。服務端需要處理的業務越來越多,幾個大型伺服器完全無法滿足業務運營的需要, 業務開發團隊也是動輒幾百、上千人。後臺的分布式架構、微服務架構開始流行,以適應複雜的業務,並圍繞獨立的業務構建團隊。隨著業務的不斷發展,微服務的數量越來越多,微服務間的通信網絡也變得十分複雜,微服務間的通信拓撲可以構成一個複雜的網絡。
在微服務架構中,一次請求往往經歷了許多服務節點。在這個角度看,服務間通信已經不在是端到端的調用了,而是"多個節點訪問多個節點"的關係了。在處理分布式微服務架構中"多個節點"的互相通信上,需要解決這些通用的問題:
服務註冊、服務發現;
負載均衡;
彈性能力(熔斷、限流、降級、超時、重試等);
安全(認證授權);
service mesh 要做微服務時代的 TCP,也就是在解決上述問題的基礎上,還要做到通用化、標準化,解耦合業務進程與 mesh。讓通信過程在微服務間變得簡單、可靠。下圖是 TCP 需要處理的問題以及 service mesh 需要處理的問題:
將這些能力與業務進程剝離,是 service mesh 和成為新一代 TCP 的理念。這樣有利於通信過程的標準化、通用化,讓業務開發無需關心通信過程,從而進一步解放業務的迭代效率。
2. 分布式微服務的通信發展史service mesh 這個詞彙在 2016 年出現。但是服務間通信的相關技術早在網格計算機系統時代就開始發展了。從計算機設備端到端通信的發展開始,經歷過以下階段:
(1)框架、庫以 Spring Cloud 、Dubbo 為代表的框架,與語言強相關相關,必須框架支持的語言,或提供各語言庫函數,才可以進行微服務通信。它們需要和業務代碼一起編譯進入業務進程,在進行框架、庫的更新時,將會十分痛苦,需要更新所有的相關業務服務。
(2)proxy 模式在分布式伺服器上,nginx 、HAProxy 等代理早就提供了終端訪問伺服器的負載均衡,它們同樣也可以用於微服務間的通信,實現服務發現、負載均衡等相關功能。且 proxy 模式下,只需要接受網絡報文即可,然後會將其轉發到對應的服務上,與調用方、服務進程的程式語言無關,無需提供特定 API、SDK ,透明性更好。但傳統的代理 nginx、HAProxy 等功能較簡單,對於經常伸縮的微服務節點,使用也十分受到限制。
(3)sidecarProxy 模式的功能較為簡單,並不能完全代替侵入式的框架。sidecar 模式則在 Proxy 模式上進一步改進,它的實現往往是在 Proxy 的請求轉發的基礎上,利用框架類庫進一步實現微服務框架具有的各種功能,如服務註冊、熔斷、重試等。sidecar 模式由於其解決的問題思路,一般是針對特定的基礎架構設計的,它的通用性具有一些局限性。但相比於傳統的框架如 Spring Cloud,它是將對應的 SDK 運行於 sidecar 進程上,當對相關庫進行更新時,只需要更新 sidecar 進程即可,不會影響到業務進程。
(4)service meshsidecar 模式的存在更多的是為了兼容已有的分布式系統,從而慢慢轉向 service mesh 理念,將流量交給"微服務時代的 TCP"。service mesh 的通信流程大致如下:
可以看到,service mesh 相比於傳統的 l5 以及當前的 polaris,業務服務調用流程上少了一步,只需要將請求轉發給 service mesh 即可,它將直接轉發到對應的業務服務。
在 service mesh 處理了這些請求、響應的轉發之後,由於流量都經過 service mesh ,這就可以很方便的對這些流量進行統一管理,從而進一步提供限流、熔斷、監控、全鏈路拓撲圖生成等, 以及可以進一步針對 service mesh 層的流量進行分析處理,這些都將不需對應業務人員參與。就像 TCP 協議一樣,統一處理了超時重傳、可靠傳輸、流量控制、擁塞控制等,並可以不斷的更新優化協議機制,而業務進程不需要再處理這些,不需要業務進程發版更新。業務進程只需構造 TCP 報文交給作業系統即可,端到端的優化則可以通過優化 TCP 處理。而 service mesh 也一樣,對於分布式微服務之間的服務調用流量的進一步分析、管理功能的迭代,不需要更新業務服務、發版處理,解放業務開發人員,也解放微服務治理基礎能力開發人員。但目前 service mesh 也存在一定的問題,大規模的實踐並不太多,騰訊內部的業務實踐上也並不多。所有流量有 mesh 層統一處理,也帶了了性能上的質疑, 不過這將被技術解決,它的優點和趨勢是十分明顯的。
(5)微服務通信治理在微服務這樣的分布式系統環境下,需要通過各種方式完成如下功能:
服務註冊: 節點啟動後,對外註冊提供服務,使得其它業務方可以調用節點的接口。
服務發現: 當業務節點需要訪問分布式的服務方時,可以通過服務發現功能獲取目標節點的 IP,完成網絡訪問。
負載均衡: 通過不同的負載均衡策略,可以將訪問分發到分布式的各個節點上,增強服務方集群的容量。
限流: 單體的節點的負載能力有限,限流可以保護服務方不至於流量過大,對節和集群加一層保護措施。
熔斷: 若服務方的響應時間過長或不可用調用過多,及時熔斷的熔斷可以提升整體的可用性。
降級: 熔斷後,業務方可以選擇進行降級處理,進行不處理或簡單處理,保證整體可用性。
自動擴容: 根據訪問量的增加,自動調整服務方集群節點數量,提高服務端的容量。
自動故障隔離: 當系統內部組件出現故障後,故障隔離措施可以將故障範圍控制在局部,防止故障範圍擴大,增加對上層系統可用性帶來的影響。
自動業務恢復: 熔斷、降級等處理後,可以及時根據系統情況恢復正常。
監控: 對微服務、容器、機器、業務進行監控,了解系統的狀況以便於進行相應調整。
日誌: 收集日誌用於復盤分析。
流量鏡像等: 將線上的流量複製一份到特定的環境中,用於對訪問內容進行分析。
service mesh 則在對流量透明轉發的基礎上,提供這些通用的能力。
3. 為什麼需要 service meshkubernetes 技術將微服務的架構推向主流,讓所有語言都可以以容器形式部署,提供微服務功能。而跨語言的微服務間通信將比 Spring Cloud 等語言相關的框架更加複雜,kubernetes 雖然提供了 service 代理層通信,提供了服務發現、服務註冊、負載均衡的基礎功能。但是認證授權、可觀測性、鏈路追蹤、熔斷、降級、限流等業務發展不斷龐大後都需要的微服務通信治理功能卻依然不足。若解決這些功能的代碼開發工作放在業務工程內,編譯進業務代碼,那就不可避免的需要進行編譯、發版甚至測試流程,對於通用能力的進一步迭代更新,比如流量分析,則需要更新發版所有業務進程。而且對於跨語言的微服務,通用的框架能力還需要提供多語言版本。而對於熔斷、限流等的規則配置,則分散於不同的業務配置中,不利於統一管理。這些通用的且業務相關性不大的微服務能力,能不能更加通用的進行維護、中臺化?將所有的流量都交給 service mesh 這一透明代理層,對流量的管控不在需要業務進程處理,相應的微服務間訪問的通用能力也交由 service mesh 層處理即可,包括認證授權、熔斷、降級、限流、監控追蹤等。對於流量的進一步分析、控制,也只要更新 service mesh 層,無需業務開發人員過多關注,交由相應的開發人員即可。比如利用 service mesh 層完成流量的灰度、管控特性分支、生成拓撲圖、統計異常訪問等,均可以做到業務進程無關。這樣可以極大的解放業務開發人員。
1. L5 名字系統L5 名字系統誕生較早,主要是在分布式架構下提供統一的服務發現、服務註冊以及負載均衡功能,它誕生時,還沒有 kubernetes,微服務還沒有如今這樣流行。它主要是在虛擬機時代通過 L5 Agent 進程協助業務進程進行服務註冊與發現,從而讓分布式系統能夠向用戶提供更好的服務端能力。L5 提供的名字系統能力主要流程如下圖所示:
L5 在流程上, 給業務進程提供的主要是服務發現、服務註冊功能,讓分布式的業務伺服器能夠找到指定服務的 IP,並通過 IP 的分發控制提供負載均衡功能。最終服務的調用是通過兩個業務服務的 IP 進行訪問的, 業務服務調用的網絡報文不會經過 L5 Agent 及 L5 Server 。
這樣,流量將直接由分布式的業務服務 A 與業務服務 B 直接建立連接。需要業務進程自行處理通信過程,涉及認證、請求、響應等。即使交給框架處理,跨語言的微服務間調用也需要跨語言的框架支持,而通用能力的更新,則需要更新業務進程發版處理,維護成本極高。並且,由於所有的流量是微服務間建立通信的,它們的調用鏈路也是不易於全局化的。
2. polaris 新一代名字系統polaris 作為誕生在 kubernetes 分布式微服務架構廣泛應用之後的雲原生時代,在架構上首先兼容了老的 L5 名字服務,以兼容騰訊內部的老業務服務,同時提供了統一的微服務功能包括限流、熔斷等能力。在未來規劃上,也考慮了 sidecar、mesh 能力。在將公司內的所有老 L5 業務系統的能力兼容遷移到 polaris 上之後,相信後續的 mesh 能力的接入也可以更加平滑。當前 polaris 的調用流程還是與 L5 類似,polaris server 將業務服務的 ip 返回,業務進程間建立連接。但是 polaris 提供了跨語言的統一 sdk,接入 polaris 的團隊在後續的更新上,可以更加統一,若 polaris 支持 mesh 能力,老服務的遷移改造對業務的影響可能會更小。
L5/polaris/k8s service/service mesh 對比L5、polaris、k8s service、service mesh 都提供了微服務之間的通信功能。以下是一些對比:相比較而言,在後續的發展中, service mesh 在通信治理的功能上更易於擴展,能力將會更加強大,同時由於其透明代理的特性,與業務的耦合極低。在業務 service mesh 化後,業務進程只需通過傳統的 tcp、http 進行通信即可,對於進一步的微服務的流量管控,都交給 service mesh 處理,而升級也將只影響 service mesh 代理層,業務進程可以無感知。
第二代 service mesh 誕生在 kubernetes 之後,它的代表是 istio。下面將在騰訊 tke 平臺上部署 istio 的 demo,讓多個跨語言的服務進行通信。除了利用 kubernetes service 提供的服務發現、服務註冊、負載均衡之外, istio 進一步通過流量的管控,生成了可視化的訪問拓撲圖,展示訪問路徑、訪問的成功失敗數。同時通過對 http header 中的 cookie 的分析,實現對特性分支的訪問,以完成灰度功能。目前騰訊內部的服務通信依然依賴於 L5,istio 目前並沒有在騰訊大規模實戰。polaris 作為新一代名字系統,雖然沒有做到 mesh,但兼容了 L5,讓 L5 業務無縫遷移到 polaris,並進一步實現了對微服務進行管控的功能,包括熔斷、限流、訪問統計等。同時,在 polaris 的規劃上,也有 sidecar、mesh 的信息。兼容老的業務系統形式,也是 service mesh 應用上的一大問題。
1. 新一代 service mesh 之 tke istio 體驗(1)demo 部署通過商城服務的 demo 演示,可以體驗 istio 提供的流量管理功能。主要配置可以參考文檔 Istio 服務 demo 演示【1】。https://zhonghua.io/2019/06/26/tke-mesh-demo/?from=timeline&isappinstalled=0
demo 演示中提供的商城 demo 服務涉及數十個微服務,並包括 nodejs、go、java、python、ruby 等各種程式語言,如下所示:
這樣的跨語言微服務之間的調用,若是基於框架完成微服務間的調用,則框架必須支持各個語言的版本,在更新框架時也必須更新各個語言版本,這給框架編寫維護帶來了極大的工作量。而框架的發展情況也將限制業務在功能上的開發。
基於商城微服務的 istio 部署,可以體驗 istio 的在通用透明性、流量轉發、流量控制、可觀測性方面帶來的優勢功能。主要部署步驟如下:
選擇支持 istio 功能的 tke 集群;
部署各個功能的 workload;
為每個 workload 建立 service ;
建立邊緣代理網關作為流量入口,創建服務網關定義邊緣代理網關的流量行為;
為 service 創建 destination rule 用於後續的分支版本控制;
創建 virtual rule 匹配到不同版本的後臺服務,實現按條件進行的分支控制,將流量轉到不同的微服務分支;
通過 virtual rule 基於流量控制實現權重路由和灰度發布。
(2)透明代理istio 基於 k8s service 的透明代理可以讓訪問方對 service mesh 層是無感知的,客戶端無需關心 service mesh 層處理的服務發現、服務註冊、負載均衡等功能。只需將迭代工作放在業務上即可。demo 演示中,客戶端直接通過 k8s service 提供的域名進行 基於 http 協議的訪問,無需關係有多少服務方、服務方版本等問題。
(3)可觀測性 - 拓撲圖與訪問統計在頁面上訪問商城主頁後,istio 通過流量的監控生成了網絡拓撲圖, 如下圖所示:
istio 通過流量的管理,可以對訪問的時間、成功失敗率進行統計:
同時也可以精確的看出每個 pod 的具體訪問數據,可以方便的看到用戶的全局訪問鏈路:
(4)流量級灰度控制在開發測試過程中,不同需求開發在測試、發布階段往往需要將特殊 pod 與基準服務 pod 進行聯合調試,通過 virtual rule 和 destination rule 的配置規則,可以精確的將特性流量轉到不同的微服務的指定特性 pod 上。通過 istio 可以快速構建下圖所示的基準環境、分支特性環境的通信過程,適應業務的需要。
istio 支持配置根據流量內容轉發,可以通過自定義截取 http 協議中如 cookie 內容,對流量進行灰度轉發,控制分支特性。demo 示例部署了根據用戶進行分支轉發,將 user=jason 的用戶的 recommend 轉到 v2 分支上,其它基準環境不變,最終訪問的拓撲圖如下:
在正式環境中,可以通過不同版本的轉發策略,實現流量級別的灰度升級,它的灰度粒度相比 tke 的 pod 級別的灰度,更加細緻,同時灰度策略也可以更加靈活,可以定義包括 cookie、header、url 等各種方式的灰度策略。
2. polaris 體驗L5 作為騰訊內部的名字系統服務,目前已經被 polaris 兼容替換。sidecar、service mesh 的支持也在 polaris 的架構規劃中。但目前業務還是以兼容 L5 的訪問形式進行。對比 istio, polaris 誕生於騰訊內部, 內部業務未來通過 polaris 切換到 service mesh 比 istio 會更加容易。
(1)L5 兼容L5 的服務端已經完全被無感知的替換到了 polaris,利用 polaris 的別名兼容 L5 的 modid:cmdid 的訪問形式,使得業務側可以沒有太多的感知。業務團隊也依然可以按照原來的方式進行後臺的業務迭代。
(2)標準化 SDKpolaris 提供的標準化的 sdk ,支持了 go、cpp、java、python 等絕大多數語言。標準化的 sdk 維護相比各自團隊的獨立的框架、sdk,在微服務調用時,跨語言、跨平臺的維護成本更低。
(3)微服務治理功能目前的 polaris 雖然在底層通信方式上雖然依然和 L5 類似,除了支持基本的服務發現、服務註冊與負載均衡, polaris 也提供統一面板管理微服務通信,支持了熔斷、限流、健康監控等微服務治理的功能。
(4)未來規劃從 polaris 的規劃看,sidecar、service mesh 都在 polaris 的支持中。相信在 polaris 支持 mesh 的過程中,對業務的改造工作量應該會更少、改造成本更低。
網際網路業務依舊在快速發展,越加融入日常生活,業務也更加複雜,業務量也更多。對於團隊的迭代、架構也造成了影響。目前主流的服務端的微服務架構便是在業務複雜性、團隊複雜性的基礎上的新一代架構,適應團隊隨業務的快速拆分、迭代。微服務化也帶來了新的通信問題。需要普遍處理
服務註冊、服務發現、負載均衡、熔斷、限流、降級、可觀測、認證授權、流量分析、監控統計等。而以 service mesh 通用化的形式處理微服務通帶來的能力,集合了世界各大企業的智慧理念,已經成為了趨勢所在。對於已經微服務化的服務架構團隊,能否向 TCP 一樣支持、處理微服務化帶來的通信問題以及改造已有業務的成本是當前主要考慮因素。polaris 目前更適應於騰訊內部業務,能夠兼容業務的 L5 通信方式,也提供了基礎的微服務治理功能, 在未來規劃上支持 sidecar、mesh 能力。對於業務團隊支持 mesh 上,預期遷移重構成本會更低。istio 則是新一代開源 service mesh 產品的代表,它是目前 service mesh 的標杆產品,在功能支持上可以快速接入各種社區產品,但適應和改造已有業務的成本會更高,同時 istio 在性能、生產實踐上也是待探索的。
參考文章:https://cloud.tencent.com/developer/article/1194147https://hezhiqiang.gitbook.io/kubernetes-handbook/ling-yu-ying-yong/service-mesh/the-enterprise-path-to-service-mesh-architectures/comparing-service-mesh-technologies
[3] Service Mesh——後 Kubernetes 時代的微服務:https://jimmysong.io/blog/service-mesh-the-microservices-in-post-kubernetes-era/
[4] Service Mesh:什麼是Sidecar模式:https://www.jianshu.com/p/626f9313e2bfhttps://www.servicemesher.com/blog/service-mesh-architectures/
[6] Sidecars and DaemonSets: Battle of containerization patterns:https://wecode.wepay.com/posts/scds-battle-of-containerizationhttps://skyao.io/learning-servicemesh/introduction/evolution.htmlhttps://zhonghua.io/2019/05/31/istio-protocol-extention/[9] Service Mesh——後 Kubernetes 時代的微服務:https://jimmysong.io/blog/service-mesh-the-microservices-in-post-kubernetes-era/
[10] 分布式架構發展史 Service Mesh:http://www.soolco.com/post/44185_1_1.htmlhttps://wewld.com/2018/07/09/%E5%BE%AE%E6%9C%8D%E5%8A%A1%E7%9A%84%E5%8F%91%E5%B1%95%E5%8E%86%E7%A8%8B/https://www.cnblogs.com/arthinking/p/12812786.html