• Gateway-02-gateway路由规则和过滤器


    1:gateway的Helloworld程序

    1:设置order服务(普通服务)

    application.yml

    server:
      port: 19092
    
    spring:
      application:
        name: gateway-order
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    在这里插入图片描述

    2:设置user服务(普通服务)

    application.yml

    server:
      port: 19091
    
    
    spring:
      application:
        name: gateway-user
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

    3:设置gateway-server服务

    1:导包

    		<dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-gatewayartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4

    2:配置application.yml

    server:
      port: 19090
    
    
    spring:
      application:
        name: gateway-server
      cloud:
        gateway:
          routes: #路由规则定义
            - id: gataway-user #路由ID,必须唯一
              uri: http://localhost:19091/ #路由地址,后续也可更改成其他的类型,诸如指向微服务
              predicates: # 断言规则,既满足此断言既按照此路由规则跳转
                - Path=/user/**
            - id: gateway-order
              uri: http://localhost:19092/
              predicates:
                - Path=/order/**
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4:测试

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

    2:Gateway路由规则

    1:路由断言工厂

    Spring Cloud Gateway将路由作为Spring WebFlux HandlerMapping 基础架构的一部分进行匹
    配。Spring Cloud Gateway包括许多内置的路由断言工厂。所有这些断言都与HTTP请求的不同属性匹
    配。您可以将多个路由断言工厂与逻辑 and 语句结合使用。
    路由断言工厂RoutePredicateFactory包含的主要实现类如图所示,包含Datetime、Cookie、
    Header、Host、Method、Path、Query、RemoteAddr、Weight等类型的路由断言。
    在这里插入图片描述

    2:日期时间路由匹配规则

    1:匹配指定日期之前后的请求After

    spring:
    application:
     name: gateway-server
    cloud:
     gateway:
      routes:
       - id: after_route
        uri: http://localhost:8080/
        predicates:
        - After=2021-04-20T06:06:06+08:00[Asia/Shanghai]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2:匹配指定日期时间之前的请求 Before

    spring:
    application:
     name: gateway-server
    cloud:
     gateway:
      routes:
       - id: before_route
        uri: http://localhost:8080/
        predicates:
        - Before=2021-04-20T06:06:06+08:00[Asia/Shanghai]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3:匹配指定日期时间之间的请求 Between

    spring:
    application:
     name: gateway-server
    cloud:
     gateway:
      routes:
       - id: betwwen_route
        uri: http://localhost:8080/
        predicates:
        - Between=2021-01-20T06:06:06+08:00[Asia/Shanghai],2021-04-
    20T06:06:06+08:00[Asia/Shanghai]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3:Cookie路由匹配规则

    所述Cookie路由断言工厂采用两个参数,该cookiename和regexp(其是Java正则表达式)。该断言匹
    配具有给定名称且其值与正则表达式匹配的cookie。以下示例配置cookie路由断言工厂:

    spring:
    application:
     name: gateway-server
    cloud:
     gateway:
      routes:
       - id: cookie_route
        uri: http://localhost:8080/
        predicates:
        - Cookie=token, \d+
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4:Header路由匹配规则

    所述 Header ;路由断言工厂采用两个参数,报头 name 和一个 regexp (其是Java正则表达式)。该断
    言与具有给定名称的头信息匹配,该标头的值与正则表达式匹配。以下示例配置Header路由断言:

    spring:
    application:
     name: gateway-server
    cloud:
     gateway:
      routes:
       - id: header_route
        uri: http://localhost:8080/
        predicates:
        - Header=X-Request-Id, \d+
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5:Host路由匹配规则

    该 Host 路由断言工厂需要一个参数:主机名的列表 patterns 。该模式是带有.分隔符的Ant样式的模
    式。断言与 Host 匹配模式的标头匹配。以下示例配置主机路由断言:

    spring:
    application:
     name: gateway-server
    cloud:
     gateway:
      routes:
       - id: host_route
        uri: http://localhost:8080/
        predicates:
        - Host=**.somehost.org,**.anotherhost.org
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    6: Method路由匹配规则

    所述 Method 路由断言厂需要 methods 的参数,它是一个或多个参数:HTTP方法来匹配。以下示例配置方法路由断言:

    spring:
    application:
     name: gateway-server
    cloud:
     gateway:
      routes:
       - id: method_route
        uri: http://localhost:8080/
        predicates:
        - Method=GET,POST
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    7:Path路由匹配规则

    spring:
    application:
     name: gateway-server
    cloud:
     gateway:
      routes:
       - id: path_route
        uri: http://localhost:8080/
        predicates:
        - Path=/product/{segment}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    8:Query路由匹配规则

    所述 Query 路由断言工厂采用两个参数:所要求的 param 和可选的 regexp (其是Java正则表达式)。
    以下示例配置查询路由断言:

    spring:
    application:
     name: gateway-server
    cloud:
     gateway:
      routes:
       - id: query_route
        uri: http://localhost:8080/
        predicates:
        - Query=green
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    如果请求包含 green 查询参数,则前面的路由匹配。

    9:RemoteAddr路由匹配规则-远端ip地址匹配

    所述 RemoteAddr 路由断言工厂需要的列表(分钟尺寸1) sources ,其是CIDR的表示法(IPv4或
    IPv6)的字符串,如 192.168.0.1/16 (其中 192.168.0.1 是一个IP地址和 16 一个子网掩码)。下面
    的示例配置RemoteAddr路由断言:

    spring:
    cloud:
     gateway:
      routes:
      - id: remoteaddr_route
       uri: https://example.org
       predicates:
       - RemoteAddr=192.168.1.1/24
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    10:Weight路由匹配规

    该 Weight 路由断言工厂有两个参数: group 和 weight (一个int)。权重是按组计算的。以下示例配
    置权重路由断言:

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

    这条路线会将大约80%的流量转发到weighthigh.org,将大约20%的流量转发到weightlow.org。
    这个方案可以用来做灰度发布

    3:Gateway过滤器

    Gateway分为Pre类型的过滤器和Post类型的过滤器。

    • Pre类型的过滤器在请求转发到后端微服务之前执行,在Pre类型过滤器链中可以做鉴权、限流等操
      作。
    • Post类型的过滤器在请求执行完成之后、将结果返回给客户端之前执行。

    在Spring Cloud Gateway中内置了很多Filter,Filter有两种实现,分别是GatewayFilter和
    GlobalFilter。GlobalFilter全局过滤器会应用到所有的路由上,而GatewayFilter只会应用到单个路由或
    者一个分组的路由上。

    1:Gateway过滤器工厂介绍

    过滤器 有 20 多个 实现 类, 包括 头部 过滤器、 路径 类 过滤器、 Hystrix 过滤器 和 变更 请求 URL 的
    过滤器, 还有 参数 和 状态 码 等 其他 类型 的 过滤器。
    内置的过滤器工厂有22个实现类,包括 头部过滤器、路径过滤器、Hystrix 过滤器 、请求URL 变更过滤
    器,还有参数和状态码等其他类型的过滤器。根据过滤器工厂的用途来划分,可以分为以下几种:
    Header、Parameter、Path、Body、Status、Session、Redirect、Retry、RateLimiter和Hystrix
    在这里插入图片描述

    2:自定义过滤器

    Spring Cloud Gateway提供了过滤器的扩展功能,开发者可以根据实际业务需求来自定义GatewayFilter网关过滤器或者GlobalFilter全局过滤器。
    GatewayFilter可以制定在某些路由上

    1:自定义Gateway Filter-实现GatewayFilter、Ordered两个接口

    编写过滤器

    package com.example.gatewayserver.filter;
    
    import org.springframework.boot.web.servlet.filter.OrderedFilter;
    import org.springframework.cloud.gateway.filter.GatewayFilter;
    import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    import org.springframework.core.Ordered;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    /**
     * @author wangkanglu
     * @version 1.0
     * @description
     * @date 2022-08-26 17:42
     */
    
    public class MyFirstFilter implements GatewayFilter, Ordered {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            System.out.println("自定义过滤器启动");
            return chain.filter(exchange);
        }
        //过滤器存在优先级,order越大,优先级越低
        @Override
        public int getOrder() {
            return -1;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    定义好MyFirstFilter 以后,其需要跟Route绑定使用,不能在application.yml文件中配置使用

    package com.example.gatewayserver.config;
    
    import com.example.gatewayserver.filter.MyFirstFilter;
    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 wangkanglu
     * @version 1.0
     * @description
     * @date 2022-08-26 19:30
     */
    @Configuration
    public class GatewayConfig {
        @Bean
        public RouteLocator routeLocator(RouteLocatorBuilder builder) {
            return builder.routes().route(r ->
                                    r.path("/user/**")
                                    //转发路由
                                    .uri("http://localhost:19091/")
                                    //注册自定义过滤器
                                    .filters(new MyFirstFilter())
                                    //给定id
                                    .id("gataway-user"))
                    .build();
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    2:自定义Gateway Filter Factory-继承AbstractGatewayFilterFactory

    很多时候更希望在配置文件中配置Gateway Filter,所以可以自定义过滤器工厂实现。

    自定义过滤器工厂需要继承AbstractGatewayFilterFactory,该类必须以GatewayFilterFactory结尾

    package com.example.gatewayserver.filter;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import org.springframework.cloud.gateway.filter.GatewayFilter;
    import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
    import org.springframework.stereotype.Component;
    
    /**
     * @author wangkanglu
     * @version 1.0
     * @description
     * @date 2022-08-26 19:44
     */
    @Component
    public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory.Config> {
    
    
        public MyGatewayFilterFactory() {
            super(Config.class);
        }
    
        @Override
        public GatewayFilter apply(Config config) {
            return (exchange, chain) -> {
                System.out.println("自定义过滤器工厂:"+config.isEnabled());
                return chain.filter(exchange);
            };
        }
    
    //    @Data
    //    @AllArgsConstructor
    //    @NoArgsConstructor
        //必须是静态内部类,必须优于Factory提前加载
        public static class Config {
            // 控制是否开启认证
            private boolean enabled;
    
            public Config() { }
    
            public boolean isEnabled() {
                return enabled;
            }
    
            public void setEnabled(boolean enabled) {
                this.enabled = enabled;
            }
    
    
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    在配置文件中新增如下配置生效自定义的过滤器,这边的名称就是自定义过滤器的前缀:

    server:
      port: 19090
    
    
    spring:
      application:
        name: gateway-server
      cloud:
        gateway:
          routes: #路由规则定义
            - id: gataway-user #路由ID,必须唯一
              uri: http://localhost:19091/ #路由地址,后续也可更改成其他的类型,诸如指向微服务
              predicates: # 断言规则,既满足此断言既按照此路由规则跳转
                - Path=/user/**   #请注意这个Path的P是大写的!
            - id: gateway-order
              uri: http://localhost:19092/
              predicates:
                - Path=/order/**
              filters:
                - name: My #名称就是自定义过滤器的前缀
                  args:
                    enabled: true
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    3:自定义全局过滤器

    全局过滤器,顾名思义,应用于全局,对于每一个经过网关的请求都会走到全局过滤器。全局过滤器可以做日志的监控以及鉴权等等功能。
    全局过滤器需要实现GlobalFilter, Ordered接口,并且加上加上@Component注解即可;

    package com.example.gatewayserver.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;
    
    
    /**
     * @author wangkanglu
     * @version 1.0
     * @description 全局过滤器
     * @date 2022-08-26 20:09
     */
    @Component
    public class MyCustomerGlobalFilter implements GlobalFilter, Ordered {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            System.out.println("此时全局过滤器前置加载-----");
    //        return chain.filter(exchange);
            return chain.filter(exchange).then(Mono.fromRunnable(
                    ()-> System.out.println("此时后置过滤器加载------------")
            ));
        }
    
        //数字越小,优先级越高
        @Override
        public int getOrder() {
            return -2;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    在这里插入图片描述

    4:gateway和nacos整合

    1:导包

     
    
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2:各项服务注册进nacos

    所有服务都要注册金nacos

    spring:
      application:
        name: gateway-user
      cloud:
        nacos:
          discovery:
            #注册中心地址
            server-addr: ip:8848
            #注册中心命名空间
            namespace: 55f18581-f53b-4d17-b27a-d05d182fe1a9
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    3:gateway路由规则按照注册服务名称调用

    server:
      port: 19090
    
    
    spring:
      application:
        name: gateway-server
      cloud:
        nacos:
          discovery:
            #注册中心地址
            server-addr: ip:8848
            #注册中心命名空间
            namespace: 55f18581-f53b-4d17-b27a-d05d182fe1a9
        gateway:
          routes: #路由规则定义
            - id: gataway-user #路由ID,必须唯一
              uri: lb://gataway-user     #路由地址,后续也可更改成其他的类型,诸如指向微服务
              predicates: # 断言规则,既满足此断言既按照此路由规则跳转
                - Path=/user/**   #请注意这个Path的P是大写的!
            - id: gateway-order
              uri:  lb://gateway-order
              predicates:
                - Path=/order/**
              filters:
                - name: My #名称就是自定义过滤器的前缀
                  args:
                    enabled: true
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
  • 相关阅读:
    APS学习-LEKIN
    凛冬已至,程序员该怎么取暖
    力扣:88. 合并两个有序数组(Python3)
    HALCON-从入门到入门-阈值分割定位算子综合运用
    Linux性能优化实践(1): 进程长时间不被调度执行案例
    【CSS颜色指南】:看完这一篇就明白CSS常见颜色表示方法
    如何使用postman做接口测试
    算法day42|背包问题
    【Linux】/proc/meminfo获取的参数信息分别是什么意思呐?
    【React-Native开发3D应用】React Native加载GLB格式3D模型并打包至Android手机端
  • 原文地址:https://blog.csdn.net/qq_41694906/article/details/126545995