gateway predicate

spring:
  cloud:
    gateway:
      routes:
        - id: test_my_provider # 自定义,全局唯一即可
          uri: http://localhost:8081 # 实际调用的地址
          predicates:
            - Path=/test/** # 请求匹配规则
        - id: test_my_consumer
          uri: http://localhost:8082
          predicates:
            - Path=/feign/**

上一篇文章 gateway 快速入门的配置文件如上,uri 中 ip 和 port 写死的,请求最终会到具体的某个节点,如果多节点部署,直接G

多节点 uri

8081 对应服务是 my-test-provider,8082 对应的服务是 my-test-consumer,如下改动即可

- id: test_my_provider 
  uri: lb://my-test-provider # 服务名代替 ip+port
  predicates:
    - Path=/test/**
- id: test_my_consumer
  uri: lb://my-test-consumer # 服务名代替 ip+port
  predicates:
    - Path=/feign/**

predicates 更多用法

前面 predicates 只是配了一个 Path,表示匹配 url,还能增加判断规则,即使能找到 url,也要满足条件才能调用,默认的有 12 种

  1. 时间判断

    1. BeforeRoutePredicateFactory、AfterRoutePredicateFactory、BetweenRoutePredicateFactory

    2. 指定时间之前、指定时间之后、时间范围内(如果是范围英文逗号分隔,start,end)

    3. 值是 ZonedDateTime 决定的

      public static void main(String[] args) {
          System.out.println(ZonedDateTime.now());
      }
      
      // 2024-07-15T21:41:48.868923400+08:00[Asia/Shanghai]
      
    4. 比如电商系统某个商品限时抢购,2024-07-13 一整天

      - id: flash-sale-promotion 
        uri: lb://my-test-provider # 服务名代替 ip+port
        predicates:
          - Path=/onsale/**
          - Between=2024-07-13T00:00:00+08:00[Asia/Shanghai],2024-07-14T00:00:00+08:00[Asia/Shanghai]
      
  2. cookie 判断

    - id: flash-sale-promotion 
      uri: lb://my-test-provider # 服务名代替 ip+port
      predicates:
        - Path=/onsale/**
        - Between=2024-07-13T00:00:00+08:00[Asia/Shanghai],2024-07-14T00:00:00+08:00[Asia/Shanghai]
        - Cookie=username,zhangsan # 请求中必须有 username = zhangsan 的 cookie,后面其实是个政策表达式
    
  3. header 请求头判断

    - id: flash-sale-promotion 
      uri: lb://my-test-provider # 服务名代替 ip+port
      predicates:
        - Path=/onsale/**
        - Between=2024-07-13T00:00:00+08:00[Asia/Shanghai],2024-07-14T00:00:00+08:00[Asia/Shanghai]
        - Cookie=username,zhangsan
        - Header=userage,\d+ # 请求头必须有 userage,并且值是正整数
    
  4. Path,前面用了很多了,就是通过 url 判断是否符合

  5. Query,请求必须带有某个 QueryString 才可以(get 请求?xx=xx&xx=xx)

  6. RemoteAddr,IP 限制,符合的 IP 才能访问

  7. Method,请求方式限制,只能符合的才能访问,GET、POST、PUT ...

自定义判断规则

/**
 * 类名必须为 xxxRoutePredicateFactory 格式(RoutePredicateFactory 结尾)
 *
 * @author yujian
 * @since 2024/7/18
 */
@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {

    // 参照别的 RoutePredicateFactory,直接拷过来
    public MyRoutePredicateFactory() {
        super(MyRoutePredicateFactory.Config.class);
    }

    // 支持短促的格式配置,参数为 Config 的属性名,意味着配置文件要配这个,也可以直接理解为读取配置文件的哪个属性
    @Override
    public List<String> shortcutFieldOrder() {
        return Collections.singletonList("level");
    }

    /**
     * 自定义的 RoutePredicateFactory,请求头的 token 必须要等于配置文件的 token 属性
     *
     * @param config 配置文件中 predicates 部分
     * @return Predicate
     */
    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return serverWebExchange -> {

            // 请求 url 必须要带 level
            String level = serverWebExchange.getRequest().getQueryParams().getFirst("level");
            if (!StringUtils.hasText(level)) {
                return false;
            }
            // 如果 level = 3 就通过(配置文件配的3)
            return level.equals(config.getLevel());
        };
    }

    @Validated
    public static class Config {

        private String level;

        public String getLevel() {
            return level;
        }

        // 参数不能为空,不然启动要报错,可以定时的时候赋个空字符串或者这里加个注解判断
        public void setLevel(@NotNull String level) {
            this.level = level;
        }
    }
}

配置文件如下,为什么是 My?因为自定义的判断是 MyRoutePredicateFactory。My=3 是什么?判断配置的属性 level(使用了短促配置,可以省略,也可以使用full配置)等于 3 就通过

routes:
- id: test_my_provider 
  uri: http://localhost:8081 
  predicates:
    - Path=/test/** # 请求匹配规则
    - My=3 # 自定义的判断规则
    #- name=My 这是 full 配置
    #  args:
    #    level: 3

测试,只有带了 3 才会成功

posted @ 2024-07-15 22:04  CyrusHuang  阅读(2)  评论(0编辑  收藏  举报