相关推荐recommended
【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器
作者:mmseoamin日期:2024-01-19

这篇文章,主要介绍微服务组件之Gateway实现动态路由、配置路由映射规则、路由过滤器

目录

一、动态路由配置

1.1、动态URI路由配置

(1)引入eureka客户端依赖

(2)添加路由配置

1.2、服务名称转发配置

二、断言配置规则

2.1、路由断言工厂类

2.2、Path路径匹配

2.3、Query请求参数匹配

2.4、Method请求方式匹配

2.5、RemoteAddr远程地址匹配

2.6、Header请求头匹配

三、路由过滤器

3.1、Path路径过滤器

(1)RewritePath重写路径

(2)PrefixPath路径前缀

(3)StripPrefix分隔前缀

(4)SetPath路径参数

3.2、Parameter参数过滤器

3.3、Status状态过滤器

3.4、自定义网关过滤器

(1)实现GatewayFilter接口

(2)配置自定义过滤器

3.5、自定义全局过滤器

(1)实现GlobalFilter接口


一、动态路由配置

1.1、动态URI路由配置

前一篇文章介绍了Gateway服务网关的基础环境搭建,在基础环境中,我们的路由地址uri是直接在application.yml配置文件中写死的,这种方式不太灵活,因为一旦微服务的IP和端口改变,此时就需要修改Gateway工程中的配置文件,然后重新启动网关工程。为了解决能够让路由不依赖于具体的IP和端口,这里就需要实现一个动态路由的功能。

动态路由,借助于eureka注册中心就能够实现,在Gateway工程中引入eureka-client客户端依赖,从注册中心获取微服务可用列表,根据微服务名称实现路由的配置。

(1)引入eureka客户端依赖



    org.springframework.cloud
    spring-cloud-starter-gateway



    org.springframework.cloud
    spring-cloud-starter-netflix-eureka-client

(2)添加路由配置

  • 动态路由配置中,必须使用【lb://微服务名称】这种格式,【lb】是LoadBalanced的缩写,表示负载均衡。
  • 动态路由本质上就是根据配置的微服务名称,去注册中心获取到对应微服务的IP地址和Port端口。
    server:
      port: 9999
    spring:
      application:
        name: gateway-eureka-server
      # 配置 gateway 路由信息
      cloud:
        gateway:
          # 指定路由信息
          routes:
            - id: consumer-client # 路由唯一标识,一般和微服务应用名称相同即可
              # 目标路由的服务名称,这里采用的是动态路由,格式必须是:【lb://微服务名称】
              uri: lb://consumer-client
              # 配置断言,也就是请求的URI满足哪些规则,才可以匹配当前这个routes路由信息
              predicates:
                # 这里使用路由断言,所有 /api/consumer 开头的请求,都将转发到 http://localhost:8081/ 这个服务上面
                - Path=/api/consumer/**
    # eureka 配置
    eureka:
      instance:
        prefer-ip-address: true # 开启采用 IP 注册形式
        # ${spring.cloud.client.ip-address} 这个属性可以获取到当前机器的 IP 地址
        instance-id: ${spring.cloud.client.ip-address}:${server.port} # 设置当前服务的实例ID,采用:IP+端口形式
      client:
        # 从 eureka 服务端获取注册信息
        fetch-registry: true
        # 将自身注册到 eureka 服务端
        register-with-eureka: true
        service-url:
          # eureka 服务端地址
          defaultZone: http://localhost:8761/eureka/

    到这里,动态URI路由就配置成功啦。

    1.2、服务名称转发配置

    第一种动态路由的配置方式中,每次新增一个微服务应用都需要在Gateway工程的配置文件里面,新增一个路由配置信息,这样也太麻烦了,Gateway还提供了一种动态路由方式,叫做:服务名称转发。这种动态路由的方式是将eureka注册中心中的微服务名称作为请求URI的前缀,然后客户端访问的时候,需要在对应的请求接口地址中带上微服务名称,Gateway通过微服务名称就可以实现服务的转发功能。

    spring:
      application:
        name: gateway-eureka-server
      # 配置 gateway 路由信息
      cloud:
        gateway:
          # 动态服务转发
          discovery:
            locator:
              enabled: true # 启用动态路由服务名称转发功能
              lower-case-service-id: true # 开启服务名称小写

    采用上面这种动态路由配置方式,在访问的时候,就需要指定微服务名称,例如:【http://localhost:9999/consumer-client/api/consumer/getUserInfo?username=csdn2023】,这里访问的时候,就是需要指定访问的是【consumer-client】这个微服务应用,然后Gateway就可以根据这个微服务名称将这个请求转发到这个应用程序里面。

    二、断言配置规则

    2.1、路由断言工厂类

    Gateway支持多种断言方式,也就是支持多种路由配置规则,断言是采用工厂模式创建的,这个工厂接口是RoutePredicateFactory,这个有很多个实现类,每一个实现类就是一种路由配置规则,常见的有下面这些:

    【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器,第1张

    使用最多的应该是Path路径匹配。

    2.2、Path路径匹配

    Path是根据请求的URI进行规则匹配,路径匹配支持正则表达式,配置规则如下所示:

    【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器,第2张

    2.3、Query请求参数匹配

    Gateway可以根据请求URI中的参数来进行规则匹配,这种方式叫做:Query。Query参数匹配的格式:

    • Query=参数名称1,参数名称2,...(多个参数采用逗号分隔)。
    • 这种匹配模式下,如果请求的URI中包含对应的参数(只要包含其中一个参数,就可以匹配成功),就会满足匹配规则。
    • 注意:需要注意的是,这种只能够对URI中的请求参数生效。
    • Query模式也支持正则表达式。

      【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器,第3张

      2.4、Method请求方式匹配

      Method是根据HTTP接口的请求方式来进行匹配。

      【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器,第4张

      Method匹配规则中,如果访问的接口地址不满足Gateway的匹配规则,则会报错404;如果是满足Gateway匹配规则,但是服务提供者这不满足调用方式,此时会报错405(表示请求方式不正确)。

      2.5、RemoteAddr远程地址匹配

      RemoteAddr是指定哪些IP地址可以访问Gateway网关,也就是说,Gateway会匹配对应的IP地址来判断是否满足规则。

      【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器,第5张

      2.6、Header请求头匹配

      Header规则是根据请求中,是否包含指定的Header请求头字段,并且还可以设置请求字段的值是否满足规则,例如:【\d+】表示数字。

      【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器,第6张

      三、路由过滤器

      Gateway中提供了两种类型的过滤器,分别是:Gateway Filter网关过滤器和Global Filter全局过滤器。GatewayFilter网关过滤器需要在application.yml配置文件中,使用【spring.cloud.gateway.routes.filters】属性进行配置;GlobalFilter全局过滤器不需要在配置文件中设置,它是作用于所有的路由上面。

      3.1、Path路径过滤器

      Path路径过滤器可以对请求的URI路径进行一些操作,例如:重写路径。

      (1)RewritePath重写路径

      路径重写可以将客户端的请求URI重新转换成另外一个请求URI,例如:将【/api-gateway/api/consumer/demo】路径重写成【/api/consumer/demo】路径,Gateway将采用重写之后的请求,去调用下游系统,从而实现接口的调用。

      【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器,第7张

      (2)PrefixPath路径前缀

      PrefixPath是路径前缀过滤器,这个过滤器可以为请求添加URI前缀,例如:当我们请求【/consumer/demo】接口的时候,并且设置PrefixPath等于【/api】,那么这个过滤器最终形成的请求将是【/api/consumer/demo】,Gateway会通过【/api/consumer/demo】调用下游系统的接口。

      【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器,第8张

      (3)StripPrefix分隔前缀

      StripPrefix是一个用于分隔路径的过滤器,它会根据【/】斜杠将请求分隔成一个数组,StripPrefix的参数值就是将前面几个元素删除,只保留剩余的路径。例如:请求【/api/api/api/consumer/demo】接口,设置【StripPrefix=2】,表示将接口前两个路径分割掉,最终得到的路径是【/api/consumer/demo】。

      【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器,第9张

      (4)SetPath路径参数

      SetPath用于路径参数的一个过滤器,它可以将URI路径中的路径参数采用map保存起来,然后在过滤器中可以通过【{segment}】获取出来。

      【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器,第10张

      3.2、Parameter参数过滤器

      Parameter参数过滤器,可以对网关接收到的请求添加、删除一些参数信息。

      【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器,第11张

      3.3、Status状态过滤器

      Status状态过滤器,是用于设置接口响应状态码的一个过滤器。正常情况下,接口调用成功之后,都是返回200的状态码,我们可以通过Status过滤器,修改返回的状态码。

      【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器,第12张

      3.4、自定义网关过滤器

      自定义网关过滤器,只需要编写一个类实现【GatewayFilter】接口,重写其中的方法即可。

      (1)实现GatewayFilter接口

      package com.gitee.demo.filter;
      import org.springframework.cloud.gateway.filter.GatewayFilter;
      import org.springframework.cloud.gateway.filter.GatewayFilterChain;
      import org.springframework.core.Ordered;
      import org.springframework.web.server.ServerWebExchange;
      import reactor.core.publisher.Mono;
      /**
       * @version 1.0.0
       * @Date: 2023/4/19 21:12
       * @Copyright (C) ZhuYouBin
       * @Description: 自定义网关过滤器
       */
      public class CustomGatewayFilter implements GatewayFilter, Ordered {
          
          @Override
          public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
              System.out.println("执行自定义GatewayFilter网关过滤器......");
              return chain.filter(exchange);
          }
          @Override
          public int getOrder() {
              return 0;
          }
      }
      

      (2)配置自定义过滤器

      这里通过配置类的形式将我们自定义的网关过滤器加入到Gateway里面。

      package com.gitee.demo.config;
      import com.gitee.demo.filter.CustomGatewayFilter;
      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;
      /**
       * @version 1.0.0
       * @Date: 2023/4/19 21:15
       * @Copyright (C) ZhuYouBin
       * @Description: Gateway 网关路由配置类
       */
      @Configuration
      public class GatewayRouteConfig {
          
          @Bean
          public RouteLocator routeLocator(RouteLocatorBuilder builder) {
              // 要按照顺序调用
              return builder.routes().route(r -> r
                      .path("/**")
                      .uri("lb://consumer-client")
                      .filters(new CustomGatewayFilter())
                      .id("consumer-client")).build();
          }
          
      }
      

      启动工程,访问接口,查看控制台输出日志。

      【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器,第13张

      3.5、自定义全局过滤器

      Gateway已经给我们提供了一些全局过滤器,不需要配置,因为这些默认的过滤器都是全局生效的,但是Gateway也允许我们自定义全局过滤器,通过自定义全局过滤器,可以实现一些功能,例如:统一鉴权、访问限流。

      (1)实现GlobalFilter接口

      package com.gitee.demo.filter;
      import org.springframework.cloud.gateway.filter.GatewayFilterChain;
      import org.springframework.cloud.gateway.filter.GlobalFilter;
      import org.springframework.core.Ordered;
      import org.springframework.stereotype.Component;
      import org.springframework.web.server.ServerWebExchange;
      import reactor.core.publisher.Mono;
      /**
       * @version 1.0.0
       * @Date: 2023/4/19 21:24
       * @Copyright (C) ZhuYouBin
       * @Description: 全局过滤器
       */
      // 这里通过注解将其注入 IOC 容器里面即可
      @Component
      public class CustomGlobalFilter implements GlobalFilter, Ordered {
          @Override
          public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
              System.out.println("执行全局过滤器......");
              return chain.filter(exchange);
          }
          @Override
          public int getOrder() {
              return 0;
          }
      }
      

      启动工程,访问任意接口,此时都会执行全局过滤器。

      【微服务笔记17】微服务组件之Gateway实现动态路由、配置路由规则、路由过滤器,第14张

      到此,Gateway动态路由、配置路由规则就介绍完啦。

      综上,这篇文章结束了,主要介绍微服务组件之Gateway实现动态路由、配置路由映射规则、路由过滤器。