icon designed | 阿貓阿簫
文 | 任浩軍
Nepxion Discovery Gray是Nepxion Discovery的極簡示例,有助於使用者快速入門。它基於Spring Cloud Greenwich版本而製作(使用者可自行改成Finchley版和Edgware版),主要功能包括:
- 網關灰度路由。採用配置中心配置路由規則映射在網關過濾器中植入Header信息而實現,主要包括版本路由和區域路由兩種。
- 服務灰度權重。採用配置中心配置權重規則映射在全鏈路而實現,主要包括版本權重和區域區域兩種。
- 自定義網關和服務的路由策略。採用簡單編程方式,根據業務參數綁定路由策略。
代碼地址:
https://github.com/Nepxion/DiscoveryGray
讀者可以star下上面這個開源項目,代碼值得研讀。
Nacos 是新一代集服務註冊發現中心和配置中心為一體的中間件。它是構建以“服務”為中心的現代應用架構 (例如微服務範式、雲原生範式) 的服務基礎設施,支持幾乎所有主流類型的“服務”的發現、配置和管理,更敏捷和容易地構建、交付和管理微服務平臺。
本文示例以 Nacos 為服務註冊中心和配置中心,通過 Gateway 和 Zuul 調用兩個版本或者區域的服務,模擬網關灰度路由和服務灰度權重的功能。
如果使用者需要更強大的功能,請參考:
https://github.com/Nepxion/Discovery
環境搭建和運行
1、下載代碼並導入 IDE
2、啟動 Nacos 服務器
- 從以下地址獲取nacos-server-x.x.x.zip,並解壓:
https://github.com/alibaba/nacos/releases
- 運行bin目錄下的startup命令行。
3、啟動四個實例服務和兩個網關服務,如下:
類名
微服務
服務端口
版本
區域
DiscoveryGrayServiceA1.java
A1
3001
1.0
dev
DiscoveryGrayServiceA2.java
A2
3002
1.1
qa
DiscoveryGrayServiceB1.java
B1
4001
1.0
dev
DiscoveryGrayServiceB2.java
B2
4002
1.1
qa
DiscoveryGrayGateway.java
Gateway
5001
1.0
無
DiscoveryGrayZuul.java
Zuul
5002
1.0
無
驗證無灰度發佈和路由的調用
在瀏覽器中執行http://localhost:5001/discovery-gray-service-a/invoke/gateway。測試沒有灰度配置的情況下,通過Spring Cloud Gateway網關的調用結果。該結果顯示,在反覆執行下,所有服務都會被調用到,如下:
gateway -> discovery-gray-service-a[192.168.0.107:3001][V1.0][Region=dev]
-> discovery-gray-service-b[192.168.0.107:4001][V1.0][Region=qa]
在瀏覽器中執行http://localhost:5002/discovery-gray-service-a/invoke/zuul。測試沒有灰度路由的情況下,通過Zuul網關的調用結果。該結果顯示,在反覆執行下,所有服務都會被調用到,如下:
zuul -> discovery-gray-service-a[192.168.0.107:3001][V1.0][Region=dev]
-> discovery-gray-service-b[192.168.0.107:4001][V1.0][Region=qa]
網關灰度路由策略
配置網關灰度路由規則
在Nacos配置中心,增加網關灰度路由規則
- 增加Zuul的基於區域路由的灰度規則,Group為discovery-gray-group,Data Id為discovery-gray-zuul,規則內容如下,實現從Zuul發起的調用都走區域為dev的服務:
<?xml version="1.0" encoding="UTF-8"?>
<rule>
<strategy>
<region>dev</region>
</strategy>
</rule>
每個服務調用的區域都可以自行指定,見下面第二條。當所有服務都選同一區域的時候,可以簡化成下面第一條
<region>dev</region>
<region>{"discovery-gray-service-a":"dev", "discovery-gray-service-b":"dev"}</region>
- 增加Spring Cloud Gateway的基於版本路由的灰度規則,Group為discovery-gray-group,Data Id為discovery-gray-gateway,規則內容如下,實現從Spring Cloud Gateway發起的調用都走版本為1.0的服務:
<?xml version="1.0" encoding="UTF-8"?>
<rule>
<strategy>
<version>1.0</version>
</strategy>
</rule>
每個服務調用的版本都可以自行指定,見下面第二條。當所有服務都選同一版本的時候,可以簡化成下面第一條:
<version>1.0</version>
<version>{"discovery-gray-service-a":"1.0", "discovery-gray-service-b":"1.0"}</version>
驗證網關灰度路由調用
重複“驗證無灰度發佈和路由的調用”步驟,結果顯示,在反覆執行下,只會調用到符合網關灰度路由規則的服務,請仔細觀察。
其他網關灰度路由策略
除了上面通過配置中心發佈灰度規則外,還有如下三種方式:
通過前端傳入灰度路由規則
通過前端(Postman)方式傳入灰度路由規則,來代替配置中心方式。注意:當配置中心和界面都配置後,以界面傳入優先
- 區域規則,Header格式如下任選一個:
n-d-region=dev
n-d-region={"discovery-gray-service-a":"dev", "discovery-gray-service-b":"dev"}
- 版本規則,Header格式如下任選一個:
n-d-version=1.0
n-d-version={"discovery-gray-service-a":"1.0", "discovery-gray-service-b":"1.0"}
通過自定義網關Filter設置灰度路由規則
繼承覆蓋GatewayStrategyRouteFilter和ZuulStrategyRouteFilter,並覆蓋掉如下方法:
protected String getRouteVersion();
protected String getRouteRegion();
protected String getRouteAddress();
通過跟業務參數綁定自定義路由規則
- 根據業務參數綁定路由。下面代碼既適用於Zuul和Spring Cloud Gateway網關,也適用於Service微服務:
// 實現了組合策略,版本路由策略+區域路由策略+IP和端口路由策略+自定義策略
public class DiscoveryGrayEnabledStrategy extends AbstractDiscoveryEnabledStrategy {
private static final Logger LOG = LoggerFactory.getLogger(DiscoveryGrayEnabledStrategy.class);
@Override
public boolean apply(Server server) {
// 對Rest調用傳來的Header參數(例如:mobile)做策略
String mobile = strategyContextHolder.getHeader("mobile");
String serviceId = pluginAdapter.getServerServiceId(server);
String version = pluginAdapter.getServerMetadata(server).get(DiscoveryConstant.VERSION);
LOG.info("負載均衡用戶定製觸發:mobile={}, serviceId={}, version={}", mobile, serviceId, version);
if (StringUtils.isNotEmpty(mobile)) {
// 手機號以移動138開頭,路由到1.0版本的服務上
if (mobile.startsWith("138") && StringUtils.equals(version, "1.0")) {
return true;
// 手機號以聯通133開頭,路由到2.0版本的服務上
} else if (mobile.startsWith("133") && StringUtils.equals(version, "1.1")) {
return true;
} else {
// 其它情況,直接拒絕請求
return false;
}
}
return true;
}
}
服務灰度權重策略
配置服務灰度權重規則
在Nacos配置中心,增加服務灰度權重規則。
注意:網關灰度路由和服務灰度權重功能會疊加,為了不影響演示效果,請先清除網關灰度路由的規則(在Nacos上刪除對應的兩條配置即可)。
- 增加區域權重的灰度規則,Group為discovery-gray-group,Data Id為discovery-gray-group(全局發佈,兩者都是組名),規則內容如下,實現區域為dev的服務提供90%的流量,區域為qa的服務提供10%的流量:
<?xml version="1.0" encoding="UTF-8"?>
<rule>
<discovery>
<weight>
<region provider-weight-value="dev=90;qa=10"/>
</weight>
</discovery>
</rule>
- 增加服務權重的灰度規則,Group為discovery-gray-group,Data Id為discovery-gray-group(全局發佈,兩者都是組名),規則內容如下,實現a服務1.0版本提供90%的流量,1.1版本提供10%的流量;b服務1.0版本提供20%的流量,1.1版本提供80%的流量:
<?xml version="1.0" encoding="UTF-8"?>
<rule>
<discovery>
<weight>
<service provider-service-name="discovery-gray-service-a" provider-weight-value="1.0=90;1.1=10"/>
<service provider-service-name="discovery-gray-service-b" provider-weight-value="1.0=20;1.1=80"/>
</weight>
</discovery>
</rule>
驗證服務灰度權重調用
重複“驗證無灰度發佈和路由的調用”步驟,結果顯示,在反覆執行下,只會調用到符合服務灰度權重的服務,請仔細觀察被隨機權重調用到的概率。