開發者說:基於 Nacos 的網關灰度路由和服務權重灰度

瀏覽器 集成開發環境 XML 啟迪雲Tuscloud 2019-06-16


開發者說:基於 Nacos 的網關灰度路由和服務權重灰度


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


開發者說:基於 Nacos 的網關灰度路由和服務權重灰度


環境搭建和運行



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>



開發者說:基於 Nacos 的網關灰度路由和服務權重灰度



每個服務調用的區域都可以自行指定,見下面第二條。當所有服務都選同一區域的時候,可以簡化成下面第一條

<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>



開發者說:基於 Nacos 的網關灰度路由和服務權重灰度



每個服務調用的版本都可以自行指定,見下面第二條。當所有服務都選同一版本的時候,可以簡化成下面第一條:

<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>
開發者說:基於 Nacos 的網關灰度路由和服務權重灰度



  • 增加服務權重的灰度規則,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>


開發者說:基於 Nacos 的網關灰度路由和服務權重灰度



驗證服務灰度權重調用

重複“驗證無灰度發佈和路由的調用”步驟,結果顯示,在反覆執行下,只會調用到符合服務灰度權重的服務,請仔細觀察被隨機權重調用到的概率。