• Gateway解析


    Spring Cloud Gateway的核心概念

    • Route 路由,它是网关的基础元素,包含ID、目标URI、断言、过滤器组成,当前请求到达网关时,会通过Gateway Handler Mapping,基于断言进行路由匹配,当断言为true时,匹配到路由进行转发
    • Predicate,断言,它可以允许开发人员去匹配HTTP请求中的元素,一旦匹配为true,则表示匹配到合适的路由进行转发
    • Filter,过滤器,可以在请求发出的前后进行一些业务上的处理,比如授权、埋点、限流等。

    它的整体工作原理如下:
    其中,predicate就是我们的匹配条件;而filter,就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标uri,就可以实现一个具体的路由了。
    客户端向 Spring Cloud Gateway 发出请求,如果请求与网关程序定义的路由匹配,则该请求就会被发送到网关 Web 处理程序,此时处理程序运行特定的请求过滤器链。
    过滤器之间用虚线分开的原因是过滤器可能会在发送代理请求的前后执行逻辑。所有 pre 过滤器逻辑先执行,然后执行代理请求;代理请求完成后,执行 post 过滤器逻辑

    Filter

    • GlobalFilter
    • RouteFilter

    AddRequestParameter GatewayFilter Factory

    省略第一个路径地址gateway,AddRequestParameter=param, blue意思是添加param=blue的参数

    spring:
      application:
        name: spring-cloud-gateway
      cloud:
        gateway:
          routes:
            - id: add_request_parameter_route
              predicates:
                - Path=/gateway/**
              uri: http://localhost:8082/
              filters:
                - StripPrefix=1
                - AddRequestParameter=param, blue
    

    RequestRateLimiter GatewayFilter Factory

    该过滤器会对访问到当前网关的所有请求执行限流过滤,如果被限流,默认情况下会响应HTTP 429- Too Many Requests。RequestRateLimiterGatewayFilterFactory 默认提供了 RedisRateLimiter 的限流实现,它采用令牌桶算法来实现限流功能

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
    </dependency>
    
    @Component
    public class IpAddressKeyResolver implements KeyResolver{
    
        @Override
        public Mono<String> resolve(ServerWebExchange exchange) {
            return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
        }
    }
    
    spring:
      cloud:
        gateway:
            routes: 
            - id: ratelimiter_route
              predicates:
                - Path=/ratelimiter/**
              filters:
                - StripPrefix=1
                - name: RequestRateLimiter
                args:
                  deny-empty-key: true
                  keyResolver: '#{@ipAddressKeyResolver}'
                  redis-rate-limiter.replenishRate: 1
                  redis-rate-limiter.burstCapacity: 2
              uri: lb://order-service
    

    redis-rate-limiter 过滤器有两个配置属性,如果了解令牌桶,就很容易知道它们的含义。

    • replenishRate:令牌桶中令牌的填充速度,代表允许每秒执行的请求数。
    • burstCapacity:令牌桶的容量,也就是令牌桶最多能够容纳的令牌数。表示每秒用户最大能够执行的请求数量。

    Retry GatewayFilter Factory

    Retry GatewayFilter Factory 为请求重试过滤器,当后端服务不可用时,网关会根据配置参数来发起重试请求

    spring:
      cloud:
        gateway:
          routes:
          - id: retry_route
          uri: http://www.example.com
          predicates:
          - Path=/example/**
          filters:
          - name: Retry
            args:
              retries: 3
              status: 503
          - StripPrefix=1
    

    RetryGatewayFilter 提供 4 个参数来控制重试请求,参数说明如下

    • retries:请求重试次数,默认值是 3。
    • status:HTTP 请求返回的状态码,针对指定状态码进行重试,比如,在上述配置中,当服务端返回的状态码是 503 时,才会发起重试,此处可以配置多个状态码。
    • methods:指定 HTTP 请求中哪些方法类型需要进行重试,默认是 GET。
    • series:配置错误码段,表示符合某段状态码才发起重试,默认值是 SERVER_ERROR(5),表示5xx 段的状态码都会发起重试。如果 series 配置了错误码段,但是 status 没有配置,则仍然会匹配 series 进行重试。

    自定义断言(实现抽象方法AbstractRoutePredicateFactory)

    @Component
    public class AuthRoutePredicateFactory extends AbstractRoutePredicateFactory<AuthRoutePredicateFactory.Config>{
    
        public AuthRoutePredicateFactory() {
            super(Config.class);
        }
    
        private static final String NAME_KEY="name";
        private static final String VALUE_KEY="value";
    
        @Override
        public List<String> shortcutFieldOrder() {
            return Arrays.asList(NAME_KEY,VALUE_KEY);
        }
    
        @Override
        public Predicate<ServerWebExchange> apply(Config config) {
            //Header中携带了某个值,进行header的判断
            return (exchange->{
                HttpHeaders headers=exchange.getRequest().getHeaders();
                List<String> headerList=headers.get(config.getName());
                return headerList.size()>0;
            });
        }
    
        public static class Config{
            private String name;
            private String value;
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public String getValue() {
                return value;
            }
    
            public void setValue(String value) {
                this.value = value;
            }
        }
    }
    
    spring:
      cloud:
        gateway:
          routes:
          - id: auth_route
            predicates:  
              - Auth=Authorization,token
            filters:
              - StripPrefix=1
            uri: https://www.baidu.com
    

    自定义拦截(实现抽象方法AbstractGatewayFilterFactory)

    @Component
    public class MyDefineGatewayFilterFactory extends AbstractGatewayFilterFactory<MyDefineGatewayFilterFactory.MyConfig>{
    
        private static final String NAME_KEY="name";
    
        Logger logger= LoggerFactory.getLogger(MyDefineGatewayFilterFactory.class);
    
        public MyDefineGatewayFilterFactory() {
            super(MyConfig.class);
        }
    
        @Override
        public List<String> shortcutFieldOrder() {
            return Arrays.asList(NAME_KEY);
        }
    
        @Override
        public GatewayFilter apply(MyConfig config) {
            //Filter pre  post
            return ((exchange,chain)->{
                logger.info("[pre] Filter Request, name:"+config.getName());
                //TODO
                return chain.filter(exchange).then(Mono.fromRunnable(()->{
                    //TODO
                    logger.info("[post]: Response Filter");
                }));
            });
        }
    
        public static class MyConfig{
            private String name;
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
        }
    }
    
    spring:  
      cloud:
        gateway:
          routes:
            - id: config_route
              predicates:
                - Path=/gateway/**
              filters:
                - StripPrefix=1
                - MyDefine=Hello world
              uri: http://localhost:8082/
    

    查看gateway的配置

    http://ip:port/actuator/gateway/routes

  • 相关阅读:
    linux top详解
    软件人才必须具备的素质
    合格程序员每天每周每月每年应该做的事
    正则匹配任意字符(包括换行)
    软件测试方案
    LInux进程间的通信方式有哪儿些?
    三网融合
    php路径问题
    xp 安装SATA AHCI驱动
    进程与线程的区别
  • 原文地址:https://www.cnblogs.com/snail-gao/p/14139338.html
Copyright © 2020-2023  润新知