springcloud(九)--SpringCloud GateWay网关

一、概述简介

1.官网

上一代 zzul 1.X : https://github.com/Netflix/zuul/wiki
在这里插入图片描述
服务网关还可以用Zuul网关,但是Zuul网关由于一些维护问题,所以这里我们学习Gateway网关

GateWay官网:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/
在这里插入图片描述

2.SpringCloud Gateway是什么?

概述:
SpringCloud全家桶里有个很重要的组件就是网关, 在1.x的版本中都是采用Zuul网关;
但在2.x版本中,Zuul的升级一直跳票,SpringCloud最后自己研发了一个网关代替Zuul,
就是说SpringCloud Gateway一句话:gateway是原Zuul1.x版的替代
在这里插入图片描述
Gateway是在Spring生态系统之上构建的API网关服务,基于Spring 5,Spring Boot 2和Project Reactor等技术。
Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤功能,例如:熔断、限流、重试等。
在这里插入图片描述

SpringCloud Gateway是Spring Cloud 的全新项目,是基于 Spring 5.0 + Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它指在为微服务构架提供一种简单有效的统一的 API 的链路管理方式。

SpringCloud Gateway作为Spring Cloud生态系统中的网关,目的是替代Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高新能版本进行集成,仍然使用的是Zuul 1.x非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
SpringCloud Gateway的目标是提供统一的路由方式且基于 Filter 链的方式提供了网关基本的功能,例如:安全、监控/指标,和限流等。

SpringCloud Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架

3.SpringCloud Gateway能做什么?

  • 反向代理
  • 鉴权
  • 流量控制
  • 熔断
  • 日志监控

微服务架构中网关的位置:
在这里插入图片描述

4.SpringCloud Gateway 与 Zuul的区别

1.netflix不太靠谱,zuul2.0一直跳票,迟迟不发布
一方面因为Zuul1.0已经进入维护阶段,而且Gateway是SpringCloud团队研发的,是亲人子产品,值得信赖。而且很多功能Zuul都没有,gateway用起来也非常简单便捷。

Gateway是基于异步非阻塞模型上进行开发的,性能方面不需要担心。虽然Netflix早就发布了最新的 Zuul 2.x,但 Spring Cloud 貌似没有整合计划。而且Netflix相关组件都宣布进入维护期;不知道前景如何?

多方面综合考虑Gateway是很理想的网关选择。

①Spring Cloud Gateway特性

  • 基于Spring Framework 5, Project Reactor和SpringBoot 2.x进行构建
  • 动态路由:能够匹配任何请求属性;
  • 可以对路由指定Predicate(断言) 和 Filter(过滤器);
  • 集成Hystrix的熔断器功能;
  • 集成SpringCloud服务发现功能;
  • 请求限流功能;
  • 支持路径重写等等。

SpringCloud Gateway 与 Zuul的区别
在SpringCloud Finchley 正式版以前,Spring Cloud 推荐的网关是 Netflix 提供的 Zuul:

1、Zuul 1.x, 是一个基于阻塞I/O的 API Gateway;

2、Zuul 1.x 基于Servlet 2.5 使用阻塞架构它不支持任何长连接(如 WebSocket)Zuul 的设计模式和Nginx较像,每次 I/O 操作都是从工作线程中选择一个执行,请求线程被阻塞到工作线程完成,但是差别是Nginx 是用C++ 实现的,Zuul 用 Java 实现,而JVM本身会有第一次加载较慢的情况,使得Zuul 的性能相对较差。

3、Zuul 2.x 理念更先进,想基于Netty非阻塞和支持长连接,但是Spring Cloud目前还没有整合。Zuul 2.x 的性能较 Zuul 1.x 有较大提升。在性能方面,根据官方提供的基准测试,Spring Cloud Gateway 的 RPS(每秒请求数)是Zuul 的 1.6 倍。

4、Spring Cloud Gateway基于Spring Framework 5、 Project Reactor和Spring Boot 2 之上,使用非阻塞 API。

5、Spring Cloud Gateway还支持 WebSocket,并且与Spring紧密集成拥有更好的开发体验

②Zuul1.x 模型

Springcloud中所集成的Zuul版本,采用的是Tomcat容器,使用的是传统的Servlet IO 处理模型。

Servlet的生命周期?servlet container进行生命周期管理。
container启动时构造servlet对象并调用servlet init()进行初始化;
container运行时接受请求,并为每个请求分配一个线程(一般线程池中获取空闲线程)然后调用service()。
container关闭是调用servlet destory()销毁servlet;
在这里插入图片描述
上述模式的缺点:
servlet是一个简单的网络IO模型,当请求进入srevlet container时,servlet container就会为其绑定一个线程,在并发不高的场景下这种模型是适用的。但是一旦高并发,线程数量就会上涨,而而线程资源代价是昂贵的(上线文切换,内存消耗大)严重影响请求的处理时间。在一些简单业务场景下,不希望为每个request分配一个线程,只需要1个或者几个线程就能应对极大并发的请求,这种业务场景下servlet模型没有优势

所以在Zuul 1.x 是基于servlet之上的一个阻塞式处理模型,即spring实现了处理所有request请求的一个servlet(DispatcherServlet)并由该servlet阻塞式处理处理。所以Springcloud Zuul无法摆脱servlet模型的弊端。

③GateWay模型

WebFlux 是什么

WebFlux 官方文档: https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#spring-webflux

在这里插入图片描述
在这里插入图片描述

WebFlux 模块的名称是spring-webflux,名称中的Flux 来源Reactor中的类Flux。Spring webflux 有一个全新的非堵塞的函数式 Reactive Web 框架,可以用来构建异步的、非堵塞的、事件驱动的服务,在伸缩性方面表现非常好。

传统的Web框架,比如说:struts2, springmvc等都是基于Servlet API 容器基础上运行的。
但是
在Servlet3.1之后有了异步非堵塞的支持。而WebFlux是一个典型非堵塞异步的框架,它的核心是基于Reactor的相关API实现的。相对于传统的web框架来说,它可以运行在诸如Netty,Undertow及支持Servlet3.1的容器上。非阻塞式+函数式编程(spring5必须让你使用java8以上)

Spring WebFlux是 Spring 5.0 引入的新的响应式框架,区别于 Spring MVC,它不需要依赖Servlet API,它是完全异步非阻塞的,并且基于 Reactor 来实现响应式流规范。

二、三大核心概念

1.Route(路由)

路由是构建网关的基本模块,它由ID、目标URI、一系列的断言和过滤器组成,如果Predicate(断言)为true则匹配路由

2.Predicate(断言)

参考的是Java8的 java.util.function.Predicate

路由转发的判断条件,目前SpringCloud Gateway支持多种方式,常见如:Path、Query、Method、Header等,写法必须遵循 key=vlue的形式

开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言匹配则进行路由

3.Filter(过滤)

Spring框架中GatewayFilter的实例
过滤器是路由转发请求时所经过的过滤逻辑,可用于修改请求、响应内容

其中Route和Predicate必须同时申明

总体
在这里插入图片描述

Web请求,通过一些匹配条件,定位到真正的服务节点,并在这个转发过程的前后,进行一些精细化的控制。
Predicate就是这些匹配条件:
而Filter,就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标的uri,就可以实现一个具体的路由了

三、GateWay工作流程

官网总结:
在这里插入图片描述
客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。

Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。
过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。

核心逻辑:
路由转发 + 执行过滤器链

四、入门配置

新建Module:cloud-gateway-gateway-9527作为网关微服务
依赖:

       <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

pom文件:

<dependencies>
        <!-- gateway -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--eureka-client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- 引入自定义的API通用包 实体类 -->
        <dependency>
            <groupId>com.zzp.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--boot web actuator-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

application.yml配置:

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: paymentRouth  # paymentRouth    # 路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:8001          # 匹配后提供服务的路由地址
          predicates:
            - Path=/payment/get/**         # 断言,路径相匹配的进行路由

        - id: paymentRouth2  # paymentRouth2    # 路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:8001          # 匹配后提供服务的路由地址
          predicates:
            - Path=/payment/lb/**         # 断言,路径相匹配的进行路由

eureka:
  instance:
    hostname: cloud-gateway-service
  client: #服务提供者provider注册进eureka服务列表内
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka7001.com:7001/eureka

其中的spring.cloud.gateway.routes是网关路由的配置

设定9527网关要对cloud-provider-payment-8001服务提供方提供的8001端口微服务进行路由处理,我们不想暴露8001端口,希望在8001端口外面套上一层网关的9527端口,在8001微服务中有如下的两个服务:

@RestController
@Slf4j
public class PaymentController {
	@GetMapping(value = "/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){...}
    
	@GetMapping(value = "/payment/lb")
    public String getPaymentLB(){...}
}

启动7001(单机),8001,9527
不过这里9527启动报错:
在这里插入图片描述
把9527服务的pom的web actuator依赖移除:

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

启动后:
在这里插入图片描述
请求:8001
在这里插入图片描述
请求:9527
在这里插入图片描述

在这里插入图片描述

1.YML网关配置说明

①Gateway网关路由有两种配置方式

1、在配置文件中,见前面9527网关的yml文件配置

2、代码中注入 RouteLocator 的Bean

代码中注入 RouteLocator 的Bean

官网案例:
在这里插入图片描述
通过9527网关对百度新闻的百度体育页面。
手写代码配置实现访
在9527网关微服务中编写如下的配置类:

package com.zzp.springcloud.config;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author zzp
 * @create
 */
@Configuration
public class GateWayConfig {

    /**
     * 配置了一个id为pathRoute1的路由规则,
     * 当访问地址 http://localhost:9527/guonei时会自动转发到地址: http://news.baidu.com/guonei
     * @param routeLocatorBuilder
     * @return
     */
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("pathRoute1",
                r -> r.path("/guonei")
                        .uri("http://news.baidu.com/guonei")).build();
        return routes.build();
    }
    @Bean
    public RouteLocator customRouteLocator1(RouteLocatorBuilder routeLocatorBuilder) {
        RouteLocatorBuilder.Builder builder = routeLocatorBuilder.routes();
        builder.route("pathRoute2",r->r.path("/sports")
                .uri("http://news.baidu.com/sports")).build();
        return builder.build();
    }

}

启动访问:http://localhost:9527/guonei ,http://localhost:9527/sports
在这里插入图片描述

在这里插入图片描述

五、通过微服务名实现动态路由

默认情况下Gateway会根据注册中心注册的服务列表,
以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能
为了演示SpringCloud Gateway实现的动态路由,我们启用服务提供方集群
provider8001/8002微服务都启动
在这里插入图片描述

为了实现网关根据微服务名对服务进行动态路由,需要在9527网关配置文件中开启从注册中心动态创建路由的功能,修改如下配置:

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true  # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: paymentRouth  # paymentRouth    #路由的ID,没有固定规则但要求唯一,建议配合服务名
#          uri: http://localhost:8001          #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/get/**         # 断言,路径相匹配的进行路由

        - id: paymentRouth2  # paymentRouth2    #路由的ID,没有固定规则但要求唯一,建议配合服务名
#          uri: http://localhost:8001          #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/lb/**         # 断言,路径相匹配的进行路由

启动网关
测试访问:

在这里插入图片描述

六、Predicate的使用

1、Predicate是什么

启动gateway9527,查看日记:
在这里插入图片描述
RoutePredicateFactory(路由工程)
访问官网:查看4.Route Predicate Factories
在这里插入图片描述
翻译:
Spring Cloud Gateway将路由作为Spring WebFlux HandlerMapping基础架构的一部分进行匹配。
Spring Cloud Gateway包括许多内置的Route Predicate Factories(路由断言工厂)。所有这些Predicate 都与HTTP请求的不同属性匹配。多个Route Predicate 工厂可以进行组合。

Spring Cloud Gateway创建Route对象,使用 Route Predicate Factories 创建 Predicate 对象,Predicate 对象可以赋值给Route。Spring Cloud Gateway包含许多内置的Route Predicate Factories。

所有这些Predicate (断言)都匹配HTTP请求不同属性。多种Route Predicate Factories可以组合,并通过逻辑and。
在这里插入图片描述

2、常用的Route Predicate

①The After Route Predicate Factory

描述:当前请求在指定时间之后才匹配
在这里插入图片描述

predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]

After: 在什么时间后请求访问。
(注:2017-01-20T17:42:47.789-07:00[America/Denver] 是美国时间 这要转换为亚洲上海时间)

获取默认时区时间: ZonedDateTime zonedDateTime = ZonedDateTime.now();
修改网关9529服务的yml文件添加配置predicates.After:

predicates:
  - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
  - After=2021-02-28T14:50:18.083+08:00[Asia/Shanghai] # 亚洲 上海时区

启动9527网关服务:访问:http://localhost:9527/payment/lb
在这里插入图片描述

设置After参数大于当前时间:After=2021-02-28T15:50:18.083+08:00[Asia/Shanghai]
重启访问:
在这里插入图片描述

②The Before Route Predicate Factory

描述:当前请求在指定时间 之前 才匹配
在这里插入图片描述
Before:在什么时间之前请求访问

Before=2017-01-20T17:42:47.789-07:00[America/Denver]

③The Between Route Predicate Factory

描述:当前请求在指定时间 中间 才匹配
在这里插入图片描述
Between:在什么时间内请求访问。(用 , 隔开)

predicates:
  - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

④The Cookie Route Predicate Factory

描述:当前请求中的cookie值匹配配置的cookie参数值时生效
在这里插入图片描述
Cookie:请求带Cookie访问;

-Cookie=chocolate, ch.p
参数1:Cookie名称name
参数2: ch.p正则表达式
路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行

yml添加配置:

predicates:
  - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
  - Cookie=username,zzp

启动,使用 curl 命令发送请求:curl http://localhost:9527/payment/lb 不带Cookie
在这里插入图片描述
带上Cookie访问: curl http://localhost:9527/payment/lb --Cookie “username=zzp”
在这里插入图片描述

⑤The Header Route Predicate Factory

描述:当前请求中的header值匹配配置的header参数值时生效
在这里插入图片描述
Header: 请求具有名为X-Request-Id其值与\d+正则表达式匹配的标头(即,其值为一个或多个数字),则此路由匹配。

-Header=X-Request-Id, \d+

yml配置:

predicates:
  - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
  - Header=X-Request-Id, \d+  # 请求头要有 X-Request-Id属性并且值为整数的正则表达式

重启:请求: curl http://localhost:9527/payment/lb -H “X-Request-Id:123”

在这里插入图片描述

⑥The Host Route Predicate Factory

描述:匹配请求头中的Host的值
在这里插入图片描述
Host:请求的Host标头值为www.somehost.org或beta.somehost.org或,则此路由匹配www.anotherhost.org。
修改yml文件

predicates:
  - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
  - Host=**.zzp.com

重启访问: curl http://localhost:9527/payment/lb -H “Host: www.zzp.com”
在这里插入图片描述

⑦The Method Route Predicate Factory

描述:匹配请求头中的Method的值
在这里插入图片描述
Method:请求方法是GET或POST

Method=GET,POST

⑧The Path Route Predicate Factory

描述:匹配请求路径。
在这里插入图片描述
Path:这条路线,如果请求路径是,例如匹配/red/1或/red/blue或/blue/green。

Path=/red/{segment},/blue/{segment}

修改yml文件

predicates:
  - Path=/payment/get/{zzp}

重启访问:curl http://localhost:9527/payment/get/12
在这里插入图片描述

/payment/get/{zzp} 支持uri模版变量,zzp可以在GatewayFilter中获取,获取方式.

Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);

String zzp= uriVariables.get("zzp");

⑨The Query Route Predicate Factory

描述:匹配请求参数
在这里插入图片描述
Query:Query=green表示请求参数中必须存在 green这个请求参数
修改yml文件

predicates:
  - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
  - Query=123

重启请求:http://localhost:9527/payment/lb?123
在这里插入图片描述
在这里插入图片描述

描述:匹配请求参数(key=value)
在这里插入图片描述
Query:Query=red,gree. 表示请求参数中必须存在red这个参数,且它的值必须与gree.匹配(正则表达式),比如:green或者greet将匹配
修改yml文件

predicates:
  - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
  - Query=name,zzp.  # 参数name=zzp.(正则)

重启请求:http://localhost:9527/payment/lb?name=zzp1
在这里插入图片描述
错误:
在这里插入图片描述
在这里插入图片描述

⑩The RemoteAddr Route Predicate Factory

描述:匹配请求的ip地址,支持ipv4和ipv6
在这里插入图片描述
RemoteAddr:如果请求的远程地址为,则此路由匹配192.168.1.1 ,后方的/24是子网掩码

①①. The Weight Route Predicate Factory

描述:根据权重来分发请求,权重是根据group来计算的。
group 组,权重根据组来计算
weight 权重值,是一个 Int 的值
在这里插入图片描述
Weight:这条路线会将大约80%的流量转发到weighthigh.org,将大约20%的流量转发到weightlow.org

自己编写一个 route predicate factory

参看:在这里插入图片描述
其中一个路由工厂

请求头带token参数:
1、 编写一个类,实现RoutePredicateFactory接口,或继承AbstractRoutePredicateFactory
> 1、AbstractRoutePredicateFactory 中的 C 表示 配置文件类
> 2、重写shortcutFieldOrder此方法,表示的配置文件中参数的位置
> 3、重写==apply(C c)==方法,表示的是具体的业务逻辑

2、我们自己编写的类必须要以RoutePredicateFactory结尾,否则比较麻烦,参考
org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#initFactories 这个方法
代码:

package com.zzp.springcloud.config;


import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

/**
 * @author zzp
 * @create
 */
@Slf4j
@Component
public class TokenRoutePredicateFactory extends AbstractRoutePredicateFactory<TokenRoutePredicateFactory.Config> {

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

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("token");
    }

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

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

yml配置文件:

predicates:
  - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
  - Token=token

在这里插入图片描述
重启请求访问:http://localhost:9527/payment/lb 不带请求头
在这里插入图片描述

带请求头token:
在这里插入图片描述

七、Filter的使用

官网解释;
在这里插入图片描述
路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路由过滤器适用于特定路由进行使用。
Spring Cloud Gateway包括许多内置的GatewayFilter工厂。

Spring Cloud Gateway 的 Filter:
生命周期:
1、pre (业务逻辑之前)
2、post (业务逻辑之后)

种类:
1、GatewayFilter (单一)
在这里插入图片描述
具体的配置,可以查看官网给的实例进行配置测试

这里选择一个工厂,测试:
在这里插入图片描述

spring:
  cloud:
    gateway:
      routes:
      - id: rewritepath_route
        uri: https://example.org
        predicates:
        - Path=/red/**
        filters:
        - RewritePath=/red(?<segment>/?.*), $\{segment}

RewritePath:
描述:根据正则表达式,执行路径重写
参数
1、regexp:匹配的正则表达式
2、replacement:需要替换成的字符串
注意:
1、在yml配置中 $ 需要写成 $
2、路径替换规则是: path.replaceAll(regexp,replacement)
yml文件配置:

 routes:
   - id: paymentRouth  # paymentRouth    #路由的ID,没有固定规则但要求唯一,建议配合服务名
     uri: lb://cloud-payment-service #匹配后提供服务的路由地址
     predicates:
       - Path=/zzp/payment/get/**         # 断言,路径相匹配的进行路由
     filters:
       - RewritePath=/zzp/(?<segment>.*), /$\{segment}

页面上访问 /zzp/payment/get/** ⇒ 到达下游服务的路径是 /payment/get/**

启动测试:http://localhost:9527/zzp/payment/get/6
在这里插入图片描述

2、GlobalFilter (全局)
在这里插入图片描述

自定义过滤器

自定义过滤器GlobalFilter
自定义配置类要实现 GlobalFilter, Ordered

@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("*********全局过滤器:时间" + new Date());
        //获得请求参数username属性
        String uname = exchange.getRequest().getQueryParams().getFirst("username");
        //如果不包含该属性,则过滤器对请求进行拦截
        if (uname == null) {
            log.info("****************用户名为null,错误");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    /**
     * 加载过滤器的顺序 数字越小 优先级越高
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

启动网关9537
请求:http://localhost:9527/payment/lb?username=123
在这里插入图片描述
错误请求:
在这里插入图片描述
或者
在这里插入图片描述
日记:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值