• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

[spring cloud gateway]ymlRoute Predicate的配置

武飞扬头像
bugs_more_more
帮助1

前言

本章节将介绍yml中 predicate中都可以配置哪些内容

下面所有的例子中,最终都要通过gateway路由到(跳转到)下面这个服务的ping接口

学新通

The After Route Predicate Factory

意思就是在predicate中配置一个叫做after的参数,直接先上图,然后讲解

  1.  
    spring:
  2.  
    cloud:
  3.  
    gateway:
  4.  
    routes:
  5.  
    - id: order-route
  6.  
    uri: http://localhost:8001
  7.  
    predicates:
  8.  
    - After=2017-01-20T17:42:47.789-07:00[America/Denver]
  9.  
    filters:
  10.  
    - StripPrefix=1
  11.  
    #StripPrefix会将url如/api/order/ping中的/api去掉后跟-path的值匹配,如果不想去掉/api就把这个去掉就行

 作用:只有你当前发起的请求的时间在这个after属性设置的时间之后,才能将请求路由到uri设置的地址上。看下面例子:

我当前gateway服务的实在localhost:9001上,gateway配置如下
学新通

我要请求的内容实在localhost:8001上,如下:

学新通

假设我当前发送请求的时间是2022-07-07 14:45,根据上面的配置,我当前的时间实在after设置的之后,是满足这个设置的,所以当我起如下请求时localhost:9001/api/order/ping时,gateway会拦截到这个请求,然后检查他的请求时间满足我们after的设置,然后就会把这个请求路由到(转发到)localhost:8001/order/ping(为什么会变成这个url参考前面内容,不是这章的内容),然后就会得到一个pong的值。

但是如果我们现在把after属性的时间改成2024年(当前时间时2022年)如下:
学新通

当前发送请求的时间时2016年,那么他就不满足after设置,这是gateway就会报错,如下:

 学新通

 这就是after的作用。

The before Route Predicate Factory

  1.  
    spring:
  2.  
    cloud:
  3.  
    gateway:
  4.  
    routes:
  5.  
    - id: order-route
  6.  
    uri: http://localhost:8001
  7.  
    predicates:
  8.  
    - Before=2017-01-20T17:42:47.789-07:00[America/Denver]
  9.  
    filters:
  10.  
    - StripPrefix=1

before与after作用相同,只不过判断的条件不同,after是请求时间在after设置的时间之后就true,而before是请求的时间在before设置的时间之前才为true。例子我就不写了,参考after就行

The Between Route Predicate Factory

  1.  
    spring:
  2.  
    cloud:
  3.  
    gateway:
  4.  
    routes:
  5.  
    - id: order-route
  6.  
    uri: http://localhost:8001
  7.  
    predicates:
  8.  
    - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

作用:只有当前请求的时间在between设置的时间之间时,表示才会路由(转发)到uri对应的地址上。具体根after和before相同,就不再举例

The Cookie Route Predicate Factory

  1.  
    spring:
  2.  
    cloud:
  3.  
    gateway:
  4.  
    routes:
  5.  
    - id: order-route
  6.  
    uri: http://localhost:8001
  7.  
    predicates:
  8.  
    - Cookie=chocolate, ch.p

作用:只有当前请求中中含有一个name为chocolate,他的值为ch.p的cookie时,表示才会路由(转发)到uri对应的地址上。

例子:
学新通

 因为请求中设置了cookie,与yml中设置的对应,所以请求成功了,否则请求失败。

The Headers Route Predicate Factory

  1.  
    spring:
  2.  
    cloud:
  3.  
    gateway:
  4.  
    routes:
  5.  
    - id: order-route
  6.  
    uri: http://localhost:8001
  7.  
    predicates:
  8.  
    - Header=X-Request-Id, \d
  9.  
    #Hearder中必须包含一个X-Request-Id的字段,他的值必须满足这个正则表达式

作用:只有当前请求中中含有一个名为X-Request-Id,他的值为数字开头header时,表示才会路由(转发)到uri对应的地址上。

看例子:
学新通

 当header中含有X-Requet-Id,并且其值为数字时(满足了yml中正则表达式),就可以成功请求。否则报错404。

The host Route Predicate Factory

  1.  
    spring:
  2.  
    cloud:
  3.  
    gateway:
  4.  
    routes:
  5.  
    - id: order-route
  6.  
    uri: http://localhost:8001
  7.  
    predicates:
  8.  
    - Host=**.somehost.org,**.anotherhost.org
  9.  
    #header中的host的值必须满足这个正则表达式

作用:只有当前请求的header中包含一个host属性时,并且host的值满足上面的设置时,才会路由(转发)到uri对应的地址上。

例子:

学新通

 虽然我的请求的地址时localhost,但是只要我的header中的host属性满足yml中host的规则就可以请求成功,否则会报404错误。

The Method Route Predicate Factory

  1.  
    spring:
  2.  
    cloud:
  3.  
    gateway:
  4.  
    routes:
  5.  
    - id: order-route
  6.  
    uri: http://localhost:8001
  7.  
    predicates:
  8.  
    - Method=GET,POST #只有当前时get或者post请求才行

作用:请求有四种方法get,post,put,delete,只有当前请求你用的方法与yml中-Method设置的相匹配时,才会路由(转发)到uri对应的地址上。

例子:
学新通

 当使用的方法与yml中的Method的配置(get,post)不匹配时,请求就失败了。只有请求时我把红框里改为get或者post请求才会成功

The Path Route Predicate Factory

这个是最常用的一个,先看配置

  1.  
    spring:
  2.  
    cloud:
  3.  
    gateway:
  4.  
    routes:
  5.  
    - id: order-route
  6.  
    uri: http://localhost:8001
  7.  
    predicates:
  8.  
    - Path=/api/order/** #请求地址出去ip:端口后其他部分与这个匹配才行

作用:当请求除去ip地址:端口这部分后,剩余的部分(也成为path部分)与我们yml设置的Path匹配时,才会路由(转发)到uri对应的地址上。

例子:
学新通

 我的请求中path部分与yml中path的设置匹配,所以请求就会成功访问

另外i,我们还可以这样写:

  1.  
    predicates:
  2.  
    - Path=/red/{segment},/blue/{segment}

这个{segment}表示一种路径变量,比如当你的请求path时/red/1,或者/red/a时,那么我们在GatewayFilter类中就可以通过代码获取到这个1,和a,如下:

  1.  
    Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
  2.  
     
  3.  
    String segment = uriVariables.get("segment");

The Query Route Predicate Factory

所谓Query指的就是我们请求中的请求参数。先看yml

  1.  
    spring:
  2.  
    cloud:
  3.  
    gateway:
  4.  
    routes:
  5.  
    - id: order-route
  6.  
    uri: http://localhost:8001
  7.  
    predicates:
  8.  
    - Query=id #值也可以写多个,用逗号隔开,另外这个值还可以使用正则表达式

作用:我们的请求中必须带有query指定的内容,请求才能匹配成功,才会路由(转发)到uri对应的地址上。

例子:

学新通

 一定要注意:-Query=value1,value2,这样配置时是一个并列关系,也就是请求中必须同时含有这个两个参数才行。

The RemoteAddress Route Predicate Factory

意思指定客户端也就是发起请求的电脑的ip地址必须是我yml中配置的ip才行

  1.  
    spring:
  2.  
    cloud:
  3.  
    gateway:
  4.  
    routes:
  5.  
    - id: order-route
  6.  
    uri: http://localhost:8001
  7.  
    predicates:
  8.  
    - RemoteAddr=192.168.1.104 #还可以使用192.168.1.104/24的形式,24是掩码位数

作用:发起请求的电脑的ip地址必须是-RemoteAddr指定的,请求才能匹配成功,才会路由(转发)到uri对应的地址上。

例子:

学新通

 我的局域网ip是192.168.1.104,与yml配置匹配,所以就成功了。
注意:请求时不能用localhost或者127.0.0.1,这样都是无效的,这样会导致服务端判断来源的时候取得的网卡地址为0.0.0.0。一定要写自己的ip地址

The Weight Route Predicate Factory

意思就是通过权重的方式指定路由到uri的比例。使用weight时,它要包含2个参数,一个是group,一个是weight的值,如下配置中group1就是参数1的group,8和2就是参数2的weight。

  1.  
    spring:
  2.  
    cloud:
  3.  
    gateway:
  4.  
    routes:
  5.  
    - id: weight_high
  6.  
    uri: https://weighthigh.org
  7.  
    predicates:
  8.  
    - Weight=group1, 8
  9.  
    - id: weight_low
  10.  
    uri: https://weightlow.org
  11.  
    predicates:
  12.  
    - Weight=group1, 2

比如这个配置,就是说10次请求的话,8次将请求到https//weighthigh.org这个uri中的接口,2次将请求到https//weightlow.org这个uri中的接口.因为本人就一台机器,就不做例子了。

Modifying the Way Remote Addresses Are Resolved

一般来说我们都直接接受客户端发来的请求,但是有的时候,我们会在gateway服务前面加上一个类似于nginx这样的代理服务器,这是如果我们在yml中使用-RemoteAddr来配置时就有问题了。因为这是请求进来的所有地址都似乎代理服务器的地址,不是客户端(真正发请求的人)的地址,所以就用到这里方案RemoteAddressResolver,其原理就是通过解析请求的header中的 X-Forwarded-For,如果不懂这个名字,可以去百度。

这里说一下请求中的header中写X-Forwarded-For的格式:

X-Forwarded-For 请求头格式非常简单,就这样:

X-Forwarded-For: client, proxy1, proxy2

可以看到,XFF 的内容由「英文逗号 空格」隔开的多个部分组成,最开始的是离服务端最远的设备 IP,然后是每一级代理设备的 IP。

如果一个 HTTP 请求到达服务器之前,经过了三个代理 Proxy1、Proxy2、Proxy3,IP 分别为 IP1、IP2、IP3,用户真实 IP 为 IP0,那么按照 XFF 标准,服务端最终会收到以下信息:

X-Forwarded-For: IP0, IP1, IP2

例子 :这个的配置较为麻烦,仔细看

首先因为要使用RemoteAddressResolver(这是个接口),我们要先把他的实现类放到容器中,所以先做一下配置:

  1.  
    //这段代码放到启动类中也行,过着自己放在一个有@Configuration注解的类中也行
  2.  
    RemoteAddressResolver resolver = XForwardedRemoteAddressResolver.maxTrustedIndex(3);
  3.  
    //这个ip就好比在yml中-RemoteAddr设置的ip作用一样【1】
  4.  
    private static final String [] remoteAddr={ "192.168.1.104"};
  5.  
    @Bean
  6.  
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
  7.  
    return builder.routes().route("order_route",
  8.  
    r -> r.path("/api/order/ping")
  9.  
    .and().remoteAddr(resolver,remoteAddr)
  10.  
    .filters(f-> f.stripPrefix(1))
  11.  
    .uri("http://localhost:8001"))
  12.  
    .build();
  13.  
    }

要使用RemoteAddresszReslover的话就要使用代码方式,不能通过yml方式,所以这里配置router的就不要在yml配置了,其他的router可以在yml中配置,最后会合并二者。

然后,我们通过postman发起请求如下:
学新通

 我们看到请求成功了。

下面我说一下过程:
XForwardedRemoteAddressResolver会解析postman中学新通

 然后会把这三个值的顺序进行一个反转放在一个数组为[0.0.0.3,0.0.0.2,192.168.1.104],

然后我们maxTrustedIndex(3)实际会指向数组的第三个值也就是192.168.1.104,然后拿着这个值根变量remoteAddr的值比较,如果相同说明匹配成功,就可以转发到localhost:8001/order/ping,就请求成功了。


 

关于这个以下几个点需要明白:
1.在header中X-Forwardared-For的书写规则(上面写了)。
2.代码中api的maxTrustedIndex(index)这个index是对应的X-Forwarded-For右侧的第几个(从1开始),至于原因在上面原理说过。

官网中的图就是上面那段原理的意思
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfjaiji
系列文章
更多 icon
同类精品
更多 icon
继续加载