这篇SpringCloud GateWay 详解,你用的到

laomugua
发布于 2023-6-30 15:00
浏览
0收藏

在微服务架构中,通常一个系统会被拆分为多个微服务,面对这么多微服务客户端应该如何去调用呢?如果没有其他更优方法,我们只能记录每个微服务对应的地址,分别去调用,但是这样会有很多的问题和潜在因素。

  1. 客户端多次请求不同的微服务,会增加客户端代码和配置的复杂性,维护成本比价高。
  2. 认证复杂,每个微服务可能存在不同的认证方式,客户端去调用,要去适配不同的认证,
  3. 存在跨域的请求,调用链有一定的相对复杂性(防火墙 / 浏览器不友好的协议)。
  4. 难以重构,随着项目的迭代,可能需要重新划分微服务

为了解决上面的问题,微服务引入了 网关 的概念,网关为微服务架构的系统提供简单、有效且统一的API路由管理,作为系统的统一入口,提供内部服务的路由中转,给客户端提供统一的服务,可以实现一些和业务没有耦合的公用逻辑,主要功能包含认证、鉴权、路由转发、安全策略、防刷、流量控制、监控日志等。

网关在微服务中的位置:

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

网关对比

  • Zuul 1.0: Netflix开源的网关,使用Java开发,基于Servlet架构构建,便于二次开发。因为基于Servlet内部延迟严重,并发场景不友好,一个线程只能处理一次连接请求。
  • Zuul 2.0: 采用Netty实现异步非阻塞编程模型,一个CPU一个线程,能够处理所有的请求和响应,请求响应的生命周期通过事件和回调进行处理,减少线程数量,开销较小

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

  • GateWay: 是Spring Cloud的一个全新的API网关项目,替换Zuul开发的网关服务,基于Spring5.0 + SpringBoot2.0 + WebFlux(基于⾼性能的Reactor模式响应式通信框架Netty,异步⾮阻塞模型)等技术开发,性能高于Zuul
  • Nginx+lua: 性能要比上面的强很多,使用Nginx的反向代码和负载均衡实现对API服务器的负载均衡以及高可用,lua作为一款脚本语言,可以编写一些简单的逻辑,但是无法嵌入到微服务架构中
  • Kong: 基于OpenResty(Nginx + Lua模块)编写的高可用、易扩展的,性能高效且稳定,支持多个可用插件(限流、鉴权)等,开箱即可用,只支持HTTP协议,且二次开发扩展难,缺乏更易用的管理和配置方式

GateWay

官方文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-starter

Spring Cloud Gateway 是Spring Cloud的一个全新的API网关项目,目的是为了替换掉Zuul1,它基于Spring5.0 + SpringBoot2.0 + WebFlux(基于⾼性能的Reactor模式响应式通信框架Netty,异步⾮阻塞模型)等技术开发,性能⾼于Zuul,官⽅测试,Spring Cloud GateWay是Zuul的1.6倍 ,旨在为微服务架构提供⼀种简单有效的统⼀的API路由管理⽅式。

  1. 可以与Spring Cloud Discovery Client(如Eureka)、Ribbon、Hystrix等组件配合使用,实现路由转发、负载均衡、熔断、鉴权、路径重写、⽇志监控等
  2. Gateway还内置了限流过滤器,实现了限流的功能。
  3. 设计优雅,容易拓展

基本概念

路由(Route)是GateWay中最基本的组件之一,表示一个具体的路由信息载体,主要由下面几个部分组成:

  1. id:路由唯一标识,区别于其他的route
  2. url:路由指向的目的地URL,客户端请求最终被转发到的微服务
  3. order:用于多个Route之间的排序,数值越小越靠前,匹配优先级越高
  4. predicate:断言的作用是进行条件判断,只有断言为true,才执行路由
  5. filter: 过滤器用于修改请求和响应信息

核心流程

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

核心概念:

  1. ​Gateway Client​​​ 向​​Spring Cloud Gateway​​ 发送请求
  2. 请求首先会被​​HttpWebHandlerAdapter​​ 进行提取组装成网关上下文
  3. 然后网关的上下文会传递到​​DispatcherHandler​​​ ,它负责将请求分发给​​RoutePredicateHandlerMapping​
  4. ​RoutePredicateHandlerMapping​​ 负责路由查找,并根据路由断言判断路由是否可用
  5. 如果过断言成功,由​​ FilteringWebHandler​​ 创建过滤器链并调用
  6. 通过特定于请求的​​Fliter​​​ 链运行请求,​​Filter​​ 被虚线分隔的原因是Filter可以在发送代理请求之前(pre)和之后(post)运行逻辑
  7. 执行所有pre过滤器逻辑。然后进行代理请求。发出代理请求后,将运行“post”过滤器逻辑。
  8. 处理完毕之后将​​Response​​​ 返回到​​Gateway​​ 客户端

Filter过滤器:

  • Filter在pre类型的过滤器可以做参数效验、权限效验、流量监控、日志输出、协议转换等。
  • Filter在post类型的过滤器可以做响应内容、响应头的修改、日志输出、流量监控等

核心思想

当用户发出请求达到 ​​GateWay​​ 之后,会通过一些匹配条件,定位到真正的服务节点,并且在这个转发过程前后,进行一些细粒度的控制,其中 Predicate(断言) 是我们的匹配条件,Filter 是一个拦截器,有了这两点,再加上URL,就可以实现一个具体的路由,核心思想:路由转发+执行过滤器链

这个过程就好比考试,我们考试首先要找到对应的考场,我们需要知道考场的地址和名称(id和url),然后我们进入考场之前会有考官查看我们的准考证是否匹配(断言),如果匹配才会进入考场,我们进入考场之后,(路由之前)会进行身份的登记和考试的科目,填写考试信息,当我们考试完成之后(路由之后)会进行签字交卷,走出考场,这个就类似我们的过滤器

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

Route(路由) :构建网关的基础模块,由ID、目标URL、过滤器等组成

Predicate(断言) 

Filter(过滤) 

框架搭建

通过上述讲解已经了解了基础概念,我们来动手搭建一个​​GateWay​​​项目,来看看它到底是如何运行的 新建项目:​​cloud-alibaba-gateway-9006​

版本对应:

GateWay属于SprinigCloud且有web依赖,在我们导入对应依赖时,要注意版本关系,我们这里使用的版本是 2.2.x的版本,所以配合使用的​​Hoxton.SR5​​版本

在这里我们要注意的是引入GateWay一定要删除spring-boot-starter-web依赖,否则会有冲突无法启动

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

父类pom引用:

<spring-cloud-gateway-varsion>Hoxton.SR5</spring-cloud-gateway-varsion>

 <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-dependencies</artifactId>
    <version>${spring-cloud-gateway-varsion}</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

子类POM引用:

<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
        <version>2.2.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

yml配置

server:
  port: 9006
spring:
  application:
    name: cloud-gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          enabled: false #开启注册中心路由功能
      routes:  # 路由
        - id: nacos-provider #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
          uri: http://localhost:9001/nacos-provider # 匹配提供服务的路由地址 lb://表示开启负载均衡
          predicates: # 断言
            - Path=/mxn/** # 断言,路径相匹配进行路由

我们在之前的​​cloud-alibaba-nacos-9001​​项目中添加下面测试代码

@RestController
@RequestMapping("/mxn")
public class DemoController {

    @Value("${server.port}")
    private String serverPort;

    @GetMapping(value = "/hello")
    public String hello(){
        return "hello world ,my port is :"+serverPort;
    }

 }   

启动Nacos、​​cloud-alibaba-nacos-9001​​​、​​cloud-alibaba-gateway-9006​​通过gateway网关去访问9001的mxn/order看看。

首先我们在Nacos中看到我们服务是注册到Nacos中了

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

然后我们访问​http://localhost:9001/mxn/hello​,确保是成功的,再通过​http://localhost:9006/mxn/hello​去访问,也是OK,说明我们GateWay搭建成功,我们进入下一步

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

在上述方法中我们是通过YML去完成的配置,​​GateWay​​​还提供了另外一种配置方式,就是通过代码的方式进行配置,​​@Bean​​​ 注入一个 ​​RouteLocator​

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;

@Configuration
public class GateWayConfig {

      /*
    配置了一个id为path_mxn的路由规则
    当访问地址http://localhost:9999/mxn/**
    就会转发到http://localhost:9001/nacos-provider/mxn/任何地址
     */
    @Bean
    public RouteLocator gateWayConfigInfo(RouteLocatorBuilder routeLocatorBuilder){
        // 构建多个路由routes
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        // 具体路由地址
        routes.route("path_mxn",r -> r.path("/mxn/**").uri("http://localhost:9001/nacos-provider")).build();
        // 返回所有路由规则
        return routes.build();
    }
}


我们可以将路由注释掉之后看一下,重启9006服务,访问地址​​http://localhost:9006/mxn/hello​​ 就可以转发到9001中具体的接口中

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

这里并不推荐,使用代码的方式来进行配置​​gateWay​​,大家有个了解就可以,因为代码的配置维护的成本比较高,而且对于一些需要修改的项,需要改代码才可以完成,这样不利于维护和拓展,所以还是推荐大家使用yml进行配置。

GateWay负载均衡

在上述的讲解中,我们已经掌握了 ​​GateWay​​​ 的一些基本配置和两种使用方式,下面我们就来讲解一下 ​​GateWay​​ 如何实现负载均衡

我们只需要在9006中添加​​lb://nacos-provider​​就可以显示负载均衡。

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

当我们去访问​http://localhost:9006/mxn/hello​的时候,就可以看到9001和9002不停的切换

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

Predicate 断言

在这一篇中我们来研究一下 断言 ,我们可以理解为:当满足条件后才会进行转发路由,如果是多个,那么多个条件需要同时满足

在官方提供的断言种类有11种(最新的有12种类型):

具体地址:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

  1. After:匹配在指定日期时间之后发生的请求。
  2. Before:匹配在指定日期之前发生的请求。
  3. Between:需要指定两个日期参数,设定一个时间区间,匹配此时间区间内的请求。
  4. Cookie:需要指定两个参数,分别为name和regexp(正则表达式),也可以理解Key和Value,匹配具有给定名称且其值与正则表达式匹配的Cookie。
  5. Header:需要两个参数header和regexp(正则表达式),也可以理解为Key和Value,匹配请求携带信息。
  6. Host:匹配当前请求是否来自于设置的主机。
  7. Method:可以设置一个或多个参数,匹配HTTP请求,比如GET、POST
  8. Path:匹配指定路径下的请求,可以是多个用逗号分隔
  9. Query:需要指定一个或者多个参数,一个必须参数和一个可选的正则表达式,匹配请求中是否包含第一个参数,如果有两个参数,则匹配请求中第一个参数的值是否符合正则表达式。
  10. RemoteAddr:匹配指定IP或IP段,符合条件转发。
  11. Weight:需要两个参数group和weight(int),实现了路由权重功能,按照路由权重选择同一个分组中的路由

1. After :表示配置时间之后才进行转发

时间戳获取代码,用于时间代码的获取:

public static void main(String[] args){
        ZonedDateTime zbj = ZonedDateTime.now();//默认时区
        System.out.println(zbj);
    }

spring:
  application:
    name: cloud-gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          enabled: true #开启注册中心路由功能
      routes:  # 路由
        - id: nacos-provider #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
          uri: lb://nacos-provider # 匹配提供服务的路由地址 lb://表示开启负载均衡
          predicates: # 断言
            - Path=/mxn/** # 断言,路径相匹配进行路由
            - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在这个时间之后的请求够可以进行通过,之前的则不能进行访问


如果在时间段之前访问则404

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

Before

匹配​​ZonedDateTime​​类型的时间,表示匹配在指定日期时间之前的请求,之后的请求则拒绝404错误

predicates: # 断言
  - Path=/mxn/** # 断言,路径相匹配进行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在这个时间之后的请求够可以进行通过,之前的则不能进行访问
  - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]

Between

​Between​​​ 可以匹配​​ZonedDateTime​​​类型的时间,由两个​​ZonedDateTime​​参数组成,第一个参数为开始时间,第二参数为结束时间,逗号进行分隔,匹配在指定的开始时间与结束时间之内的请求,配置如下:

predicates: # 断言
  - Path=/mxn/** # 断言,路径相匹配进行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在这个时间之后的请求够可以进行通过,之前的则不能进行访问
#  - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
  - Between=2022-06-11T15:30:40.785+08:00[Asia/Shanghai],2022-06-11T16:30:40.785+08:00[Asia/Shanghai]

Cookie

由两个参数组成,分别为​​name(Key)​​​和​​regexp(正则表达式)(Value​​),匹配具有给定名称且其值与正则表达式匹配的Cookie。

路由规则会通过获取Cookie name值和正则表达式去匹配,如果匹配上就会执行路由,如果匹配不上则不执行。

predicates: # 断言
  - Path=/mxn/** # 断言,路径相匹配进行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在这个时间之后的请求够可以进行通过,之前的则不能进行访问
#  - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
#  - Between=2022-06-11T15:30:40.785+08:00[Asia/Shanghai],2022-06-11T16:30:40.785+08:00[Asia/Shanghai]
   - Cookie=muxiaonong,[a-z]+ # 匹配Cookie的key和value(正则表达式)表示任意字母

小写字母匹配成功:

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

数字匹配不成功:

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

Header

由两个参数组成,第一个参数为​​Header名称​​​,第二参数为​​Header的Value值​​,指定名称的其值和正则表达式相匹配的Header的请求

predicates: # 断言
  - Path=/mxn/** # 断言,路径相匹配进行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在这个时间之后的请求够可以进行通过,之前的则不能进行访问
#  - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
#  - Between=2022-06-11T15:30:40.785+08:00[Asia/Shanghai],2022-06-11T16:30:40.785+08:00[Asia/Shanghai]
#  - Cookie=muxiaonong,[a-z]+ # 匹配Cookie的key和value(正则表达式)表示任意字母
  - Header=headerName, \d+ # \d表示数字

请求头携带数字断言请求成功,

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

断言字母匹配失败:

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

Host

匹配当前请求是否来自于设置的主机。

predicates: # 断言
  - Path=/mxn/** # 断言,路径相匹配进行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在这个时间之后的请求够可以进行通过,之前的则不能进行访问
#  - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
#  - Between=2022-06-11T15:30:40.785+08:00[Asia/Shanghai],2022-06-11T16:30:40.785+08:00[Asia/Shanghai]
#  - Cookie=muxiaonong,[a-z]+ # 匹配Cookie的key和value(正则表达式)表示任意字母
#  - Header=headerName, \d+ # \d表示数字
  - Host=**.muxiaonong.com #匹配当前的主机地址发出的请求

满足Host断言,请求成功

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

不满足Host断言失败

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

Method 

可以设置一个或多个参数,匹配HTTP请求,比如​​POST,PUT,GET,DELETE​

predicates: # 断言
  - Path=/mxn/** # 断言,路径相匹配进行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在这个时间之后的请求够可以进行通过,之前的则不能进行访问
#  - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
#  - Between=2022-06-11T15:30:40.785+08:00[Asia/Shanghai],2022-06-11T16:30:40.785+08:00[Asia/Shanghai]
#  - Cookie=muxiaonong,[a-z]+ # 匹配Cookie的key和value(正则表达式)表示任意字母
#  - Header=headerName, \d+ # \d表示数字
#  - Host=**.muxiaonong.com #匹配当前的主机地址发出的请求
  - Method=POST,GET

GET断言成功

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

PUT断言请求失败

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

Query

由两个参数组成,第一个为参数名称(必须),第二个为参数值(可选-正则表达式),匹配请求中是否包含第一个参数,如果有两个参数,则匹配请求中第一个参数的值是否符合第二个正则表达式。

predicates: # 断言
  - Path=/mxn/** # 断言,路径相匹配进行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在这个时间之后的请求够可以进行通过,之前的则不能进行访问
#  - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
#  - Between=2022-06-11T15:30:40.785+08:00[Asia/Shanghai],2022-06-11T16:30:40.785+08:00[Asia/Shanghai]
#  - Cookie=muxiaonong,[a-z]+ # 匹配Cookie的key和value(正则表达式)表示任意字母
#  - Header=headerName, \d+ # \d表示数字
#  - Host=**.muxiaonong.com #匹配当前的主机地址发出的请求
#  - Method=POST,GET
  - Query=id,.+ # 匹配任意请求参数,这里如果需要匹配多个参数,可以写多个- Query=

断言匹配 请求成功

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

RemoteAddr

参数由CIDR 表示法(IPv4 或 IPv6)字符串组成,也就是匹配的ID地址,配置如下:

predicates: # 断言
  - Path=/mxn/** # 断言,路径相匹配进行路由
# - After=2022-06-11T16:30:40.785+08:00[Asia/Shanghai] #在这个时间之后的请求够可以进行通过,之前的则不能进行访问
#  - Before=2022-06-11T15:30:40.785+08:00[Asia/Shanghai]
#  - Between=2022-06-11T15:30:40.785+08:00[Asia/Shanghai],2022-06-11T16:30:40.785+08:00[Asia/Shanghai]
#  - Cookie=muxiaonong,[a-z]+ # 匹配Cookie的key和value(正则表达式)表示任意字母
#  - Header=headerName, \d+ # \d表示数字
#  - Host=**.muxiaonong.com #匹配当前的主机地址发出的请求
#  - Method=POST,GET
#  - Query=id,.+ # 匹配任意请求参数,这里如果需要匹配多个参数,可以写多个Query
  - RemoteAddr=192.168.1.1/24

RemoteAddr

需要两个参数group和weight(int)权重数值,实现了路由权重功能,表示将相同的请求根据权重跳转到不同的uri地址,要求group的名称必须一致

routes:  # 路由
  - id: weight_high #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
    uri: https://blog.csdn.net/qq_14996421
    predicates: # 断言
      - Weight=groupName,8
  - id: weight_low #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
    uri: https://juejin.cn/user/2700056290405815
    predicates: # 断言
      - Weight=groupName,2

直接访问​​http://localhost:9006/​​可以看到我们请求的地址成8/2比例交替显示, 80% 的流量转发到https://blog.csdn.net/qq_14996421,将约 20% 的流量转发到https://juejin.cn/user/2700056290405815

Predicate就是为了实现一组匹配规则,让请求过来找到对应的Route进行处理。如果有多个断言则全部命中后进行处理

GateWay Filter

路由过滤器允许修改传入的HTTP请求或者返回的HTTP响应,路由过滤器的范围是特定的路由.

Spring Cloud GateWay 内置的Filter生命周期有两种:pre(业务逻辑之前)、post(业务逻辑之后)

GateWay本身自带的Filter分为两种:GateWayFilter(单一)、GlobalFilter(全局)

GateWay Filter提供了丰富的过滤器的使用,单一的有32种,全局的有9种,有兴趣的小伙伴可以了解一下。

官方参考网址:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#global-filters

StripPrefix

StripPrefix 在我们当前请求中,通过规则值去掉某一部分地址,比如我们有一台服务中加入了一个前端​​nacos-provider​​​想要通过这个去访问,我们在项目​​cloud-alibaba-nacos-9001​​​中加入 ​​context-path​

server:
  port: 9001
  servlet:
    context-path: /nacos-provider

现在9001的访问路径变为​​http://localhost:9001/nacos-provider/mxn/hello​​​,但是如果我们通过网关去访问路径就会变成​​http://localhost:9006/mxn/nacos-provider/mxn/hello​​​ 这个时候我们通过这个路径去访问是访问不成功的,想要解决这个方法,这个就用到了我们​​FIlter​​​ 中的 ​​StripPrefix​

routes:  # 路由
  - id: nacos-provider #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
    uri: lb://nacos-provider
    predicates: # 断言
      - Path=/mxn/** # 匹配对应地址
    filters:
      - StripPrefix=1 # 去掉地址中的第一部分

我们重新启动9006项目,再去访问

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

自定义Filter

虽然Gateway给我们提供了丰富的内置Filter,但是实际项目中,自定义Filter的场景非常常见,因此单独介绍下自定义FIlter的使用。

想要实现GateWay自定义过滤器,那么我们需要实现GatewayFilter接口和Ordered接口

@Slf4j
@Component
public class MyFilter implements Ordered, GlobalFilter {
    /**
     *     @param exchange 可以拿到对应的request和response
     *     @param chain 过滤器链
     *     @return 是否放行
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){
        //获取第一个参数
        String id = exchange.getRequest().getQueryParams().getFirst("id");
        //打印当前时间
        log.info("MyFilter 当前请求时间为:"+new Date());
        //判断用户是否存在
        if(StringUtils.isEmpty(id)){
            log.info("用户名不存在,非法请求!");
            //如果username为空,返回状态码为407,需要代理身份验证
            exchange.getResponse().setStatusCode(HttpStatus.PROXY_AUTHENTICATION_REQUIRED);
            // 后置过滤器
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    /**
     * 设定过滤器的优先级,值越小则优先级越高
     *     @return
     */
    @Override
    public int getOrder(){
        return 0;
    }
}

当我们访问​​http://localhost:9006/mxn/nacos-provider/mxn/hello​​请求,没有携带ID参数,请求失败

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

当我们访问​http://localhost:9006/mxn/nacos-provider/mxn/hello?id=1​请求,请求成功

这篇SpringCloud GateWay 详解,你用的到-鸿蒙开发者社区

总结

到这里我们的​​GateWay​​​就讲解完了,对于GateWay的核心点主要有三个​​Route\Predicate\Filter​​​,我们搞懂了这三点,基本上对于​​GateWay​​的知识就掌握的差不多了,GateWay核心的流程就是:路由转发+执行过滤器链,如果对文中有疑问的小伙伴,欢迎留言讨论。

创作不易,如果文中对你有帮助,记得点赞关注,您的支持是我创作的最大动力。


文章转载自公众号:牧小农

分类
已于2023-6-30 15:00:45修改
收藏
回复
举报
回复
    相关推荐