dubbo-go 中如何實現路由策略功能

可在控制面對服務的路由進行精細控制,是一個成熟 RPC 系統必備的能力之一。作爲一個逐步走向成熟的 RPC 系統,Apache/dubbo-go(以下簡稱 dubbo-go )的最新版本 v1.4 中已經實現了 Condition Router 和 Health Instance First Router 等路由。

實現一個功能,首先要清楚其本質。那到底什麼是路由規則,我們爲什麼需要路由規則?設想這麼一個場景:現在要對某服務的新版本進行一次灰度發佈,需要將一些對實驗流量進行引流到灰度機器,其餘流量依舊使用正常服務。此時就可以考慮使用路由策略達到目的。

路由規則( routing rule )是爲了改變網絡流量所經過的途徑而修改路由信息的技術,通過改變路由屬性(包括可達性)達到引流的目的。在發起一次 RPC 調用前,它會過濾目標服務器地址,將消費端最終發起 RPC 調用的目標範圍限定在過濾後的地址列表。

目標


路由策略的關鍵點在於:

1、設定規則:用戶可通過什麼方式把路由規則傳遞給使用方;

2、解析規則:涉及到的路由規則的語法,以及對語法的解析。比如,要考慮規則是否支持邏輯運算;

3、規則匹配:如何判斷一個服務實例是否匹配某條路由規則。

綜上,可以總結出 dubbo-go 路由規則的目標有:

1、支持從多個地方,如本地文件、遠程配置中心,讀取路由規則信息;

2、設計一套定義路由規則的簡單語法;

3、保持與 Dubbo 的兼容,降低學習成本;

總體設計


首先要考慮的是:路由規則應該放在整個服務治理週期的哪個階段呢?dubbo-go 的架構圖如下:

可以看到圖中的 Router 介於 Cluster 和 LB(load balance) 之間,這就意味着一個請求被髮送到哪個服務器,是經過了 Cluster - Router - LB 三層處理的。可以將 Router 看做是一種較小範圍的邏輯分組。

而在 Router 內部,將經歷三個步驟:讀取路由規則,解析路由規則,執行匹配。爲了提高程序效率,路由規則的讀取和解析都是可以提前完成的,比如在應用啓動的時候。

根據上面圖中流程,可清楚地明晰 Router 的路由流程。

接口設計


根據前面的目標和總體設計,我們很容易地設計出 Router 的接口。

路由規則接口

Router 是 dubbo-go 路由最核心的接口。它可以理解爲,當一個請求(或者說一次調用)過來的時候,判斷哪些實例是滿足該規則的抽象。其實際代碼定義如下:

其核心在於 Route 方法,執行匹配邏輯。目前該接口的實現有:

  • ListenableRouter

  • AppRouter

  • ConditionRouter

  • HealthCheckRouter

  • FileConditionRouter

在現實實現中,不同的不同的路由規則是有優先級的,即 Router 的另一個重要特性:Priority 。它決定了的是路由規則的組織方式。

路由規則鏈式接口

除了優先級,多個路由規則的執行是有順序的。有路由規則的 Chain 接口如下:

Chain 實現了對不同路由規則的組織。從命名也可以看出,它是責任鏈模式的一種應用,通過該接口可將路由規則組成一條鏈,鏈中每條規則的輸出都是下一條規則的輸入。至於整個鏈路中不同規則的順序,取決於每個規則的 Priority ,它決定了每條路由規則的排序。

讀取路由規則接口

讀取路由規則對應 FileRouterFactory 和 RouterFactory 兩個接口。一般地,只需要一個 RouterFactory 接口就可以,但考慮到路由規則的不同來源,比如規則可能是從配置文件裏面讀取過來,也可能是直接在服務的 URL 解析而來,所以我們抽象出來了兩個接口:

FileRouterFactory

RouterFactory

我們一般將這兩個接口對應本地和遠程兩種情況:

1、本地路由規則配置:在原配置加載階段,新增讀取路由配置文件步驟。使用 FileRouterFactory 解析後,生成對應路由規則,然後加載到緩存中。

2、遠程路由規則配置:讀取遠程配置並且監聽其變化,篩選符合路由規則配置信息,通過 RouterFactory 生成對應路由規則,同樣加載到緩存中備用。

實現


從圖裏面可以看出,實現路由規則以兼容 dubbo 爲首要目標,降低使用者的學習成本爲輔助目標。與配置中心模塊相結合,實現路由規則遠程統一管理與下發。

規則類型

下面介紹一下 dubbo-go 現有的路由規則實現。

條件路由

Condition Router 作爲 dubbo-go 中第一個支持的路由規則實現,允許用戶通過配置文件及配置中心管理路由規則。與之相似的一個概念是 dubbo-go 的 group,但是條件路由提供了更加細粒度的控制手段和更加豐富的表達語義。比較典型的使用場景是黑白名單設置,灰度以及測試等。

健康檢查路由

在 RPC 調用中,如果希望儘可能地將請求命中到那些處理能力快、處於健康狀態的實例,即可以考慮該路由。該路由判定斷定某個服務提供者的不健康度,優先調用那些健康的服務實例。對 "健康" 度的判定,dubbo-go 默認的實現策略是:某服務的錯誤比例到達某一個閾值或者請求活躍數大於上限,則認爲其不健康,頗類似於服務熔斷。dubbo-go 當然亦允許用戶擴展其健康檢測策略。

標籤路由

以 Provider 爲維度,將某一個或多個服務的提供者劃分到同一個分組,約束流量只在指定分組中流轉,從而實現流量隔離的目的,即爲標籤路由。它可以作爲藍綠髮布、灰度發佈等場景的能力基礎。

  • 靜態打標:根據配置文件所配置的標籤,固定給 Provider 設置標籤。

  • 動態打標:基於健康檢查路由,根據服務不同時刻,不同狀態,動態在 Provider 設置適合的標籤。

示例

下面以條件路由在 zookeeper 實現爲例,對服務提供者與服務消費者進行整體流程分析。

如何配置條件路由規則

可以直接通過 dubbo-admin 進行配置:

這些配置可以分成全局配置和服務配置兩類。

全局配置:

對應應用級全局路由規則配置。例如:

/dubbo/config/dubbo/user-info-server(應用名).condition-router


上面 schema 配置中,應用名配置爲爲 user-info-server,即該條規則只對該應用生效。後綴 ".condition-router" 表明該條規則爲條件路由。除此之外,還可用 ".tag-router" 表示標籤路由。

服務配置:

對應服務級所有路由規則配置。例如有如下規則 schema:

/dubbo/ com.ikurento.user.UserProvider(服務名) /routers


該規則中服務名爲 com.ikurento.user.UserProvider。

除了在控制面板 Dubbo Admin 中下發路由規則外,還可以在本地文件中配置相應的規則。比如說在文件 router_config.yml 中配置:

# dubbo router yaml configure filepriority: 1force: trueconditions : ["host = 1.1.1.1 => host = 192.168.199.214"]


更多配置方式請參考條件路由配置。使用 dubbo-go 的路由功能時,注意以以下方式 引入對應的包:


條件路由配置

http://dubbo.apache.org/zh-cn/docs/user/demos/routing-rule.html


總結


dubbo-go 整體路由規則功能實現,已基本對齊 dubbo 2.7.x 版本,目前上文中描述過的條件路由、標籤路由與健康檢測路由,且支持本地及遠端配置路由規則,能滿足基本使用場景,但距離完善還有還長遠的路。dubbo-go 未來路由功能計劃如下:

1、更多的配置中心【如 etcd/consul 等】支持,理論上已經支持,但還沒測試;

2、service-router(未支持);

3、標籤路由-配置中心(未支持);

4、目前路由與配置中心結合的代碼,對新增路由規則並不友好,有一定接入成本。

本文對 dubbo-go 已有的路由功能進行了總結,至於源碼級的分析,本文不作展開。歡迎大家持續關注 dubbo-go 項目:

https://github.com/apache/dubbo-go

作者信息:

鄒毅賢,Github ID @zouyx,開源愛好者,就職於 SheIn 供應鏈部門,負責供應鏈開放平臺。

本文縮略圖:icon by cg尐愳

Tips:

# 點下“看”❤️

# 然後,公衆號對話框內發送“杯刷”,試試手氣?????

# 本期獎品是來自淘寶心選的椰棕杯刷

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章