微博開源的Motan RPC最新進展:新增跨語言及服務治理支持
https://github.com/weibocom/motan
Motan 是一個基於 Java 開發的高性能的輕量級 RPC 框架,Motan 提供了豐富的服務治理功能和優秀的擴展能力,可以方便的基於 Motan 進行二次開發。Motan 框架於 2016 年開源後取得了社區的廣泛好評,並且由社區貢獻了眾多 PR,開源後增加了全註解配置、不同序列化方式、非同步調用、OpenTracing、Restful 等眾多功能,得到了快速的發展。
微博平台的服務交互方式主要是基於 Motan 的 RPC 調用,從 2013 年 Motan 誕生,到 2015 年基於 Docker 容器化部署的混合雲架構,Motan 框架也隨著每次微博服務化的升級而不斷發展。目前微博服務化體系上運行著上千個服務,每天完成萬億次的 RPC 服務調用和數百億的 API 調用。微博的服務化能夠實現複雜的服務治理功能,並且能夠快速、細粒度的動態擴縮容。
但是 Motan 還有一個跨語言服務化的問題沒有很好的解決,在多語言場景下使用時,還需要服務提供方同時提供 RPC 服務和 HTTP 服務。雖然 Motan 支持了 YAR 協議可以在一定程度上解決這個問題,但是還有 Golang、C++、Python 等一些語言的服務需要進行跨語言調用。如何在多語言之間提供統一的服務化能力與標準,是目前微博服務化需要解決的主要問題,也是 Motan 框架目前的研發方向。
一、跨語言服務化的挑戰
服務化交互有很多種方式,例如 HTTP、RPC、非同步消息隊列等,這裡主要對 HTTP 和 RPC 這兩種常用方式的跨語言方案進行介紹:
HTTP RESTful API
HTTP 本身就是語言無關的協議,一般由服務提供方與使用方通過文檔來進行服務約定。這也是目前使用非常廣泛的跨語言交互方式,HTTP 服務的服務治理能力一般依賴於代理層和服務調用方自己實現,一般代理服務需要單獨部署,所有請求流量經由代理服務進行轉發。例如使用 nginx 提供基礎的負載均衡與流量控制等治理能力就是最簡單的跨語言服務治理方案。
HTTP 的跨語言服務化,有些方案選擇了為特定語言實現強大服務治理能力,對其他語言提供兼容能力,例如 Spring Cloud 為 Java 服務提供完整的服務治理能力,包括服務發現、路由器、過濾器、配置管理、熔斷器等等。但很難為不同語言提供統一的服務治理能力,特別是在 Client 側的一些服務治理能力,不同語言都需要做相同功能的開發。
還有一些方案使用本機代理的方式,例如 envoy、linkerd 等可以部署到單機的 HTTP 代理服務,在代理服務中集成統一服務發現與治理能力。這種方案能夠做到不同語言的 Client 和 Server 都提供相同的服務治理能力,但服務治理的功能很難做到前一種方案那麼強大。
RPC
使用 RPC 作為服務調用方式時,跨語言與服務治理也很難同時滿足,對於跨語言型的 RPC 協議,例如 gRPC 等,都能夠提供不同語言交互的能力,但是相關的服務治理功能還沒有那麼完善,做到了』交互』,但還無法做到』治理』。使用跨語言型 RPC 框架時一般會選擇使用 HTTP(HTTP2)作為通信協議,這樣可以直接應用 HTTP 方式的服務治理功能;
對於服務治理型 RPC,由於選擇了在 Client 端進行服務發現與治理,如果要實現不同語言統一的服務治理能力,需要在不同語言的一側都實現相同的功能。實現起來也相當的困難。因此大部分服務治理型 RPC 專註與為特定語言提供完善的治理能力。
看來,無論哪種服務交互方式,跨語言與統一服務治理都很難做到魚與熊掌兼得
二、Motan 的跨語言服務化方案
Motan 作為服務治理型 RPC 框架,跨語言服務治理是一個非常大的挑戰,為了實現不同語言的統一服務治理能力,我們評估了幾種方案,如下表所示:
兼容 HTTP 協議。增加 HTTP RESTful 協議,可以直接提供 HTTP 服務。在 dubbox 中採用的就是這種方案,但是這種方案將 Java 語言的 RPC 調用方式與其他語言獨立開來,只針對 Java Server 端提供,沒有為其他語言提供服務治理能力。與 Motan 支持 YAR 協議一樣,更多的是一種兼容方案。由於只需要做 Java 協議的開發,這種方案研發和維護成本很低,不過能夠提供的統一服務治理能力就很低了。
為不同語言提供 RPC 模塊。這種方案能做到最貼近不同語言的使用習慣,可以為不同語言提供完全一致的服務治理能力,不論是作為 Server 端還是 Client 端。但這種方式也是成本最高的,包括開發不同語言的版本,以及後續的功能升級與版本維護代價都非常高。
開發一個 Agent 模塊,實現絕大部分的服務治理能力。Agent 在不同服務的 Server 或 Client 側運行。然後為不同語言開發一個很輕量的 Client 與 Agent 進行交互,由於 Client 只實現必要的交互功能,降低了不同語言版本的開發量與維護的成本。
最終我們選擇的方案是 Client + Agent 方式。
為不同語言提供非常輕量的 Client,只實現與 Agent 的交互和必要的請求序列化能力;提供一個 local 的 Agent 代理,能夠提供不同 RPC 協議交互能力,以及統一的服務治理能力與標準,服務治理的絕大部分功能都在語言無關的 Agent 中實現。通過使用 Agent,可以為類似 PHP 這樣的解釋型語言提供長鏈接復用能力,提高請求性能。
這種方案為不同語言提供了語言友好的 Client,由於 Client 非常輕量,後續的維護工作會非常簡單;由語言無關的 Agent 模塊為不同語言提供統一的 RPC 協議、負載均衡、HA策略等服務治理能力支持,Agent 升級和維護都不需要使用方代碼做任何變更。特別是在使用Docker容器化部署的場景中,Agent 可以作為組件打包至基礎鏡像,業務使用時可以很方便做到無感知升級。
Agent 方式與 nginx 等代理服務相比,Agent 只負責本機的請求轉發,不需要額外的伺服器資源部署代理服務。Agent 與 Server 端進行直連請求,請求鏈路更短,可以保持長鏈接減少建連開銷(與使用的 RPC 協議是否支持有關)。
我們使用 Golang 作為 Agent 的開發語言,並設計了對不同語言更友好的新 Motan 協議,不同語言 Client 通過統一的協議與 Agent 與進行交互,Agent 則可以支持多種不同協議擴展,可以根據配置將請求轉換為不同 RPC 協議進行轉發。
如上圖所示,PHP Client 通過 Motan 協議請求 Agent,Agent 可以用 gRPC 和 Motan 協議請求不同的 Server。
Agent 代理在設計上即可以做正向代理也可以做反向代理,這樣不同語言就可以提供相同的 RPC 協議服務了。如上圖中,gRPC 協議不支持 PHP 做 Server,通過 Agent 進行代理,可以彌補這個缺陷,PHP 也可以作為 Server 提供 gRPC 服務。
三、遇到的問題:
1)HTTP 服務遷移
Google 的 Protocol Buffers(pb)序列化能夠提供優秀的跨語言序列化能力,因此我們在做服務化時傾向於使用 pb 作為序列化方式,同時支持原生 gRPC 協議的調用。但是在進行測試時發現已有的舊 HTTP 服務改造為 gRPC 服務還存在一些問題,例如 PHP 在做複雜 pb 對象(50+ 嵌套 feilds,100k 大小)序列化時性能比較差,耗時差不多是相同對象 json 序列化的 3 倍左右;一些業務從 HTTP 調用改造為 gRPC 調用時 Server 端和 Client 端代碼修改量巨大,並且可能因為 pb 默認值等原因在業務邏輯中存在一些潛在風險等等。
對於新服務,我們傾向使用 pb 序列化,因為這樣可以為服務提供明確的契約;對於 HTTP 服務遷移,我們準備增加一種簡單序列化方式,參數和返回值僅支持 utf8 string 以及 key、value 為 string 類型的 map,這種序列化方式簡單高效,與原有的 HTTP 請求比較類似,可以很方便的完成舊服務的改造。
2)Agent 監控與運維
Agent 是跨語言服務化的核心,因此,Agent 的運維與保活監控非常的重要,那麼 Agent 該由統一的團隊進行監控運維,還是有不同業務方各自管理?由於不同的業務由不同的運維團隊管理,而 Agent 的波動一般也需要相應的業務人員關注,目前我們傾向的方案為由各業務方進行 Agent 的保活監控。為此我們提供了 HTTP 管理埠來支持探活與工作狀態查詢,同時也提供了 pid 文件機制,方便使用不同方式方式對 Agent 進行探活。而後續 Agent 也將支持心跳上報等能力,可以支持統一監控方式。
3)Agent 降級
萬一 Agent 掛掉了怎麼辦呢?Agent 是 local 部署,個別 Agent 掛掉,不會造成全局性問題。除了報警、監控腳本自動重啟以及運維人工介入外,在 Agent 掛掉時,Client 必須擁有降級能力,能夠直接進行 RPC 調用。
如下圖所示,Agent 會在本地指定位置維護一份最近一次可用 Server 節點的快照,當 Client 感知到 Agent 掛掉後,可以根據可用 Server 節點的快照按簡單負載均衡策略進行直連 Server,保證服務仍然可以正常使用。降級機制可以為 Agent 掛掉時提供一段時間的恢復窗口期。目前 PHP Client 提供了對 Motan、gRPC 協議的 Server 進行直連的能力。
作為服務治理型 RPC 框架,為不同語言提供統一的服務治理能力是 Motan 框架的目標,Motan Agent 基礎功能目前已基本完成,正在部分業務中進行調試,等功能穩定之後將會進行開源,非常歡迎對 Motan、對跨語言服務化感興趣的同學一起加入,共同完善 Motan 框架。
作者簡介
張雷,新浪微博技術專家,Motan RPC 框架技術負責人。2013 年加入新浪微博,作為核心技術成員參與微博 RPC 服務化、混合雲等多個重點項目,當前負責 MotanRPC 框架的維護與架構改進。專註於高可用架構及服務中間件開發方向。
參考閱讀
本文作者 Motan 開發團隊張雷。技術原創及架構實踐文章,歡迎通過公眾號菜單「聯繫我們」進行投稿。
高可用架構
改變互聯網的構建方式
長按二維碼 關注「高可用架構」公眾號
※如何選擇合適的分散式機器學習平台
※從一道簡單的面試題考查應聘者的技術能力
※基於Falcon的滴滴內部監控系統
※「活動報名」CCF TF 01:與25家Top技術團隊架構師共論微服務
※微博廣告Hubble系統:秒級大規模分散式智能監控平台架構實踐
TAG:高可用架構 |
※跨語言版BERT:Facebook提出跨語言預訓練模型XLM
※GraalVM:新一代高性能跨語言虛擬機
※Facebook新研究:一個編碼器hold住93種語言!跨語言遷移無需修改
※北大獲中國首個WWW大會最佳論文獎,提出ELSA跨語言情感分析模型
※鄒炎炎:語義分析介紹及跨語言信息在語義分析中的應用|AI 研習社第 70 期大講堂
※基於對抗跨語言多任務學習的微博個性化情感分析
※鄒炎炎:語義分析介紹及跨語言信息在語義分析中的應用
※語義分析介紹及跨語言信息在語義分析中的應用
※提升青少年跨文化和跨語言交流能力,拓展青少年的全球視野和獨立人格
※系統探討「跨語言詞嵌入」,這是一本剛出爐新書
※普通話輕聲的感知:成人和嬰兒的跨語言研究