Spring Cloud服务网关 - Gateway

一、Gateway简介

1、Spring Cloud Gateway是Spring官方提供的API网关

2、Gateway是基于Spring5和Spring Boot2开发的

3、Gateway是基于Netty开发的异步调用网关

二、Gateway依赖配置



  org.springframework.boot
  spring-boot-starter-webflux



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


#配置示例
spring:
  cloud:
    gateway:
      routes:
       - id: xxx-predicate
       	 uri: "http://www.jd.com"
         predicates:
         - Path=/xxx/**

三、Gateway特性

1、提供动态路由和限流等措施

2、易于编写的Predicate和Filter,提供了良好的扩展性

3、提供了Discovery和Hystrix的集成

#Hystrix Filter配置:
spring:
  cloud:
    gateway:
      routes:
       - id: xxx-predicate
       	 uri: "http://www.jd.com"
         predicates:
         - Path=/xxx/**
         filter:
          - name: Hystrix
            args:
              name: ExampleHystrix
              fallbackUri: forward:/fallback

四、Predicate使用

1、Predicate是路由匹配规则,满足条件即可触发路由

2、Predicate可以进行自定义,满足个性化要求

#Path是断言的名字,等号后面是断言的值
spring:
  cloud:
    gateway:
      routes:
       - id: xxx-predicate
       	 uri: "http://www.jd.com"
         predicates:
         - Path=/xxx/**
         - After=2020-10-25
/**
 * @author : zhenghaorui
 * @program : com.springcloud.gatewaydemo.predicates
 * @description : 日期路由自定义
 **/
//注意:自定义类继承AbstractRoutePredicateFactory,并且命名必须以RoutePredicateFactory结尾,而RoutePredicateFactory前面自定义的名字是断言的名字
public class AfterRoutePredicateFactory extends AbstractRoutePredicateFactory {
  public static final String AFTER_KEY = "datetime";
  /**
  * @Description:  传入配置信息
  * @Param: []
  * @return:
  * @Author: zhenghaorui
  */
  public JiangzhAfterRoutePredicateFactory() {
    super(JiangzhAfterRoutePredicateFactory.Config.class);
  }

  /** 
  * @Description: 参数列表与Config属性之间的映射
  * @Param: [] 
  * @return: java.util.List 
  * @Author: zhenghaorui
  */ 
  @Override
  public List shortcutFieldOrder() {
    return Collections.singletonList(AFTER_KEY);
  }
  /**
  * @Description: 具体的路由匹配逻辑
  * @Param: [config]
  * @return: java.util.function.Predicate
  * @Author: zhenghaorui
  */
  @Override
  public Predicate apply(Config config) {
    System.out.println("JiangzhAfterRoutePredicateFactory -> config : "+config);
    DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    long nowTime = System.currentTimeMillis();
    return (exchange) -> {
      // 解析出配置定义的时间
      long afterTime = 0;
      try {
        afterTime = format.parse(config.getDatetime()).getTime();
      } catch (ParseException e) {
        return false;
      }
      // 如果当前时间大于配置定义时间,则返回true
      return nowTime > afterTime;
    };
  }

  /**
  * @Description: 用于承载断言传入的值
  * @Param: 我们这里是判断输入的时间与真实时间之间的先后关系
  * @Author: zhenghaorui
  */
  public static class Config {
    @NotEmpty
    private String datetime;

    public Config() {
    }

    public String getDatetime() {
      return datetime;
    }

    public void setDatetime(String datetime) {
      this.datetime = datetime;
    }
  }

}
@Configuration
public class GWConf {
    @Bean
    public AfterRoutePredicateFactory initAfterRoutePredicateFactory() {
        return new AfterRoutePredicateFactory();
    }
}

3、Spring Cloud Gateway预置了很多Predicate

Spring Cloud服务网关 - Gateway_第1张图片

五、Filter使用

1、Filter可以对Request进行请求过滤处理

2、Gateway的Filter分为全局和局部两种

1)自定义全局Filter:

/**
 * @author : zhenghaorui
 * @program : com.springcloud.gatewaydemo.Filters
 * @description : 自定义全局Filter
 **/
@Slf4j
public class MyGlobalFilter implements GlobalFilter, Ordered {
  /**
   * @Description : 业务处理逻辑
   * @Param : [exchange, chain]
   * @return : reactor.core.publisher.Mono
   * @Author : zhenghaorui
   **/
  @Override
  public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    long beginTime = System.currentTimeMillis();
    log.info("filter start ----> beginTime:{}", beginTime);
    return chain.filter(exchange).then(Mono.fromRunnable(()->{
      long endTime = System.currentTimeMillis();
      log.info("filter end ----> endTime{}, cost:{}",endTime , endTime-beginTime);
    }));
  }

  /**
   * @Description : 判断Filter顺序
   * @Param : []
   * @return : int
   * @Author : zhenghaorui
   **/
  @Override
  public int getOrder() {
    return 0;
  }
}
@Configuration
public class GWConf {
    @Bean
    public AfterRoutePredicateFactory initAfterRoutePredicateFactory() {
        return new AfterRoutePredicateFactory();
    }
    
    @Bean
    public MyGlobalFilter initMyGlobalFilter() {
        return new MyGlobalFilter();
    }
}

 2)自定义局部Filter:

#配置示例
spring:
  cloud:
    gateway:
      routes:
       - id: xxx-predicate
       	 uri: "http://www.jd.com"
         predicates:
         - Path=/xxx/**
         - After=2020-10-25
         filter:
         - Example=paramName,paramValue
/**
 * @author : zhenghaorui
 * @program : com.springcloud.gatewaydemo.Filters.factorys
 * @description :
 **/
@Slf4j
@Component
public class ExampleGatewayFilterFactory extends AbstractGatewayFilterFactory {
  private static String PARAM_NAME="paramName";
  private static String PARAM_VALUE="paramValue";

  public JiangzhGatewayFilterFactory(){
    super(Config.class);
  }

  @Override
  public GatewayFilter apply(Config config) {
    return ((exchange, chain) -> {
      Set keys = exchange.getRequest().getQueryParams().keySet();
      for(String key : keys){
        log.info("key:{} , value:{}", key, exchange.getRequest().getHeaders().get(key));
      }

      List headNames = exchange.getRequest().getQueryParams().get(config.getParamName());

      if(headNames!=null && headNames.size()>0){
        log.info("PARAM_NAME:{},PARAM_VALUE:{}, headNames:{}",config.getParamName(),config.getParamValue(),headNames);
        if(config.getParamValue().equalsIgnoreCase(headNames.get(0))){
          return chain.filter(exchange);
        }
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
      }else{
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
      }
      return exchange.getResponse().setComplete();
    });
  }

  @Override
  public List shortcutFieldOrder() {
    return Arrays.asList(PARAM_NAME,PARAM_VALUE);
  }

  @Data
  public static class Config{
    private String paramName;
    private String paramValue;

    public String getParamName() {
      return paramName;
    }

    public void setParamName(String paramName) {
      this.paramName = paramName;
    }

    public String getParamValue() {
      return paramValue;
    }

    public void setParamValue(String paramValue) {
      this.paramValue = paramValue;
    }
  }
}

3)预定义全局Filter: 

Spring Cloud服务网关 - Gateway_第2张图片

4)预定义局部Filter:

Spring Cloud服务网关 - Gateway_第3张图片

3、Filter除了过滤还可以对请求内容进行增强处理

你可能感兴趣的:(Spring,Cloud,java,spring,springcloud)