TARS、gRPC、Service Mesh……究竟哪個微服務框架適合你?

  • 2020 年 3 月 16 日
  • 筆記

近日,雲+社區技術沙龍「騰訊開源技術」圓滿落幕。本次沙龍邀請了多位騰訊技術專家,深度揭秘了騰訊開源項目TencentOS tiny、TubeMQ、Kona JDK、TARS以及MedicalNet。下文是田甜老師關於TARS的演講整理

目前開源界的微服務框架大體可以分為以下四個種類

第一類是無服務治理的,這一類基本可以看做是一個RPC框架。RPC發展到現在已經有幾十年的時間了,主要代表為gRPC、BRPC、Thrift,它們也都有對外開源的程式碼。

第二類是帶治理功能,但是語言比較單一,主要的代表是以Java為主的Spring Cloud、dubbo等。

第三類就是Service Mesh,主要代表產品是Linkerd和ISTIO,這是未來的發展方向。

最後就是TARS,不僅支援多語言,還附帶一些服務治理相關的功能產品。

一、TARS 架構體系

1. TARS簡介

TARS是騰訊從2008年到今天一直在使用的後台邏輯層的統一應用框架TAF(Total Application Framework),目前支援C++、Java、PHP、Nodejs、Go語言。

該框架為用戶提供了涉及到開發、運維、以及測試的一整套解決方案,幫助一個產品或者服務快速實現開發、部署、測試,以及上線。

它集可擴展協議編解碼、高性能RPC通訊框架、名字路由與發現、發布監控、日誌統計、配置管理等於一體。通過它可以快速用微服務的方式構建自己的穩定可靠的分散式應用,並實現完整有效的服務治理。

2. TARS整體架構

TARS的架構如下圖所示:

Devops相關方面,主要有程式碼管理、程式碼編譯和自動化測試等等,底層還有OSS的服務治理。

支援協議方面,主要基於自身的TARS協議,另外一些其他自定義的協議也可以支援。

服務治理的功能較為豐富,包括大家常用的服務註冊、負載均衡、熔斷、服務配置等等,這些都是在我們線上做分散式服務管理的時候要做的。

TARS支援五大程式語言,其中包括C++和JAVA、nodejs和PHP和GO,也可以擴展其它語言。

3. 服務治理

對於服務治理,其實最重要就在於客戶端和服務端之間的調用。我們的客戶端調用服務端是通過registry 來實現的,registry 中文名字叫做主控。

客戶端在調用的時候會去 registry 做請求,後端有一個 SDK 管理所有的協議,這個 SDK 可以對服務進行監控統計,全部自動完成。

(1) 自動區域感知

調用 logsvr 的時候,用戶請求主控拿到節點列表並直連。這裡需要指出,基於路由的規則,我們需要把網段註冊成一個地區,從而實現自動區域感知

這是因為在線上業務當中,會出現一些問題。如果一個服務部署到同一地區的不同區域以後,它的跨機房時延在4毫秒左右。如果是跨城市、省份的話可能高達到40毫秒,所以如果我們同機房有部署的話,就會盡量訪問自己機房,這樣可以提高性能,減少訪問耗時。

綜上,常規的負載均衡方式面對跨地區或者跨機房部署的服務,會因為網路原因造成延時增大,使用不同服務名來解決該問題時也會帶來繁重的運維工作,而通過 Registry 和開發框架配合實現自動區域感知可以自動完成相關的工作。

(2)  SET模型   

SET模型是騰訊運用比較廣泛的體系,因為當容量大到一定程度之後,一個服務發布的過程中也許能影響到全區的服務。例如手機QQ的用戶基數上億,一點微小的變動都會產生深遠的影響,因此我們設計了SET模型。

如上圖所示,假設該模型有300萬的容量。如果單個地區容量過大會導致整個容量過載,所以將它分成三組,6個服務,每個服務自我調用。但是這種服務開發成本相對比較高,如果要再擴增100萬容量的話,需要建更多組服務才可以實現。

通過框架處理可以很好解決上述問題,為了以示區別,我們在服務A、B前加上標識Set。通過縱向割裂,將300萬以100萬/個SET的單位分成3組,每一個SET負責100萬的容量,未來業務容量超過了300萬接近400萬時就只需要加一個SET就可以了。

該場景主要是防止故障擴散,如果其中一個場景在迭代的時候出現了問題,只會影響指定SET的100萬的用戶,不會影響到其他200萬的客戶。

(3)流量控制

關於流量控制,其實在分散式架構方面也會存在一些問題。比如說,我們經常發布節點,如果按照節點一個一個發布的話,即使服務部署得非常多,但因為流量較大,單個節點存在的用戶也會比較多。

這時可以通過權重設置做到無損發布,例如通過權重指定某一個節點的流量只有10%,以此來控制流量。

在發布的時候,經常會出現重啟導致流量丟失的現象。面對這種情況,我們可以先把流量調為0,發布完成之後,再調回來,這樣就可以實現部分按需流量的控制,這也是在大規模線上應用比較常用的解決方案。

(4)分散式跟蹤   

當有用戶回饋說某項服務訪問比較慢的時候,我們就需要知道用戶相應的用能耗時。這種情況下,如果只是通過相應的數據去排查的話,是比較困難的。

因為在一個微服務下面,一個請求可能會跳多次,所以無法預測到一個服務具體走的跳數,這時候就需要通過分散式跟蹤來進行鏈路追蹤。TARS有一套比較完整的體系,從接入到存儲都可以自我實現。

(5) 服務配置管理

關於服務配置管理,我們分了四級,分別是應用級配置、SET配置、服務配置和節點配置。

做分散式架構,最難的點就是運維可視化。這樣做不僅能讓部署和發布更加方便,還能將開發和運維分離,不需要開發接入,一些流程化操作可以尋求外包人員,這樣也減輕了人力成本。

TARS的產品應用比較完善,在某些技術上甚至處於領先地位,目前應用在很多大規模應用上也很少出問題。

二、gRPC架構體系

gRPC主體是一個RPC框架,同樣也定義了負載均衡策略。

gRPC主要基於Protocol Buffers 框架,Protocol Buffers 是Google出品的序列化的框架,與開發語言和平台都無關,具有良好的可拓展性,可用於數據存儲和通訊協議。

gRPC官方介紹雖然簡單,但實際在線上應用時需要腳本和參數。所以我們做了一個腳手架,通過這個參數生成程式碼。

因為gRPC線上只提供了標準的介面,並不直接提供程式碼。很多服務治理的服務,比如日誌、ACL這些全都得自己實現。

gRPC可以實現多數語言的程式碼客戶端生成,但是如果想要使用的話還需要做出一些改造,完成相應協議的互轉,最後還需要開發常用內部服務SDK來降低使用成本。

服務的實現主要依賴於gRPC攔截器的實現,通過攔截器可以實現遠程日誌、監控上報、鏈路追蹤等服務。gRPC可以在RPC調用前觸發註冊的攔截器,在調用前可以執行遠程日誌上報等等功能,通過多種攔截器串列,實現一個攔截器鏈路,最終實現各種插件。

關於Protocol Buffers插件系統,它可以做到一些簡單的增強。我們在自己的項目中把Protocol Buffers作為一個描述語言,當介面完成時,通過Protocol Buffers的插件功能將開發文檔轉成swagger,這樣的話與前端互通就會變得非常方便,這些程式碼和文檔就可以一下子自動生成。

關於gRPC的周邊生態,它主要依賴於Protocol Buffers,擁有龐大的插件集合,可以轉換出任何的語言,包含Tars協議。gRPC現在應用的場景也已經非常廣泛,主要是在雲原生方面。

gRPC也和TARS一樣,存在著一些問題,就是它們需要用戶改造過以後才能使用。這樣的話就會產生用戶的學習成本,需要把整體架構改造成符合RPC框架思路的架構,造成比較多的麻煩。

三、Service Mesh的探索

我們知道騰訊遊戲的數量非常繁多,架構往往並不統一。各個團隊都跟著自己的思路走,想用什麼就用什麼,慢慢得各種框架和問題也隨之出現。為了探索解決這一問題,我們引入了一個新的思路:Service Mesh。

Service Mesh 是一個相對底層的架構,作為我們微服務的底層。兩大主要產品是linkerd和Istio,它們可以直接從底層做一些鏈路追蹤方面的事情,通過應用下沉提高了系統的適用性。

如下圖所示,左邊展示的是TARS和gRPC,他們的主要思路在於無性能損耗的交用,把所有的東西都執行到RPC裡面,侵入性較強。

右邊是Service Mesh的架構,Service Mesh會把業務的服務做得很薄,基本上沒有什麼業務邏輯,而把所有微服務治理的東西全部放到下層,從而做到整個服務的流量控制,這樣就組成了一個個小方格,互相之間可以互聯。

這樣的方式可以將框架做得非常薄,甚至不要都可以。整個架構非常清晰,相當於單體調用通過Service Mesh可以直接變為分散式的架構。

我們去年在王者榮耀裡面也做了一些應用,最後發現這些架構非常方便。當我們給王者榮耀做活動使用的時候,雖然流量很大,但是性能非常穩定。

每個服務下面都有一個Proxy,Proxy就是Sidecar,用於處理服務網格中所有服務的所有入站和出站流量。Proxy把所有的頭轉給Mixer,Mixer是負責提供策略控制和遙測收集的組件服務,這一塊是做數據平面的一些操作。

接著是Adapter,為Mixer提供擴展服務的獨立服務,比如做一些遠程負載均衡的流量控制。以這一套架構作為分散式體系的一部分,能大幅度降低許多單體應用的開發成本。

Pilot主要職責是向 Sidecar 發現服務、資訊和各種流量管理和路由規則,Galley服務提供配置的校驗、各種配置之間統籌,為 Istio 提供配置管理服務,Citadel用於密鑰管理和證書管理,下發到Sidecar等負責通訊轉發的組件。

通過測試數據可以看到,Istio在打開Mixer情況下單邊延遲增加1ms 左右,雙邊延遲增加2ms左右,對服務影響較小,關閉Mixer延遲可以更低。

如果以絕對數字來看的話,相當於增加了一倍的耗時。但是在我們正式應用當中,大部分服務耗時都是在50毫秒左右,如果我們只增加了1毫秒,其實影響並不大。

但是如果對於一些底層存儲應用,本身的耗時是比較低的,如果再用這套架構把它變成分散式架構就會非常困難,因為性能損耗會變得非常大。

未來騰訊雲會在設置一個統一的Istio管理平台,在容器管理平台裡面會提供Istio的服務網格技術,在上面一層可以通過一些控制平面,服務我們上面的一些管控體系,通過Istio的應用管理平面來實現,底層可以訪問我們的外部存儲的,這個就是我們一套比較完整的應用架構。

下圖所示的是 Service Mesh 和我們微服務框架的對比,在語言支援方面,它是跟語言無關的的底層架構,所以具有很高的拓展性。未來我們將會逐步完善整體生態建設,社區現在的活躍度也維持在較高水平。

最後給大家總結一下,我們的傳統框架未來還會存在,但是它的功能會越來越業務化,治理相關的一些功能會逐漸下沉,更加註重是業務化的功能。

如果在應用當中,你還沒有配置一些框架的服務體系的話,那使用TARS是非常合適的。TARS使用的是完整的微服務體系,非常方便快捷。

如果使用gRPC則需要自己建設周邊的體系。我們未來將會以Service Mesh為主,慢慢替代原有框架。如果大家還在做框架開發相關的業務,可以慢慢地抽出來往Service Mesh上面靠,因為框架開發未來會慢慢以業務開發為主,治理這一塊將不再是重點。

四、Q&A

Q:對於Service Mesh,Service Mesh相當於將所有的服務治理都單元化集成到某個應用中,那麼每一個單元的負載均衡或者是流量控制,是如何控制的呢?

A:負載均衡其實就是將流量轉化成IP列表,分發給不同的IP。這裡需要通過Sidecar?因為Sidecar會知道你的流量往哪邊走,目前是通過iptables劫持流量指向Sidecar。當你的服務通過Sidecar之後,Sidecar獲取到目的地址,通過控制面板上的數據,搭配一些策略,然後做映射,把你相應的請求分發到多個節點中去從而實現均衡。

講師介紹

田甜,騰訊高級工程師,對分散式架構與容器化技術有深入研究,具有豐富的分散式架構設計開發與項目實踐經驗。目前專註TARS-GO框架開發,是TARS-GO早期發起人和最核心開發成員之一,也是騰訊遊戲數據研發工程師,致力於在數據服務場景中應用微服務架構。