目錄
- 前言
- 1. SubsetConf配置項的結構
- 1.1 SubsetConf
- 1.2 RatioConfig
- 1.3 KeyConfig
- 1.4 KeyRoute
- 1.5 SubsetConf的結構示意圖
- 2. 測驗方案設計
- 2.1 構建前置條件
- 2.2 呼叫測驗方法
- 2.3 輸出測驗結果
- 3. 按比例路由規則 - 單次測驗
- 4. 按比例路由規則 - 多次測驗
- 5. 按引數路由規則 - 精確匹配測驗
- 6. 按引數路由規則 - 正則匹配測驗
- 7. 無路由規則測驗
- 最后
前言
中期匯報會后,對Tars Subset功能更加熟悉,并根據TarsGo的實作方式,對Java JDK實作代碼進行翻新改造,于是有了以下兩篇分析文章:
第5篇 基于TarsGo Subset路由規則的Java JDK實作方式(上篇)
https://www.cnblogs.com/dlhjw/p/15245113.html
第6篇 基于TarsGo Subset路由規則的Java JDK實作方式(下篇)
https://www.cnblogs.com/dlhjw/p/15245116.html
其中,《上篇》注重TarsGo分析,《下篇》注重TarsJava實作方式,不出意外的話,最終提交的考核成果就在下面的GitHub代碼倉庫中(以下簡稱“最終代碼”),后續可能會有些許地方需要更改:
TarsJava 實作Subset路由規則JDK GitHub開源地址
https://github.com/dlhjw/TarsJava/commit/cc2fe884ecbe8455a8e1f141e21341f4f3dd98a3
最終代碼與中期代碼在整體思想邏輯上都是一致的都是:先判斷Subset路由規則,再根據規則路由到定義的節點,不同點在于:中期在處理整個程序時,用一個方法filterEndpointsBySubset()實作;而最終的實作方式則是以subsetEndpointFilter()方法作為整個Subset流量路由的入口,通過subsetManager管理器呼叫getSubset()方法獲取到路由規則的String型別的subset欄位,與節點自身的subset欄位一一比較過濾節點;其中Subset路由規則的判斷封裝在getSubset()方法里;
總的來說就是最終代碼是在處理subset規則邏輯中增加了很多細節,比如:通過新增的registry介面獲取subsetConf配置項;將獲取到是配置項存入快取中;以及將“判斷Subset路由規則”進行層層封裝,最侄訓傳一個簡單的String型別的subset欄位與節點自身的subset欄位比較等;
因此,在測驗方案上相比較中期有些許區別,但總體上的單元測驗原則是不變的:
- 首先構建前置條件;
- 呼叫測驗方法;
- 輸出測驗結果;
其中的區別主要體現在前置條件的構建上,本篇將結合最終代碼的實作邏輯,重點介紹其測驗方案的設計;首先介紹測驗方案的設計原則,接著針對五種情況(按比例單次、按比例多次、按引數精確、按引數正則路由與默認規則)做詳細介紹與展示測驗結果,
最終代碼的Subset執行流程分析請參考下面這篇文章:
第8篇 TarsJava Subset最終代碼的執行流程與原理分析
https://blog.csdn.net/dlhjw1412/article/details/119932752
《測驗方案設計》與《執行流程分析》兩篇文章相輔相成,相互觀閱能更快更好地理解整個Subset的業務流程與輸出示例;
1. SubsetConf配置項的結構
在中期,筆者使用一個map來模擬subset的流量規則;而在最終代碼里,是用多個物件來模擬Subset的配置,這些物件是理解整個Subset流量過濾規則的基礎的,因此很有必要在這里做個介紹;
1.1 SubsetConf
public class SubsetConf {
private boolean enanle;
private String ruleType;
private RatioConfig ratioConf;
private KeyConfig keyConf;
private Instant lastUpdate;
……
}
可以看出SubsetConf配置項里有以下屬性:
- enanle:表示是否開啟Subset流量管理功能;
- true:開啟;false:關閉;
- ruleType:表示流量管理的型別;
- 目前有
ratio按比例和key按引數兩種模式;
- 目前有
- RatioConfig:表示按比例路由配置項;
- 里面定義了路由比例與路徑等資訊,詳情請參考《1.2 RatioConfig》
- KeyConfig:表示按引數路由配置項;
- 里面定義了規則key與路由路徑等資訊,詳情請參考《1.3 KeyConfig》
- lastUpdate:表示該配置項上次更新時間,將在快取那里起作用;
1.2 RatioConfig
public class RatioConfig {
private Map<String, Integer> rules;
……
}
RatioConfig里只有一個map型別的rules路由規則,其中key為一個String型別的subset欄位,用來跟節點的subset欄位匹配,value為路由權重,如:{ {"v1" , 20} , {"v2" , 60} , {"v3" , 20} }表示路由到subset欄位為v1的節點的概率為0.2;路由到subset欄位為v2的節點的概率為0.6;路由到subset欄位為v3的節點的概率為0.2;
1.3 KeyConfig
public class KeyConfig {
private String defaultRoute;
private List<KeyRoute> rules;
……
}
KeyConfig里有兩個屬性,一個是defaultRoute默認路由路徑;另一個是list型別的rules,里面是KeyRoute,其定義了按引數匹配的型別、規則key與路徑,詳情請見《1.4 KeyRoute》
1.4 KeyRoute
public class KeyRoute {
private String action = null;
private String value = https://www.cnblogs.com/dlhjw/archive/2021/09/14/null;
private String route = null;
public static final String TARS_ROUTE_KEY ="TARS_ROUTE_KEY";
……
}
KeyRoute里面有四個String型別的屬性,如下:
- action:用來定義引數匹配的型別;
- 目前可設定的型別有:equals精確匹配、match正則匹配、default默認匹配;
- value:這就是大名鼎鼎的規則key了,當action=equals時,還需滿足規則key與請求key匹配,才能進行精確匹配;當action=match時,還需滿足規則key與請求key正則匹配,才能進行正則匹配;action=default對規則key沒要求;
- route:用來規定路由路徑,其值為一個String型別的subset欄位,匹配到節點的subset欄位;
- TARS_ROUTE_KEY:一個常量欄位,為Tars請求體里的status(map型別)的key;
1.5 SubsetConf的結構示意圖
上述提到的配置類聯系結構圖如下:

2. 測驗方案設計
這里的測驗主要指測驗subsetEndpointFilter()根據subset過濾節點這一核心方法,在測驗中構建前置條件最為復雜,因此將在2.1仔細介紹;
2.1 構建前置條件
從SubsetConf的結構圖可以看出,按比例與引數路由的一些前置條件不同,比如按引數路由需要一個list型別的KeyRoute,而按比例路由則是用一個map型別的資料結構實作類似KeyRoute的功能;
除此之外,KeyRoute里的value為規則的key,其作用是與請求key做對比匹配,是引數匹配的必要不充分條件;這就要求構建前置條件時要考慮從Tars的請求體TarsServantRequest中的status屬性(map型別)獲取到鍵TARS_ROUTE_KEY的值value,而Tars的請求體又要通過分布式背景關系資訊DistributedContext獲取;默認路由又不用考慮染色key……
因此,按比例與默認路由方式的前置條件包括:
- 一個Subset過濾器;
- 核心方法
subsetEndpointFilter的傳入引數;- objectName:物件名;
- routeKey:背景關系的染色key;
- activeEp:存活的節點串列及存活的節點;
- 一個SubsetManager管理器;
- RatioConfig比例路由規則;
- subsetConf配置項;
- 等;
可以通過以下代碼實作、模擬:
//創建Subset過濾器
Subset subsetFilter = new Subset();
//模擬objectName
String objectName = "objectName";
//模擬routeKey
String routeKey = "routeKey";
//存活節點list串列
List<EndpointF> endpointFList = new ArrayList<EndpointF>();
Holder<List<EndpointF>> activeEp = new Holder<List<EndpointF>>(new ArrayList<EndpointF>());
//1. 給過濾器設定過濾規則
//1.1 創建SubsetManager管理器
SubsetManager subsetManager = new SubsetManager();
//1.1 設定比例路由規則
RatioConfig ratioConf = new RatioConfig();
Map<String , Integer> map = new HashMap<>();
map.put("v1",20);
map.put("v2",80);
//map.put("v3",20);
ratioConf.setRules(map);
//1.2 設定subsetConf,并加入快取
SubsetConf subsetConf = new SubsetConf();
subsetConf.setEnanle(true);
subsetConf.setRuleType("ratio");
subsetConf.setRatioConf(ratioConf);
subsetConf.setLastUpdate( Instant.now() );
Map<String, SubsetConf> cache = new HashMap<>();
cache.put(objectName,subsetConf);
subsetManager.setCache(cache);
//1.3 給過濾器設定過濾規則和管理者
subsetFilter.setSubsetConf(subsetConf);
subsetFilter.setSubsetManager(subsetManager);
//2. 模擬存活節點
endpointFList.add(new EndpointF("host1",1,2,3,4,5,6,"setId1",7,8,9,10,"v1"));
endpointFList.add(new EndpointF("host2",1,2,3,4,5,6,"setId2",7,8,9,10,"v1"));
endpointFList.add(new EndpointF("host3",1,2,3,4,5,6,"setId3",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host4",1,2,3,4,5,6,"setId4",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host5",1,2,3,4,5,6,"setId5",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host5",1,2,3,4,5,6,"setId5",7,8,9,10,"v3"));
activeEp.setValue(endpointFList);
而按引數匹配路由方式的前置條件包括:
- 一個Subset過濾器;
- 核心方法
subsetEndpointFilter的傳入引數;- objectName:物件名;
- routeKey:背景關系的染色key;
- activeEp:存活的節點串列及存活的節點;
- 一個SubsetManager管理器;
- KeyConfig引數路由規則;
- KeyRoute引數路由屬性;
- subsetConf配置項;
- Tars的請求體TarsServantRequest;
- 一個Session域,用來構建Tars請求體
- 分布式背景關系資訊DistributedContext;
- 等;
可以通過以下代碼實作、模擬:
//創建Subset過濾器
Subset subsetFilter = new Subset();
//模擬objectName
String objectName = "objectName";
//模擬routeKey
String routeKey = "routeKey";
//存活節點list串列
List<EndpointF> endpointFList = new ArrayList<EndpointF>();
Holder<List<EndpointF>> activeEp = new Holder<List<EndpointF>>(new ArrayList<EndpointF>());
//定義一個Session域,用來構建Tars請求體
Session session;
//1. 給過濾器設定過濾規則
//1.1 創建SubsetManager管理器
SubsetManager subsetManager = new SubsetManager();
//1.1 設定引數路由規則,這里的KeyRoute的value為 “規則的染色key”
KeyConfig keyConf = new KeyConfig();
List<KeyRoute> krs = new LinkedList<>();
krs.add(new KeyRoute("match","routeKey","v1"));
keyConf.setRules(krs);
//1.2 設定subsetConf,并加入快取
SubsetConf subsetConf = new SubsetConf();
subsetConf.setEnanle(true);
subsetConf.setRuleType("key");
subsetConf.setKeyConf(keyConf);
subsetConf.setLastUpdate( Instant.now() );
Map<String, SubsetConf> cache = new HashMap<>();
cache.put(objectName,subsetConf);
subsetManager.setCache(cache);
//1.3 給過濾器設定過濾規則和管理者
subsetFilter.setSubsetConf(subsetConf);
subsetFilter.setSubsetManager(subsetManager);
//1.4 模擬Tars “請求的染色key” TARS_ROUTE_KEY,但請求染色key和規則染色key匹配時,才能精確路由
//1.4.1 創建Tars的請求體TarsServantRequest
TarsServantRequest request = new TarsServantRequest( session );
//1.4.2 往請求體的status添加{TARS_ROUTE_KEY, "routeKey"}鍵值對
Map<String, String> status = new HashMap<>();
status.put("TARS_ROUTE_KEY", "routeKey");
request.setStatus(status);
//1.4.3 構建分布式背景關系資訊,將請求放入分布式背景關系資訊中,因為getSubset()的邏輯是從分布式背景關系資訊中取
DistributedContext distributedContext = new DistributedContextImpl();
distributedContext.put(DyeingSwitch.REQ,request);
//2. 模擬存活節點
endpointFList.add(new EndpointF("host1",1,2,3,4,5,6,"setId1",7,8,9,10,"v1"));
endpointFList.add(new EndpointF("host2",1,2,3,4,5,6,"setId2",7,8,9,10,"v1"));
endpointFList.add(new EndpointF("host3",1,2,3,4,5,6,"setId3",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host4",1,2,3,4,5,6,"setId4",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host5",1,2,3,4,5,6,"setId5",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host5",1,2,3,4,5,6,"setId5",7,8,9,10,"v3"));
activeEp.setValue(endpointFList);
2.2 呼叫測驗方法
呼叫測驗方法比較簡單,用如下陳述句實作即可:
//4. 對存活節點按subset規則過濾
Holder<List<EndpointF>> filterActiveEp = subsetFilter.subsetEndpointFilter(objectName, routeKey, activeEp);
2.3 輸出測驗結果
輸出測驗結果也比較簡單,在過濾前后都遍歷一些節點串列,判斷其是否起到過濾功能即可,可以用如下代碼實作:
//3. 輸出過濾前資訊
System.out.println("過濾前節點資訊如下:");
for( EndpointF endpoint : endpointFList){
System.out.println(endpoint.toString());
}
//5. 輸出過濾結果
System.out.println("過濾后節點資訊如下:");
for( EndpointF endpoint : filterActiveEp.getValue() ){
System.out.println(endpoint.toString());
}
如此,一個大概的測驗方案就成型了,下面將介紹各路由方式的測驗代碼與測驗結果;
3. 按比例路由規則 - 單次測驗
測驗代碼如下:
/**
* 按比例路由規則 - 單次測驗
* 沒有測驗registry獲取subsetConf功能
*/
@Test
public void testRatioOnce() {
//1. 給過濾器設定過濾規則
//1.1 創建SubsetManager管理器
SubsetManager subsetManager = new SubsetManager();
//1.1 設定比例路由規則
RatioConfig ratioConf = new RatioConfig();
Map<String , Integer> map = new HashMap<>();
map.put("v1",20);
map.put("v2",80);
//map.put("v3",20);
ratioConf.setRules(map);
//1.2 設定subsetConf,并加入快取
SubsetConf subsetConf = new SubsetConf();
subsetConf.setEnanle(true);
subsetConf.setRuleType("ratio");
subsetConf.setRatioConf(ratioConf);
subsetConf.setLastUpdate( Instant.now() );
Map<String, SubsetConf> cache = new HashMap<>();
cache.put(objectName,subsetConf);
subsetManager.setCache(cache);
//1.3 給過濾器設定過濾規則和管理者
subsetFilter.setSubsetConf(subsetConf);
subsetFilter.setSubsetManager(subsetManager);
//2. 模擬存活節點
endpointFList.add(new EndpointF("host1",1,2,3,4,5,6,"setId1",7,8,9,10,"v1"));
endpointFList.add(new EndpointF("host2",1,2,3,4,5,6,"setId2",7,8,9,10,"v1"));
endpointFList.add(new EndpointF("host3",1,2,3,4,5,6,"setId3",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host4",1,2,3,4,5,6,"setId4",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host5",1,2,3,4,5,6,"setId5",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host5",1,2,3,4,5,6,"setId5",7,8,9,10,"v3"));
activeEp.setValue(endpointFList);
//3. 輸出過濾前資訊
System.out.println("過濾前節點資訊如下:");
for( EndpointF endpoint : endpointFList){
System.out.println(endpoint.toString());
}
//4. 對存活節點按subset規則過濾
Holder<List<EndpointF>> filterActiveEp = subsetFilter.subsetEndpointFilter(objectName, routeKey, activeEp);
//5. 輸出過濾結果
System.out.println("過濾后節點資訊如下:");
for( EndpointF endpoint : filterActiveEp.getValue() ){
System.out.println(endpoint.toString());
}
}
測驗結果如下:

在上述情況下,如果我們將所有v2節點洗掉,即模擬經過按比例權重查找后匹配到節點subset欄位為v2集合,但原來存活節點里卻沒有subset欄位為v2的節點這種情況,將會輸出一句錯誤資訊,如下:

4. 按比例路由規則 - 多次測驗
測驗代碼如下:
/**
* 按比例路由規則 - 多次測驗
* 沒有測驗registry獲取subsetConf功能
*/
@Test
public void testRatioTimes() {
//1. 給過濾器設定過濾規則
//1.1 創建SubsetManager管理器
SubsetManager subsetManager = new SubsetManager();
//1.1 設定比例路由規則
RatioConfig ratioConf = new RatioConfig();
Map<String , Integer> map = new HashMap<>();
map.put("v1",20);
map.put("v2",80);
map.put("v3",20);
ratioConf.setRules(map);
//1.2 設定subsetConf,并加入快取
SubsetConf subsetConf = new SubsetConf();
subsetConf.setEnanle(true);
subsetConf.setRuleType("ratio");
subsetConf.setRatioConf(ratioConf);
subsetConf.setLastUpdate( Instant.now() );
Map<String, SubsetConf> cache = new HashMap<>();
cache.put(objectName,subsetConf);
subsetManager.setCache(cache);
//1.3 給過濾器設定過濾規則和管理者
subsetFilter.setSubsetConf(subsetConf);
subsetFilter.setSubsetManager(subsetManager);
//2. 模擬存活節點
endpointFList.add(new EndpointF("host1",1,2,3,4,5,6,"setId1",7,8,9,10,"v1"));
endpointFList.add(new EndpointF("host2",1,2,3,4,5,6,"setId2",7,8,9,10,"v1"));
endpointFList.add(new EndpointF("host3",1,2,3,4,5,6,"setId3",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host4",1,2,3,4,5,6,"setId4",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host5",1,2,3,4,5,6,"setId5",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host5",1,2,3,4,5,6,"setId5",7,8,9,10,"v3"));
activeEp.setValue(endpointFList);
//3. 回圈times次
int times = 1000000;
int v1Times = 0;
int v2Times = 0;
int v3Times = 0;
int errTimes = 0;
for (int i = 0; i < times; i++) {
//對存活節點按subset規則過濾
Holder<List<EndpointF>> filterActiveEp = subsetFilter.subsetEndpointFilter(objectName, routeKey, activeEp);
String subsetValue = https://www.cnblogs.com/dlhjw/archive/2021/09/14/filterActiveEp.getValue().get(0).getSubset();
if("v1".equals(subsetValue)){
v1Times++;
} else if("v2".equals(subsetValue)){
v2Times++;
} else if("v3".equals(subsetValue)){
v3Times++;
} else {
errTimes++;
}
}
//輸出結果
System.out.println("一共回圈次數:" + times);
System.out.println("路由到v1次數:" + v1Times);
System.out.println("路由到v2次數:" + v2Times);
System.out.println("路由到v3次數:" + v3Times);
System.out.println("路由例外次數:" + errTimes);
}
測驗結果如下:

這里如果我們將陳述句subsetConf.setEnanle(true);中的true置為false,可以發現沒有起到路由功能,所有結點路由到v1那邊,如下圖所示:

如果我們給方法subsetEndpointFilter(objectName, routeKey, activeEp)中的routeKey傳入引數為空字串"",則會等比例隨機路由,測驗結果如下:

5. 按引數路由規則 - 精確匹配測驗
測驗代碼如下:
/**
* 測驗引數匹配 - 精確匹配
* 沒有測驗registry獲取subsetConf功能
* 注意要成功必須routeKey和match匹配上
*/
@Test
public void testMatch() {
//1. 給過濾器設定過濾規則
//1.1 創建SubsetManager管理器
SubsetManager subsetManager = new SubsetManager();
//1.1 設定引數路由規則,這里的KeyRoute的value為 “規則的染色key”
KeyConfig keyConf = new KeyConfig();
List<KeyRoute> krs = new LinkedList<>();
krs.add(new KeyRoute("match","routeKey","v1"));
keyConf.setRules(krs);
//1.2 設定subsetConf,并加入快取
SubsetConf subsetConf = new SubsetConf();
subsetConf.setEnanle(true);
subsetConf.setRuleType("key");
subsetConf.setKeyConf(keyConf);
subsetConf.setLastUpdate( Instant.now() );
Map<String, SubsetConf> cache = new HashMap<>();
cache.put(objectName,subsetConf);
subsetManager.setCache(cache);
//1.3 給過濾器設定過濾規則和管理者
subsetFilter.setSubsetConf(subsetConf);
subsetFilter.setSubsetManager(subsetManager);
//1.4 模擬Tars “請求的染色key” TARS_ROUTE_KEY,但請求染色key和規則染色key匹配時,才能精確路由
//1.4.1 創建Tars的請求體TarsServantRequest
TarsServantRequest request = new TarsServantRequest( session );
//1.4.2 往請求體的status添加{TARS_ROUTE_KEY, "routeKey"}鍵值對
Map<String, String> status = new HashMap<>();
status.put("TARS_ROUTE_KEY", "routeKey");
request.setStatus(status);
//1.4.3 構建分布式背景關系資訊,將請求放入分布式背景關系資訊中,因為getSubset()的邏輯是從分布式背景關系資訊中取
DistributedContext distributedContext = new DistributedContextImpl();
distributedContext.put(DyeingSwitch.REQ,request);
//2. 模擬存活節點
endpointFList.add(new EndpointF("host1",1,2,3,4,5,6,"setId1",7,8,9,10,"v1"));
endpointFList.add(new EndpointF("host2",1,2,3,4,5,6,"setId2",7,8,9,10,"v1"));
endpointFList.add(new EndpointF("host3",1,2,3,4,5,6,"setId3",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host4",1,2,3,4,5,6,"setId4",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host5",1,2,3,4,5,6,"setId5",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host5",1,2,3,4,5,6,"setId5",7,8,9,10,"v3"));
activeEp.setValue(endpointFList);
//3. 輸出過濾前資訊
System.out.println("過濾前節點資訊如下:");
for( EndpointF endpoint : endpointFList){
System.out.println(endpoint.toString());
}
//4. 對存活節點按subset規則過濾
Holder<List<EndpointF>> filterActiveEp = subsetFilter.subsetEndpointFilter(objectName, routeKey, activeEp);
//5. 輸出過濾結果
System.out.println("過濾后節點資訊如下:");
for( EndpointF endpoint : filterActiveEp.getValue() ){
System.out.println(endpoint.toString());
}
}
測驗結果如下:

這里如果我們使規則key與請求key不匹配,將起不到過濾功能,并輸出一句錯誤日志,如下圖所示:

6. 按引數路由規則 - 正則匹配測驗
測驗代碼如下:
/**
* 測驗引數匹配 - 正則匹配
* 沒有測驗registry獲取subsetConf功能
* 注意要成功必須routeKey和match匹配上
*/
@Test
public void testEqual() {
//1. 給過濾器設定過濾規則
//1.1 創建SubsetManager管理器
SubsetManager subsetManager = new SubsetManager();
//1.1 設定引數路由規則,這里的KeyRoute的value為 “規則的染色key”
KeyConfig keyConf = new KeyConfig();
List<KeyRoute> krs = new LinkedList<>();
krs.add(new KeyRoute("equal","routeKey","v1"));
keyConf.setRules(krs);
//1.2 設定subsetConf,并加入快取
SubsetConf subsetConf = new SubsetConf();
subsetConf.setEnanle(true);
subsetConf.setRuleType("key");
subsetConf.setKeyConf(keyConf);
subsetConf.setLastUpdate( Instant.now() );
Map<String, SubsetConf> cache = new HashMap<>();
cache.put(objectName,subsetConf);
subsetManager.setCache(cache);
//1.3 給過濾器設定過濾規則和管理者
subsetFilter.setSubsetConf(subsetConf);
subsetFilter.setSubsetManager(subsetManager);
//1.4 模擬Tars “請求的染色key” TARS_ROUTE_KEY,但請求染色key和規則染色key匹配時,才能精確路由
//1.4.1 創建Tars的請求體TarsServantRequest
TarsServantRequest request = new TarsServantRequest( session );
//1.4.2 往請求體的status添加{TARS_ROUTE_KEY, "routeKey"}鍵值對
Map<String, String> status = new HashMap<>();
status.put("TARS_ROUTE_KEY", "route*");
request.setStatus(status);
//1.4.3 構建分布式背景關系資訊,將請求放入分布式背景關系資訊中,因為getSubset()的邏輯是從分布式背景關系資訊中取
DistributedContext distributedContext = new DistributedContextImpl();
distributedContext.put(DyeingSwitch.REQ,request);
//2. 模擬存活節點
endpointFList.add(new EndpointF("host1",1,2,3,4,5,6,"setId1",7,8,9,10,"v1"));
endpointFList.add(new EndpointF("host2",1,2,3,4,5,6,"setId2",7,8,9,10,"v1"));
endpointFList.add(new EndpointF("host3",1,2,3,4,5,6,"setId3",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host4",1,2,3,4,5,6,"setId4",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host5",1,2,3,4,5,6,"setId5",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host5",1,2,3,4,5,6,"setId5",7,8,9,10,"v3"));
activeEp.setValue(endpointFList);
//3. 輸出過濾前資訊
System.out.println("過濾前節點資訊如下:");
for( EndpointF endpoint : endpointFList){
System.out.println(endpoint.toString());
}
//4. 對存活節點按subset規則過濾
Holder<List<EndpointF>> filterActiveEp = subsetFilter.subsetEndpointFilter(objectName, routeKey, activeEp);
//5. 輸出過濾結果
System.out.println("過濾后節點資訊如下:");
for( EndpointF endpoint : filterActiveEp.getValue() ){
System.out.println(endpoint.toString());
}
}
測驗結果如下:

這里如果我們使規則key與請求key正則匹配不上,跟精確匹配一樣將起不到過濾功能,并輸出一句錯誤日志,如下圖所示:

7. 無路由規則測驗
測驗代碼如下:
/**
* 測驗默認路由
* 沒有測驗registry獲取subsetConf功能
*/
@Test
public void testDefault() {
//1. 給過濾器設定過濾規則
//1.1 創建SubsetManager管理器
SubsetManager subsetManager = new SubsetManager();
//1.1 設定引數路由規則,這里的KeyRoute的value為 “規則的染色key”
KeyConfig keyConf = new KeyConfig();
List<KeyRoute> krs = new LinkedList<>();
krs.add(new KeyRoute("default","","v1"));
keyConf.setRules(krs);
//1.2 設定subsetConf,并加入快取
SubsetConf subsetConf = new SubsetConf();
subsetConf.setEnanle(true);
subsetConf.setRuleType("key");
subsetConf.setKeyConf(keyConf);
subsetConf.setLastUpdate( Instant.now() );
Map<String, SubsetConf> cache = new HashMap<>();
cache.put(objectName,subsetConf);
subsetManager.setCache(cache);
//1.3 給過濾器設定過濾規則和管理者
subsetFilter.setSubsetConf(subsetConf);
subsetFilter.setSubsetManager(subsetManager);
//2. 模擬存活節點
endpointFList.add(new EndpointF("host1",1,2,3,4,5,6,"setId1",7,8,9,10,"v1"));
endpointFList.add(new EndpointF("host2",1,2,3,4,5,6,"setId2",7,8,9,10,"v1"));
endpointFList.add(new EndpointF("host3",1,2,3,4,5,6,"setId3",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host4",1,2,3,4,5,6,"setId4",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host5",1,2,3,4,5,6,"setId5",7,8,9,10,"v2"));
endpointFList.add(new EndpointF("host5",1,2,3,4,5,6,"setId5",7,8,9,10,"v3"));
activeEp.setValue(endpointFList);
//3. 輸出過濾前資訊
System.out.println("過濾前節點資訊如下:");
for( EndpointF endpoint : endpointFList){
System.out.println(endpoint.toString());
}
//4. 對存活節點按subset規則過濾
Holder<List<EndpointF>> filterActiveEp = subsetFilter.subsetEndpointFilter(objectName, routeKey, activeEp);
//5. 輸出過濾結果
System.out.println("過濾后節點資訊如下:");
for( EndpointF endpoint : filterActiveEp.getValue() ){
System.out.println(endpoint.toString());
}
}
測驗結果如下:

最后

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/300117.html
標籤:其他
