Spring Cloud Gateway中的权重路由

Stella981
• 阅读 1208

摘要:本文主要通过运用Spring Cloud Gateway的WeightRoutePredicateFactory对URL进行权重路由。

1.权重路由

1.1 权重路由使用场景

在开发或者测试的时候,或者线上发布,线上服务多版本控制的时候,需要对服务提供权重路由,最常见的使用就是,一个服务有两个版本,旧版本V1,新版本v2。在线上灰度的时候,需要通过网关动态实时推送,路由权重信息。比如95%的流量走服务v1版本,5%的流量走服务v2版本。

Spring Cloud Gateway中的权重路由

issue: The Spring Cloud Gateway issue of Allow Rolling Deployments https://github.com/spring-cloud/spring-cloud-gateway/issues/67

1.2 Spring Cloud Gateway权重路由原理

Spring Cloud Gateway中提供了 org.springframework.cloud.gateway.handler.predicate.WeightRoutePredicateFactory去实现根据分组设置权重进行路由,因此使用起来相对比较简单,有兴趣的可以debug阅读源码。

  1. public class WeightRoutePredicateFactory extends AbstractRoutePredicateFactory<WeightConfig> implements ApplicationEventPublisherAware {

  2. private static final Log log = LogFactory.getLog(WeightRoutePredicateFactory.class);

  3. public static final String GROUP_KEY = WeightConfig.CONFIG_PREFIX + ".group";

  4. public static final String WEIGHT_KEY = WeightConfig.CONFIG_PREFIX + ".weight";

  5. private ApplicationEventPublisher publisher;

  6. public WeightRoutePredicateFactory() {

  7. super(WeightConfig.class);

  8. }

  9. [@Override](https://my.oschina.net/u/1162528)

  10. public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {

  11. this.publisher = publisher;

  12. }

  13. [@Override](https://my.oschina.net/u/1162528)

  14. public List<String> shortcutFieldOrder() {

  15. return Arrays.asList(GROUP_KEY, WEIGHT_KEY);

  16. }

  17. [@Override](https://my.oschina.net/u/1162528)

  18. public String shortcutFieldPrefix() {

  19. return WeightConfig.CONFIG_PREFIX;

  20. }

  21. [@Override](https://my.oschina.net/u/1162528)

  22. public void beforeApply(WeightConfig config) {

  23. if (publisher != null) {

  24. publisher.publishEvent(new WeightDefinedEvent(this, config));

  25. }

  26. }

  27. [@Override](https://my.oschina.net/u/1162528)

  28. public Predicate<ServerWebExchange> apply(WeightConfig config) {

  29. return exchange -> {

  30. Map<String, String> weights = exchange.getAttributeOrDefault(WEIGHT_ATTR,

  31. Collections.emptyMap());

  32. String routeId = exchange.getAttribute(GATEWAY_PREDICATE_ROUTE_ATTR);

  33. // all calculations and comparison against random num happened in

  34. // WeightCalculatorWebFilter

  35. String group = config.getGroup();

  36. if (weights.containsKey(group)) {

  37. String chosenRoute = weights.get(group);

  38. if (log.isTraceEnabled()) {

  39. log.trace("in group weight: "+ group + ", current route: " + routeId +", chosen route: " + chosenRoute);

  40. }

  41. return routeId.equals(chosenRoute);

  42. }

  43. return false;

  44. };

  45. }

  46. }

2.Spring Cloud Gateway中的权重路由案例

2.1 案例代码地址

https://github.com/SoftwareKing/sc-gateway/tree/master/ch4

2.2 Spring Cloud Gateway Server说明

Spring Cloud Gateway will dispatch 95% of the requests to version 1 and 5% of the traffic to version 2 of a specified service, as shown by the following figure.

Spring Cloud Gateway中的权重路由

我们通过在Spring Cloud Gateway中会配置不同的权重信息到不同URL上,Spring Cloud Gateway会根据我们配置的路由权重信息,将请求分发到不同的源服务组,权重信息如ch4/ch4-gateway中的application.yml所示,主要配置信息如下。

  1. spring:

  2. application:

  3. name: ch4-gateway

  4. cloud:

  5. gateway:

  6. routes:

  7. - id: service1_v1

  8. uri: http://localhost:8081/v1

  9. predicates:

  10. - Path=/test

  11. - Weight=service1, 95

  12. - id: service1_v2

  13. uri: http://localhost:8081/v2

  14. predicates:

  15. - Path=/test

  16. - Weight=service1, 5

Weight=service1, 95,Weight=service1, 5就是路由的权重信息。

2.3 源服务

源服务在本案例中源服务如ch4-service-provider所示,主要提提供Gateway Server权重路由对应的后端源服务。因为比较简单因此不做详细说明,主要代码如下所示。

  1. package org.xujin.sc.service;

  2. import org.springframework.web.bind.annotation.RequestMapping;

  3. import org.springframework.web.bind.annotation.RestController;

  4. import reactor.core.publisher.Mono;

  5. @RestController

  6. public class ServiceController {

  7. @RequestMapping(value = "/v1", produces = "text/plain;charset=UTF-8")

  8. public Mono<String> v1() {

  9. return Mono.just("v1");

  10. }

  11. @RequestMapping(value = "/v2", produces = "text/plain;charset=UTF-8")

  12. public Mono<String> v2() {

  13. return Mono.just("v2");

  14. }

  15. }

2.4 测试

分别启动ch4-gateway,ch4-service-provider进行访问:http://localhost:8080/test 测试,发现会根据所设权重进行路由。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
Nepxion Discovery 5.4.2 发布
发布日志版本更新:升级SpringBoot到2.1.9.RELEASE服务端更新:增加服务本身的权重路由修复叠加执行权重规则和版本区域策略会失效的Bug修复DiscoveryEnabledStrategy中apply方法执行两次的Bug
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这