Spring Cloud Gateway Route Predicate Factory 的使用

Stella981
• 阅读 709

一、需求

记录Spring Cloud Gateway的一些用法,不对其原理进行过多的探究。

二、基本组成

1、简介

Spring Cloud Gateway 是 基于Spring boot 5Spring Boot 2.0Project Reactor 等技术开发的网关。它旨在为微服务提供一个简单有效的方式来管理api路由。

Spring Cloud Gateway 是基于 Netty 运行的,不能运行在传统的Servlet容器中作为War包运行。

2、核型概念

1、Route 路由

Route是网关的基本组成单元,它是有一个ID,一个目标URI和一组predicates和一组filters组成,如果一组断言结果为真,则匹配路由,目标URI会被访问。 注意: 1、多个 Predicate 之间是 逻辑and 的关系。
2、多个Predicate是从定义的顺序从上到下依次执行,也可以指定 order 属性的值。

2、Predicate 谓语、断言

Predicate 是Java 8 Function interface。输入类型是Spring Framework ServerWebExchange。可以用来匹配HTTP请求中的任何内容,例如headers 或者 parameters

3、Filter 过滤器

FilterGatewayFilter的实例。通过Filter我们可以在请求发送或返回下游服务时 修改 请求响应

3、工作原理

Spring Cloud Gateway Route Predicate Factory 的使用 上图来自 Spring 官网。

三、网关 Predicate配置方式

1、快捷配置方式(配置文件)

快捷方式是由过滤器是的名称识别,后面紧跟=,在跟以逗号(,)分隔的参数值。

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - Cookie=mycookie,mycookievalue

上一个示例使用两个参数定义了Cookie Route Predicate Factory,这两个参数是cookie名称,mycookie和与mycookievalue匹配的值

2、完全展开的参数(配置文件)

name:指定谓词工厂的名字 args:指定对应谓词工厂中的参数对应的值。

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - name: Cookie
          args:
            name: mycookie
            regexp: mycookievalue

这种方式配置和上面的快捷方式配置的是一个意思

3、上方2种方式配置和代码对应关系

Spring Cloud Gateway Route Predicate Factory 的使用

4、uri 值的方式

1、以http开头

当匹配到这个路由后,会跳转到这个地址。

2、以 lb 开头

eg:      uri: lb://service-name 解释: lb:表示负载均衡的意思
service-name:值的是调用服务在注册中心注册的服务名。

四、Route Predicate Factories

Spring Cloud Gateway内置了特别多的路由谓词工厂,用来匹配http请求。当多个一起使用时,是and的关系,即需要所有的谓词工厂都匹配,才匹配这个路由。

1、After

1、描述:

当前请求在指定时间之后才匹配

2、存在参数:

    datetime 数据类型是 ZonedDateTime,带有时区

3、配置实例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider # 名字唯一即可
          uri: lb://product-provider
          predicates:
            - After=2020-11-01T11:05:08.020+08:00[Asia/Shanghai]

2、Before

1、描述:

当前请求在指定时间之前才匹配

2、存在参数:

    datetime 数据类型是 ZonedDateTime,带有时区

3、配置实例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider # 名字唯一即可
          uri: lb://product-provider
          predicates:
            - Before=2020-11-01T11:05:08.020+08:00[Asia/Shanghai]

3、Between

1、描述:

当前请求在指定时间中间才匹配

2、存在参数:

    datetime1 数据类型是 ZonedDateTime,带有时区
    datetime2 数据类型是 ZonedDateTime,带有时区
     并且 datetime1 必须< datetime2

3、配置实例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider # 名字唯一即可
          uri: lb://product-provider
          predicates:
            - Between=2020-11-01T11:08:08.020+08:00[Asia/Shanghai],2020-11-01T11:15:08.020+08:00[Asia/Shanghai]

4、Cookie

1、描述:

当前请求中的cookie值匹配配置的cookie参数值时生效

2、存在参数:

    name 请求cookie中的参数的名字
    regexp 请求cookie中的参数的值,配置的值是Java中的正则表达式形式。

3、配置实例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider # 名字唯一即可
          uri: lb://product-provider
          predicates:
            - Cookie=token,tokenvalue\d+

Spring Cloud Gateway Route Predicate Factory 的使用

4、解释

  • Cookie=token,tokenvalue\d+
    表示 请求中必须存在一个 cookie 的key 是 token 的,且值必须是 tokenvalue 后面加上一个数子才匹配的上,否则匹配不上。

5、Header

1、描述:

当前请求中的header值匹配配置的header参数值时生效

2、存在参数:

    name header key的名字
    regexp header key对应的值,配置的Java中的正则表达式形式

3、配置实例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider # 名字唯一即可
          uri: lb://product-provider
          predicates:
            - Header=X-Token-Id,\d+

4、解释

  • Header=X-Token-Id,\d+ 表示请求头中必须存在R-Token-Id且它的值必须是数字

6、Host

1、描述:

匹配请求头中的Host的值

2、存在参数:

    patterns 配置一系列的以.作为分隔的ant风格host地址,多个中间以,隔开。Host中配置的值还支持URI template variables ,比如{xxx}.baidu.com

3、配置实例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider # 名字唯一即可
          uri: lb://product-provider
          predicates:
            - Host=**.gateway.com,{study}.baidu.com

Spring Cloud Gateway Route Predicate Factory 的使用

4、解释

  • Host=**.gateway.com,{study}.baidu.com 1、**.gateway.com:表示请求中的Host的值需要配置这种ant风格
    2、{study}.baidu.comstudy这个模版变量可以在GatewayFilter中获取到,通过ServerWebExchange.getAttributes().get(ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE)获取

7、Method

1、描述:

匹配请求头中的Method的值

2、存在参数:

    methods 需要匹配的方法,比如GETPOST

3、配置实例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider # 名字唯一即可
          uri: lb://product-provider
          predicates:
            - Method=GET,POST,PUT # 只有get,post,put请求才能匹配上方这个路由

8、Path

1、描述:

匹配请求路径。

2、存在参数:

    patterns 需要匹配的路径eg: /product/{id},/product/**
    matchOptionalTrailingSeparator 一个可选的参数

3、配置实例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider # 名字唯一即可
          uri: lb://product-provider
          predicates:
            - Path=/product/findOne/{productId},/product/**

4、解释

/product/findOne/{productId} 支持uri模版变量,productId可以在GatewayFilter中获取,获取方式.

Map<string, string> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
String segment = uriVariables.get("productId");

9、Query

1、描述:

匹配请求参数。

2、存在参数:

    param 请求参数的key值
    regexp 请求参数的值,配置的值是Java中的正则表达式形式。

3、配置实例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider # 名字唯一即可
          uri: lb://product-provider
          predicates:
            #- Query=pwd
            - Query=username,\d+

4、解释

1、Query=pwd 表示请求中必须存在 pwd这个请求参数
2、Query=username,\d+ 表示请求中必须存在username这个参数,且它的值必须是数字

10、RemoteAddr

1、描述:

匹配请求的ip地址,支持ipv4和ipv6。

2、存在参数:

    sources 地址列表eg:127.0.0.1/16 后方的/16是子网掩码

3、配置实例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider # 名字唯一即可
          uri: lb://product-provider
          predicates:
            - RemoteAddr=127.0.0.1/16

4、注意

如果我们的Spring Cloud Gateway是位于代理后面,那么获取到远程地址可能不正确,此时我们可以自己编写一个RemoteAddressResolver来解决。

参考链接:https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#the-weight-route-predicate-factory

11、Weight

1、描述:

根据权重来分发请求,权重是根据group来计算的。

2、存在参数:

    group 组,权重根据组来计算
    weight 权重值,是一个 Int 的值

3、配置实例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider
          uri: https://weighthigh.org
          predicates:
            - Weight=group1,8
        - id: user-consumer
          uri: https://weightlow.org
          predicates:
            - Weight=group1,2

4、解释

上方配置会导致80%的请求落到 https://weighthigh.org,有20%的请求落到https://weightlow.org

五、自己编写一个 route predicate factory

1、编写步骤

1、编写一个类,实现RoutePredicateFactory接口,或继承AbstractRoutePredicateFactory
    > 1、AbstractRoutePredicateFactory 中的 C 表示 配置文件类
    > 2、重写shortcutFieldOrder此方法,表示的配置文件中参数的位置
    > 3、重写apply(C c)方法,表示的是具体的业务逻辑
2、我们自己编写的类必须要以RoutePredicateFactory结尾,否则比较麻烦,参考 org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#initFactories 这个方法。

2、要实现的功能

判断请求参数中是否存在 token 配置的值。

3、Java代码

@Slf4j
@Component
public class TokenRoutePredicateFactory extends AbstractRoutePredicateFactory<tokenroutepredicatefactory.config> {

    public TokenRoutePredicateFactory() {
        super(Config.class);
    }

    @Override
    public List<string> shortcutFieldOrder() {
        return Lists.newArrayList("token");
    }

    @Override
    public Predicate<serverwebexchange> apply(Config config) {
        return exchange -&gt; {
            log.info("判断请求头中是否存在token这个参数");
            String token = exchange.getRequest().getQueryParams().getFirst(config.getToken());
            return StringUtils.isNotBlank(token);
        };
    }

    @Data
    public static class Config {
        private String token;
    }
}

4、配置文件

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider
          uri: lb://product-provider
          predicates:
            - Token=token

5、解释

Spring Cloud Gateway Route Predicate Factory 的使用

六、完整代码

https://gitee.com/huan1993/spring-cloud-alibaba-parent/tree/master/gateway

七、参考链接

https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
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
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
2个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这