路由規則決定一次 dubbo 服務調用的目標服務器,分為條件路由規則和腳本路由規則,並且支持可擴展
比如:所有訪問127.0.0.1提供的服務的消費者均轉為訪問192.168.198.128提供的服務(一般為集群背景)
寫入路由規則
向注冊中心寫入路由規則的操作通常由監控中心或治理中心的頁面完成
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension(); Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://127.0.0.1:2181")); //所有訪問127.0.0.1提供的服務的消費者均轉為訪問192.168.198.128提供的服務(一般為集群背景) registry.register(URL.valueOf("condition://0.0.0.0/com.ssmp.service.TblEmpService?category=routers&dynamic=false&rule=" + URL.encode("host = 127.0.0.1 => host = 192.168.198.128")));
其中:
- condition:// 表示路由規則的類型,支持條件路由規則和腳本路由規則,可擴展,必填。
- 0.0.0.0 表示對所有 IP 地址生效,如果只想對某個 IP 的生效,請填入具體 IP,必填。
- com.foo.BarService 表示只對指定服務生效,必填。
- group=foo 對指定服務的指定group生效,不填表示對未配置group的指定服務生效
- version=1.0對指定服務的指定version生效,不填表示對未配置version的指定服務生效
- category=routers 表示該數據為動態配置類型,必填。
- dynamic=false 表示該數據為持久數據,當注冊方退出時,數據依然保存在注冊中心,必填。
- enabled=true 覆蓋規則是否生效,可不填,缺省生效。
- force=false 當路由結果為空時,是否強制執行,如果不強制執行,路由結果為空的路由規則將自動失效,可不填,缺省為 flase。
- runtime=false 是否在每次調用時執行路由規則,否則只在提供者地址列表變更時預先執行並緩存結果,調用時直接從緩存中獲取路由結果。如果用了參數路由,必須設為 true,需要注意設置會影響調用的性能,可不填,缺省為 flase。
- priority=1 路由規則的優先級,用於排序,優先級越大越靠前執行,可不填,缺省為 0。
- rule=URL.encode("host = 10.20.153.10 => host = 10.20.153.11") 表示路由規則的內容,必填。
條件路由規則
基於條件表達式的路由規則,如:host = 10.20.153.10 => host = 10.20.153.11
規則:
- => 之前的為消費者匹配條件,所有參數和消費者的 URL 進行對比,當消費者滿足匹配條件時,對該消費者執行后面的過濾規則。
- => 之后為提供者地址列表的過濾條件,所有參數和提供者的 URL 進行對比,消費者最終只拿到過濾后的地址列表。
- 如果匹配條件為空,表示對所有消費方應用,如:=> host != 10.20.153.11
- 如果過濾條件為空,表示禁止訪問,如:host = 10.20.153.10 =>
表達式:
參數支持:
- 服務調用信息,如:method, argument 等,暫不支持參數路由
- URL 本身的字段,如:protocol, host, port 等
- 以及 URL 上的所有參數,如:application, organization 等
條件支持:
- 等號 = 表示"匹配",如:host = 10.20.153.10
- 不等號 != 表示"不匹配",如:host != 10.20.153.10
值支持:
- 以逗號 , 分隔多個值,如:host != 10.20.153.10,10.20.153.11
- 以星號 * 結尾,表示通配,如:host != 10.20.*
- 以美元符 $ 開頭,表示引用消費者參數,如:host = $host
示例:
1. 排除預發布機:
=> host != 172.22.3.91
2. 白名單:
host != 10.20.153.10,10.20.153.11 =>
3. 黑名單:
host = 10.20.153.10,10.20.153.11 =>
4. 服務寄宿在應用上,只暴露一部分的機器,防止整個集群掛掉:
=> host = 172.22.3.1*,172.22.3.2*
5. 為重要應用提供額外的機器:
application != kylin => host != 172.22.3.95,172.22.3.96
6. 讀寫分離:
method = find*,list*,get*,is* => host = 172.22.3.94,172.22.3.95,172.22.3.96
method != find*,list*,get*,is* => host = 172.22.3.97,172.22.3.98
7. 前后台分離:
application = bops => host = 172.22.3.91,172.22.3.92,172.22.3.93
application != bops => host = 172.22.3.94,172.22.3.95,172.22.3.96
8. 隔離不同機房網段:
host != 172.22.3.* => host != 172.22.3.*
9. 提供者與消費者部署在同集群內,本機只訪問本機的服務:
=> host = $host
腳本路由規則
腳本路由規則支持 JDK 腳本引擎的所有腳本,比如:javascript, jruby, groovy 等,通過 type=javascript 參數設置腳本類型,缺省為 javascript。
"script://0.0.0.0/com.foo.BarService?category=routers&dynamic=false&rule=" + URL.encode("(function route(invokers) { ... } (invokers))")
注意:腳本沒有沙箱約束,可執行任意代碼,存在后門風險。