optimize gray-release router example

1. optimize gray-release router example
2. fix some router bugs
pull/199/head
andrew shan 3 years ago committed by GitHub
parent 2b82768727
commit 553667fc16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -116,6 +116,10 @@ public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered
} }
// pass label by header // pass label by header
if (escapeLabels.size() == 0) {
requestTemplate.header(RouterConstants.ROUTER_LABEL_HEADER);
return;
}
requestTemplate.header(RouterConstants.ROUTER_LABEL_HEADER, JacksonUtils.serialize2Json(escapeLabels)); requestTemplate.header(RouterConstants.ROUTER_LABEL_HEADER, JacksonUtils.serialize2Json(escapeLabels));
} }

@ -0,0 +1,263 @@
# Spring Cloud Polaris Gray Release Example
[English](./README.md) | 简体中文
## 项目说明
本项目演示如何使用 Spring Cloud Tencent 的路由和标签透传功能 完成 Spring Cloud 应用的全链路灰度。
## 示例架构
![](https://qcloudimg.tencent-cloud.cn/raw/488182fd3001b3e77d9450e2c8798ff3.png)
本示例请求都通过最上层网关进行分发分发的目的地主要涉及3个环境
- 灰度环境1只针对uid=1的请求放开环境标识为env=green绿色环境
- 灰度环境2只针对uid=2的请求放开环境标识为env=purple紫色环境
- 基线环境稳定的业务版本针对其他请求放开环境标识为env=blue蓝色环境
## 如何接入
### 启动网关服务
1. 添加环境变量
- 北极星服务端地址polaris_address=grpc://127.0.0.1:8091
- 可观测性PushGateway地址prometheus_address=127.0.0.1:9091
2. 启动router-grayrelease-gateway应用
- IDE直接启动找到主类 `GrayReleaseGatewayApplication`,执行 main 方法启动应用。
- 打包编译后启动:首先执行 `mvn clean package` 将工程编译打包,然后执行 `java -jar router-grayrelease-gateway-${verion}.jar`启动应用。
3. 添加路由规则
通过往北极星接口发送以下数据为网关服务添加路由规则路由规则可以针对用户ID进行环境的分发。
````
POST /naming/v1/routings
[{
"service": "gray-release-gateway",
"namespace": "default",
"outbounds": [
{
"sources": [
{
"service": "gray-release-gateway",
"namespace": "default",
"metadata": {
"${http.header.uid}": {
"type": "EXACT",
"value": "2"
}
}
}],
"destinations": [
{
"service": "*",
"namespace": "*",
"metadata": {
"env": {
"type": "EXACT",
"value": "purple"
}
},
"priority": 0,
"weight": 100,
"isolate": false
}]
},
{
"sources": [
{
"service": "gray-release-gateway",
"namespace": "default",
"metadata": {
"${http.header.uid}": {
"type": "EXACT",
"value": "1"
}
}
}],
"destinations": [
{
"service": "*",
"namespace": "*",
"metadata": {
"env": {
"type": "EXACT",
"value": "green"
}
},
"priority": 0,
"weight": 100,
"isolate": false
}]
},
{
"sources": [
{
"service": "gray-release-gateway",
"namespace": "default",
"metadata": {
"*": {
"type": "EXACT",
"value": "*"
}
}
}],
"destinations": [
{
"service": "*",
"namespace": "*",
"metadata": {
"env": {
"type": "EXACT",
"value": "blue"
}
},
"priority": 0,
"weight": 100,
"isolate": false
}]
}
]
}]
````
路由规则也可以通过北极星控制台进行定义,最终控制台效果如下:
![](https://qcloudimg.tencent-cloud.cn/raw/28e3d734c4b73624869a5b9b7059b118.png)
### 启动Front服务
#### 启动基线环境(蓝色)
1. 添加环境变量
- 北极星服务端地址polaris_address=grpc://127.0.0.1:8091
- 可观测性PushGateway地址prometheus_address=127.0.0.1:9091
- 环境标识SCT_METADATA_CONTENT_env=blue
- 透传环境标识SCT_METADATA_CONTENT_TRANSITIVE=env
2. 启动router-grayrelease-frontend应用
- IDE直接启动找到主类 `GrayReleaseFrontApplication`,执行 main 方法启动应用。
- 打包编译后启动:首先执行 `mvn clean package` 将工程编译打包,然后执行 `java -jar router-grayrelease-frontend-${verion}.jar`启动应用。
#### 启动灰度环境1绿色
1. 添加环境变量
- 北极星服务端地址polaris_address=grpc://127.0.0.1:8091
- 可观测性PushGateway地址prometheus_address=127.0.0.1:9091
- 环境标识SCT_METADATA_CONTENT_env=green
- 透传环境标识SCT_METADATA_CONTENT_TRANSITIVE=env
2. 启动router-grayrelease-frontend应用与前面一致
如果遇到端口冲突,可以通过-Dserver.port来指定端口
#### 启动灰度环境2紫色
1. 添加环境变量
- 北极星服务端地址polaris_address=grpc://127.0.0.1:8091
- 可观测性PushGateway地址prometheus_address=127.0.0.1:9091
- 环境标识SCT_METADATA_CONTENT_env=purple
- 透传环境标识SCT_METADATA_CONTENT_TRANSITIVE=env
2. 启动router-grayrelease-frontend应用与前面一致
#### 启动后效果
在北极星控制台可以看到gray-release-front服务下有3个节点每个节点有不同的环境标识。
![](https://qcloudimg.tencent-cloud.cn/raw/96d2bdd2fb3495f737ab278e31a4a2e7.png)
### 启动middle服务
#### 启动基线环境(蓝色)
1. 添加环境变量
- 北极星服务端地址polaris_address=grpc://127.0.0.1:8091
- 可观测性PushGateway地址prometheus_address=127.0.0.1:9091
- 环境标识SCT_METADATA_CONTENT_env=blue
- 透传环境标识SCT_METADATA_CONTENT_TRANSITIVE=env
2. 启动router-grayrelease-middle应用
- IDE直接启动找到主类 `GrayReleaseMiddleApplication`,执行 main 方法启动应用。
- 打包编译后启动:首先执行 `mvn clean package` 将工程编译打包,然后执行 `java -jar router-grayrelease-middle-${verion}.jar`启动应用。
#### 启动灰度环境2紫色
1. 添加环境变量
- 北极星服务端地址polaris_address=grpc://127.0.0.1:8091
- 可观测性PushGateway地址prometheus_address=127.0.0.1:9091
- 环境标识SCT_METADATA_CONTENT_env=purple
- 透传环境标识SCT_METADATA_CONTENT_TRANSITIVE=env
2. 启动router-grayrelease-middle应用与前面一致
### 启动back服务
#### 启动基线环境(蓝色)
1. 添加环境变量
- 北极星服务端地址polaris_address=grpc://127.0.0.1:8091
- 可观测性PushGateway地址prometheus_address=127.0.0.1:9091
- 环境标识SCT_METADATA_CONTENT_env=blue
- 透传环境标识SCT_METADATA_CONTENT_TRANSITIVE=env
2. 启动router-grayrelease-backend应用
- IDE直接启动找到主类 `GrayReleaseBackendApplication`,执行 main 方法启动应用。
- 打包编译后启动:首先执行 `mvn clean package` 将工程编译打包,然后执行 `java -jar router-grayrelease-backend-${verion}.jar`启动应用。
#### 启动灰度环境1绿色
1. 添加环境变量
- 北极星服务端地址polaris_address=grpc://127.0.0.1:8091
- 可观测性PushGateway地址prometheus_address=127.0.0.1:9091
- 环境标识SCT_METADATA_CONTENT_env=green
- 透传环境标识SCT_METADATA_CONTENT_TRANSITIVE=env
2. 启动router-grayrelease-backend应用与前面一致
### 测试
#### 基线环境路由
````
curl -H'uid:0' 127.0.0.1:59100/router/gray/route_rule
````
获取结果
````
gray-release-gateway -> gray-release-front[blue] -> gray-release-middle[blue] -> gray-release-back[blue]
````
#### 灰度环境1绿色路由
````
curl -H'uid:1' 127.0.0.1:59100/router/gray/route_rule
````
获取结果
````
gray-release-gateway -> gray-release-front[green] -> gray-release-middle[blue] -> gray-release-back[green]
````
#### 灰度环境2紫色路由
````
curl -H'uid:2' 127.0.0.1:59100/router/gray/route_rule
````
获取结果
````
gray-release-gateway -> gray-release-front[purple] -> gray-release-middle[purple] -> gray-release-back[blue]
````

@ -0,0 +1,262 @@
# Spring Cloud Polaris Gray Release Example
English | [简体中文](./README-zh.md)
## Project Explanation
This project shows how to use Spring Cloud Tencent route and transitive feature to do the full chain gray releasing.
## Architecture
![](https://qcloudimg.tencent-cloud.cn/raw/488182fd3001b3e77d9450e2c8798ff3.png)
Incoming requests dispatched from Gateway service to 3 environments
- gray1(match uid=1), env=green(green environment)
- gray2(match uid=2), env=purple(purple environment)
- baselinestable environment, match all other requests, env=blue(blue environment)
## How to access
### Start Gateway service
1. add environment variables
- polaris server address: polaris_address=grpc://127.0.0.1:8091
- pushgateway address: prometheus_address=127.0.0.1:9091
2. start router-grayrelease-gateway application
- Launch by IDEStart the main class `GrayReleaseGatewayApplication`.
- Launch by JarExecute `mvn clean package` to compile with jar package, then use `java -jar router-grayrelease-gateway-${verion}.jar` to launch application.
3. add the route rule
Send http request to polaris server to add the route rule, make requests dispatched to 3 environments.
````
POST /naming/v1/routings
[{
"service": "gray-release-gateway",
"namespace": "default",
"outbounds": [
{
"sources": [
{
"service": "gray-release-gateway",
"namespace": "default",
"metadata": {
"${http.header.uid}": {
"type": "EXACT",
"value": "2"
}
}
}],
"destinations": [
{
"service": "*",
"namespace": "*",
"metadata": {
"env": {
"type": "EXACT",
"value": "purple"
}
},
"priority": 0,
"weight": 100,
"isolate": false
}]
},
{
"sources": [
{
"service": "gray-release-gateway",
"namespace": "default",
"metadata": {
"${http.header.uid}": {
"type": "EXACT",
"value": "1"
}
}
}],
"destinations": [
{
"service": "*",
"namespace": "*",
"metadata": {
"env": {
"type": "EXACT",
"value": "green"
}
},
"priority": 0,
"weight": 100,
"isolate": false
}]
},
{
"sources": [
{
"service": "gray-release-gateway",
"namespace": "default",
"metadata": {
"*": {
"type": "EXACT",
"value": "*"
}
}
}],
"destinations": [
{
"service": "*",
"namespace": "*",
"metadata": {
"env": {
"type": "EXACT",
"value": "blue"
}
},
"priority": 0,
"weight": 100,
"isolate": false
}]
}
]
}]
````
The route rule can be added by polaris console:
![](https://qcloudimg.tencent-cloud.cn/raw/28e3d734c4b73624869a5b9b7059b118.png)
### Start Front service
#### Start baseline environment (blue)
1. add environment variables
- polaris server address: polaris_address=grpc://127.0.0.1:8091
- pushgateway address: prometheus_address=127.0.0.1:9091
- env tagSCT_METADATA_CONTENT_env=blue
- transitive tagSCT_METADATA_CONTENT_TRANSITIVE=env
2. start router-grayrelease-frontend application
- Launch by IDEStart the main class `GrayReleaseFrontApplication`.
- Launch by JarExecute `mvn clean package` to compile with jar package, then use `java -jar router-grayrelease-frontend-${verion}.jar` to launch application.
#### Start gray1 environment (green)
1. add environment variables
- polaris server address: polaris_address=grpc://127.0.0.1:8091
- pushgateway address: prometheus_address=127.0.0.1:9091
- env tagSCT_METADATA_CONTENT_env=green
- transitive tagSCT_METADATA_CONTENT_TRANSITIVE=env
2. start router-grayrelease-frontend application (same as previous instruction)
If port conflicted, you can specify another port by -Dserver.port
#### Start gray2 environment (purple)
1. add environment variables
- polaris server address: polaris_address=grpc://127.0.0.1:8091
- pushgateway address: prometheus_address=127.0.0.1:9091
- env tagSCT_METADATA_CONTENT_env=purple
- transitive tagSCT_METADATA_CONTENT_TRANSITIVE=env
2. start router-grayrelease-frontend application (same as previous instruction)
#### Start effective
You can find the instances with different tags in polaris console.
![](https://qcloudimg.tencent-cloud.cn/raw/96d2bdd2fb3495f737ab278e31a4a2e7.png)
### Start Middle service
#### Start baseline environment (blue)
1. add environment variables
- polaris server address: polaris_address=grpc://127.0.0.1:8091
- pushgateway address: prometheus_address=127.0.0.1:9091
- env tagSCT_METADATA_CONTENT_env=blue
- transitive tagSCT_METADATA_CONTENT_TRANSITIVE=env
2. start router-grayrelease-middle application
- Launch by IDEStart the main class `GrayReleaseMiddleApplication`.
- Launch by JarExecute `mvn clean package` to compile with jar package, then use `java -jar router-grayrelease-middle-${verion}.jar` to launch application.
#### Start gray2 environment (purple)
1. add environment variables
- polaris server address: polaris_address=grpc://127.0.0.1:8091
- pushgateway address: prometheus_address=127.0.0.1:9091
- env tagSCT_METADATA_CONTENT_env=purple
- transitive tagSCT_METADATA_CONTENT_TRANSITIVE=env
2. start router-grayrelease-middle application (same as previous instruction)
### Start Back service
#### Start baseline environment (blue)
1. add environment variables
- polaris server address: polaris_address=grpc://127.0.0.1:8091
- pushgateway address: prometheus_address=127.0.0.1:9091
- env tagSCT_METADATA_CONTENT_env=blue
- transitive tagSCT_METADATA_CONTENT_TRANSITIVE=env
2. start router-grayrelease-backend application
- Launch by IDEStart the main class `GrayReleaseBackendApplication`.
- Launch by JarExecute `mvn clean package` to compile with jar package, then use `java -jar router-grayrelease-backend-${verion}.jar` to launch application.
#### Start gray1 environment (green)
1. add environment variables
- polaris server address: polaris_address=grpc://127.0.0.1:8091
- pushgateway address: prometheus_address=127.0.0.1:9091
- env tagSCT_METADATA_CONTENT_env=green
- transitive tagSCT_METADATA_CONTENT_TRANSITIVE=env
2. start router-grayrelease-backend application (same as previous instruction)
### Test
#### Baseline routing
````
curl -H'uid:0' 127.0.0.1:59100/router/gray/route_rule
````
Got result
````
gray-release-gateway -> gray-release-front[blue] -> gray-release-middle[blue] -> gray-release-back[blue]
````
#### Green routing
````
curl -H'uid:1' 127.0.0.1:59100/router/gray/route_rule
````
Got result
````
gray-release-gateway -> gray-release-front[green] -> gray-release-middle[blue] -> gray-release-back[green]
````
#### Purple routing
````
curl -H'uid:2' 127.0.0.1:59100/router/gray/route_rule
````
Got result
````
gray-release-gateway -> gray-release-front[purple] -> gray-release-middle[purple] -> gray-release-back[blue]
````

@ -1,47 +1,49 @@
/* /*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available. * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
* *
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* *
* Licensed under the BSD 3-Clause License (the "License"); * Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://opensource.org/licenses/BSD-3-Clause * https://opensource.org/licenses/BSD-3-Clause
* *
* Unless required by applicable law or agreed to in writing, software distributed * Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the * CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License. * specific language governing permissions and limitations under the License.
* *
*/ */
package com.tencent.cloud.polaris.router.grayrelease.gateway; package com.tencent.cloud.polaris.router.grayrelease.gateway;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/router/gray") @RestController
public class GatewayController { @RequestMapping("/router/gray")
public class GatewayController {
@Autowired
private Environment environment; @Autowired
private Environment environment;
@Autowired
private RouterService routerService; @Autowired
private RouterService routerService;
/**
* Get information of callee. /**
* @return information of callee * Get information of callee.
*/ * @return information of callee
@GetMapping("/entry") */
public String rest() { @GetMapping("/route_rule")
String appName = environment.getProperty("spring.application.name"); public String routeRule(@RequestHeader("uid") int userId) {
String resp = routerService.rest(); String appName = environment.getProperty("spring.application.name");
return appName + " -> " + resp; String resp = routerService.restByUser(userId);
} return appName + " -> " + resp;
} }
}

@ -20,6 +20,7 @@ package com.tencent.cloud.polaris.router.grayrelease.gateway;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
/** /**
* Router callee feign client. * Router callee feign client.
@ -30,6 +31,5 @@ import org.springframework.web.bind.annotation.GetMapping;
public interface RouterService { public interface RouterService {
@GetMapping("/router/gray/rest") @GetMapping("/router/gray/rest")
String rest(); String restByUser(@RequestHeader("uid") int user);
} }

@ -84,6 +84,7 @@ public class ServiceRuleManager {
ServiceEventKey srcSvcEventKey = new ServiceEventKey(new ServiceKey(namespace, sourceService), ServiceEventKey srcSvcEventKey = new ServiceEventKey(new ServiceKey(namespace, sourceService),
ServiceEventKey.EventType.ROUTING); ServiceEventKey.EventType.ROUTING);
routerKeys.add(srcSvcEventKey);
DefaultServiceEventKeysProvider svcKeysProvider = new DefaultServiceEventKeysProvider(); DefaultServiceEventKeysProvider svcKeysProvider = new DefaultServiceEventKeysProvider();
svcKeysProvider.setSvcEventKeys(routerKeys); svcKeysProvider.setSvcEventKeys(routerKeys);

Loading…
Cancel
Save