Spring Cloud之网关

298 阅读13分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

网关(Gateway)是微服务体系中非常重要的一个模块,它提供了鉴权、路由、限流等功能。

为什么需要网关?

  • 如果添加鉴权功能,需要对每一个服务进行改造。

  • 跨域问题需要对每一个服务进行改造。

  • 流量控制需要对每一个服务进行改造。

  • 灰度发布、动态路由需要对每一个服务进行改造。

  • 收集用户日志访问记录需要聚合各个微服务里的数据。

  • 存在安全问题。每个微服务暴露的Endpoint是固定的,客户端访问需要清楚各个微服务真实的Endpoint。

有了网关之后,客户端所有的流量全部先经过网关,网关再转发到对应的微服务,然后微服务返回结果给网关,网关最终将结果展现给客户。

Spring Cloud Gateway

Spring Cloud Gateway基于reactive响应式模型,是一个非阻塞式的网关实现。由于Spring Cloud Gateway是Spring生态体系的一个子项目,因此也整合了Spring生态体系的其他项目:服务注册/发现、分布式配置,并且使用Circuit Breaker提供容错机制。

Spring Cloud Gateway定义了RoutePredicateHandlerMapping这个HandlerMappping接口实现类(该接口是WebFlux定义的一个流量请求的处理器),用于处理请求的映射关系,得到的结果被HandlerAdapter处理。下面代码是RoutePredicateHandlerMapping对请求的处理过程:

    @Override
    protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
       // 应用开启了management功能(Spring Boot Actuator)
       // 若端口与应用不一致,则不对请求进行处理
       if (this.managementPortType == DIFFERENT && this.managementPort != null
             && exchange.getRequest().getURI().getPort() == this.managementPort) {
          return Mono.empty();
       }
       exchange.getAttributes().put(GATEWAY_HANDLER_MAPPER_ATTR, getSimpleName());

       return lookupRoute(exchange) // 根据请求信息,通过lookup方法找出合适的Route信息
             .flatMap((Function<Route, Mono<?>>) r -> {
                exchange.getAttributes().remove(GATEWAY_PREDICATE_ROUTE_ATTR);
                if (logger.isDebugEnabled()) {
                   logger.debug(
                         "Mapping [" + getExchangeDesc(exchange) + "] to " + r);
                }

                exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, r);
               	// HandlerMapping返回结果是一个FilteringWebHandler。
               	// 这个WebHandler会在GatewayAutoConfiguration自动化配置类中被构造
                return Mono.just(webHandler);
             }).switchIfEmpty(Mono.empty().then(Mono.fromRunnable(() -> {
                exchange.getAttributes().remove(GATEWAY_PREDICATE_ROUTE_ATTR);
                if (logger.isTraceEnabled()) {
                   logger.trace("No RouteDefinition found for ["
                         + getExchangeDesc(exchange) + "]");
                }
             })));
    }
    protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
            return this.routeLocator.getRoutes() // 根据RouterLocator找出所有定义的路由信息
                            //  通过Route里的Predicate和请求信息判断路由是否满足条件
                            .concatMap(route -> Mono.just(route).filterWhen(r -> {
                                    exchange.getAttributes().put(GATEWAY_PREDICATE_ROUTE_ATTR, r.getId());
                                    return r.getPredicate().apply(exchange);
                            })
            .doOnError(e -> logger.error(
                  "Error applying predicate for route: " + route.getId(),
                  e))
            .onErrorResume(e -> Mono.empty()))
                            .next()
                            .map(route -> {
                                    if (logger.isDebugEnabled()) {
                                            logger.debug("Route matched: " + route.getId());
                                    }
                                    // 验证路由是否合法
                                    validateRoute(route, exchange);
                                    return route;
                            });
    }

RoutePredicateHandlerMapping返回的WebHandlerFilteringWebHandler,它会被HandlerAdapter接口处理。Spring Cloud Gateway会被SimpleHandlerAdapter这个HandlerAdapter实现类处理(如果是WebFlux,则会被RequestMappingHandlerAdapter处理)。

下面是SimpleHandlerAdapter处理FilteringWebHandler的过程,内部直接使用FilteringWebHandler对请求进行处理:

public class SimpleHandlerAdapter implements HandlerAdapter {

   @Override
   public boolean supports(Object handler) {
      return WebHandler.class.isAssignableFrom(handler.getClass());
   }

   @Override
   public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
      WebHandler webHandler = (WebHandler) handler;
      Mono<Void> mono = webHandler.handle(exchange);
      return mono.then(Mono.empty());
   }

}

public class FilteringWebHandler implements WebHandler {
  ...
    @Override
    public Mono<Void> handle(ServerWebExchange exchange) {
        Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
        List<GatewayFilter> gatewayFilters = route.getFilters();

        // globalFilters属性是构造FilteringWebHandler的过程注入的GlobalFilters拦截器集合
        List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
        combined.addAll(gatewayFilters);
        // TODO: needed or cached?
        AnnotationAwareOrderComparator.sort(combined);

        if (logger.isDebugEnabled()) {
                logger.debug("Sorted gatewayFilterFactories: " + combined);
        }

        return new DefaultGatewayFilterChain(combined).filter(exchange);
    }
    // DefaultGatewayFilterChain是个过滤器链,内部存储着各种过滤器。
    private static class DefaultGatewayFilterChain implements GatewayFilterChain {

        private final int index;

        private final List<GatewayFilter> filters;

        DefaultGatewayFilterChain(List<GatewayFilter> filters) {
                this.filters = filters;
                this.index = 0;
        }

        private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {
                this.filters = parent.getFilters();
                this.index = index;
        }

        public List<GatewayFilter> getFilters() {
                return filters;
        }

        @Override
        public Mono<Void> filter(ServerWebExchange exchange) {
                return Mono.defer(() -> {
                        if (this.index < filters.size()) {
                                GatewayFilter filter = filters.get(this.index);
                                DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this,
                                                this.index + 1);
                                return filter.filter(exchange, chain);
                        }
                        else {
                                return Mono.empty(); // complete
                        }
                });
        }

    }
  ...
}

Spring Cloud Gateway整个请求处理流程:

截屏2022-09-17+21.21.08.png

  1. 请求进来后,被RoutePredicateHandlerMapping这个HandlerMapping处理。

  2. HandlerMapping处理的过程中,会通过所有的Route信息列表中每一个路由信息里的Predicate找出合适的Route(路由)。

  3. RoutePredicateHandlerMapping处理后得到的结果是一个FilterWebHandler

  4. FilterWebHandler使用内部的GlobalFilter对请求进行处理。如果路由信息也配置类GatewayFilter,这些GatewayFilter会和GlobalFilter一起被执行(GlobalFilter对全局生效,GatewayFilter只对部分(需要配置)生效)。

  5. 一些路由Filter会调用下游对服务,最终将结果返回给客户端。

Route路由信息

Spring Cloud Gateway在RoutePredicateHandlerMapping映射请求的过程中,首先找出所有的路由信息,这个路由信息对应的就是Route类。

Route类存在以下6个属性:

  • idString:路由的ID。

  • uriURI:路由的URI信息。每个URI有对应的protocol协议和path(路径)。Spring Cloud Gateway会根据URI里的属性完成不同的事情。

    • lb协议的URI会根据ReactiveLoadBalancerClientFilter从注册中心获取实例;

    • HTTP或HTTPS协议的URI会根据WebClientHttpRoutingFilter通过WebClient发起HTTP请求;

    • WS或WSS协议的URI会根据WebSocketRoutingFilter通过WebSocketClient发起websocket请求。

  • orderint:路由的优先级。Route实现了Spring的Ordered接口,该接口对应的getOrder方法的返回值就是该属性。

  • predicateAsyncPredicate<ServerWebExchange>AsyncPredicate是支持Reactive的Predicate实现,内部的Predicate通过RoutePredicateFactory构造。

  • gatewayFiltersList<GatewayFilter>GatewayFilter集合。

  • metadataMap<String,Object>:路由信息的元数据信息。

Predicate机制

Predicate是Spring Cloud Gateway的核心组件之一,其作用是在请求映射的过程中匹配到用户的请求。比如,PathRoutePredicateFactory构造的Predicate会用于路径的匹配,HeaderRoutePredicateFactory构造的Predicate用于Header的匹配。

PredicationDefinition和AsyncPredicate

Spring Cloud Gateway路由配置对应的predicate信息通过对象PredicationDefinition构造。

@Validated
public class PredicateDefinition {

   @NotNull
   private String name;

   private Map<String, String> args = new LinkedHashMap<>();

   public PredicateDefinition() {
   }

   public PredicateDefinition(String text) {
      int eqIdx = text.indexOf('=');
      if (eqIdx <= 0) {
         throw new ValidationException("Unable to parse PredicateDefinition text '"
               + text + "'" + ", must be of the form name=value");
      }
      setName(text.substring(0, eqIdx));

      String[] args = tokenizeToStringArray(text.substring(eqIdx + 1), ",");

      for (int i = 0; i < args.length; i++) {
         this.args.put(NameUtils.generateName(i), args[i]);
      }
   }
   ...
 }

PredicationDefinition对应的配置信息Path=/httpbin/**其实就是根据这个构造函数完成构造的。PredicationDefinition会在PredicationDefinitionRouteLocator中通过RoutePredicateFactory转换成AsyncPredicate(支持Reactive的Predicate)。

PredicationDefinitionRouteLocator在构造时会使用通过Spring ApplicationContext注入的predicate集合来给它的内部属性predicate赋值,这个predicate属性时Map<String,RoutePredicateFactory>类型的,对应的key是RoutePredicateFactory的name方法的返回值。name方法默认的实现是返回类名的缩写,比如PathRoutePredicateFactory对应的name方法的返回值为Path;HostRoutePredicateFactory对应的name方法的返回值为Host。

RoutePredicateFactory

每个RoutePredicateFactory接口的实现有对应的配置Config,表示这个Predicate需要的配置信息,每个Predicate的配置都有自己单独发属性。

下列代码是RouteDefinitionRouteLocator构造函数,内部调用initFactories方法初始化predicates属性:

public RouteDefinitionRouteLocator(RouteDefinitionLocator routeDefinitionLocator,
                                   List<RoutePredicateFactory> predicates,
                                   List<GatewayFilterFactory> gatewayFilterFactories,
                                   GatewayProperties gatewayProperties,
                                   ConfigurationService configurationService) {
  this.routeDefinitionLocator = routeDefinitionLocator;
  this.configurationService = configurationService;
  initFactories(predicates);
  gatewayFilterFactories.forEach(
    factory -> this.gatewayFilterFactories.put(factory.name(), factory));
  this.gatewayProperties = gatewayProperties;
}
private void initFactories(List<RoutePredicateFactory> predicates) {
  predicates.forEach(factory -> {
    String key = factory.name();
    if (this.predicates.containsKey(key)) {
      this.logger.warn("A RoutePredicateFactory named " + key
                       + " already exists, class: " + this.predicates.get(key)
                       + ". It will be overwritten.");
    }
    this.predicates.put(key, factory);
    if (logger.isInfoEnabled()) {
      logger.info("Loaded RoutePredicateFactory [" + key + "]");
    }
  });
}

这些注入的RoutePredicateFactory集合在GatewayAutoConfiguration自动化配置类中完成构造。

RouteDefinitionRouteLocator获取路由信息的时候会根据配置的PreditionDefinition在 predicates属性中寻找对应的RoutePredicateFactory

private AsyncPredicate<ServerWebExchange> combinePredicates(
      RouteDefinition routeDefinition) {
   List<PredicateDefinition> predicates = routeDefinition.getPredicates();
   AsyncPredicate<ServerWebExchange> predicate = lookup(routeDefinition,
         predicates.get(0));

   for (PredicateDefinition andPredicate : predicates.subList(1,
         predicates.size())) {
      AsyncPredicate<ServerWebExchange> found = lookup(routeDefinition,
            andPredicate);
      predicate = predicate.and(found);
   }

   return predicate;
}

lookup方法内部不仅会找到对应的RoutePredicateFactory,还会根据PredicateDefinition的args属性构造对应的Config参数作为RoutePredicateFactory的apply方法里的参数:

private AsyncPredicate<ServerWebExchange> lookup(RouteDefinition route,
      PredicateDefinition predicate) {
   RoutePredicateFactory<Object> factory = this.predicates.get(predicate.getName());
   if (factory == null) {
      throw new IllegalArgumentException(
            "Unable to find RoutePredicateFactory with name "
                  + predicate.getName());
   }
   if (logger.isDebugEnabled()) {
      logger.debug("RouteDefinition " + route.getId() + " applying "
            + predicate.getArgs() + " to " + predicate.getName());
   }

   // @formatter:off
   Object config = this.configurationService.with(factory)
         .name(predicate.getName())
         .properties(predicate.getArgs())
         .eventFunction((bound, properties) -> new PredicateArgsEvent(
               RouteDefinitionRouteLocator.this, route.getId(), properties))
         .bind();
   // @formatter:on

   return factory.applyAsync(config);
}

内置RoutePredicateFactoty

Spring Cloud Gateway提供了一些内置的RoutePredicateFactory

  • PathRoutePredicateFactory:predicates属性里对应的key为Path,根据请求路径的pattern确认是否满足路由条件。对应的Config配置内部维护List类型的patterns,用于请求路径的判断。

  • HostRoutePredicateFactory:predicates属性里对应的key为Host,根据Request Header里的Host属性确认是否满足路由条件。对应的Config配置内部维护List类型的patterns,用于Host Header的判断。

  • MethodRoutePredicateFactory:predicates属性里对应的key为Method,根据Request HTTP Method属性确认是否满足路由条件。对应的Config配置内部维护HttpMethod类型的method属性,用于Request HTTP Method的判断。

  • QueryRoutePredicateFactory:predicates属性里对应的key为Query,根据Request Query Parameter参数是否满足正则表达式确认是否满足路由条件。对应的Config配置内部维护param(Request Query Parameter的key)和regexp(正则表达式)属性,用于从Request Query Parameter中获取对应的信息,并判断是否满足正则表达式。

  • CookieRoutePredicateFactory:predicates属性里对应的key为Cookie,根据Cookie属性是否满足正则表达式确认是否满足路由条件。对应的Config配置内部维护name(Cookie的key)和regexp(正则表达式)属性,用于从Cookie里获取对应的信息并判断是否满足正则表达式。

  • AfterRoutePredicateFactory:predicates属性里对应的key为After,根据当前时间是否晚于配置的时间确认是否满足路由条件。对应的Config配置内部维护datetime属性,用于与当前时间进行比较。

  • BeforeRoutePredicateFactory:predicates属性里对应的key为Before,根据当前时间是否早于配置的时间确认是否满足路由条件。对应Config配置内部维护datetime属性,用于与当前时间进行比较。

  • BetweenRoutePredicateFactory:predicates属性里对应的key为Between,根据当前时间是否处于配置的时间区间确认是否满足路由条件。对应Config配置内部维护datetime1和datetime2属性,用于判断当前时间是否处于这两个时间之内。

  • RemoteAddrRoutePredicateFactory:predicates属性里对应的key为RemoteAddr,根据请求的IP是否处于配置的IP段内确认是否满足路由条件。对应的Config配置内部维护RemoteAddressResolver接口和String集合的source属性。RemoteAddressResolver根据请求解析IP,source用于生产Netty的IpSubnetFilterRule规则进行IP段的判断。

Filter机制

Filter是Spring Cloud Gateway的另一个核心组件,其作用是处理请求。

FilterDefinition和GatewayFilter

Spring Cloud Gateway路由配置对应的Filter信息通过对象FilterDefinition构造:

@Validated
public class FilterDefinition {

   @NotNull
   private String name;

   private Map<String, String> args = new LinkedHashMap<>();

   public FilterDefinition() {
   }

   public FilterDefinition(String text) {
      int eqIdx = text.indexOf('=');
      if (eqIdx <= 0) {
         setName(text);
         return;
      }
      setName(text.substring(0, eqIdx));

      String[] args = tokenizeToStringArray(text.substring(eqIdx + 1), ",");

      for (int i = 0; i < args.length; i++) {
         this.args.put(NameUtils.generateName(i), args[i]);
      }
   }
  ...
}

FilterDefinition的解析与PredicateDefinition基本一致。这个带有String参数的构造函数根据配置信息解析成对应的属性。FilterDefinition最终会被转换成GatewayFilter,这个动作在RouteDefinitionRouteLocator中通过GatewayFilterFactory完成。convertToRoute方法内部不但会根据PredicateDefinition集合构造AsyncPredicate,还会根据FilterDefinition集合构造GatewayFilter,并把这些信息设置到Route属性内:

// RouteDefinitionRouteLocator.java
private Route convertToRoute(RouteDefinition routeDefinition) {
   // 基于定义的路由信息内部的predicate配置构造AsyncPredicate
   AsyncPredicate<ServerWebExchange> predicate = combinePredicates(routeDefinition);
   // 基于定义的路由信息内部的Filter配置构造GatewayFilter
   List<GatewayFilter> gatewayFilters = getFilters(routeDefinition);

   return Route.async(routeDefinition).asyncPredicate(predicate)
         .replaceFilters(gatewayFilters).build();
}

private List<GatewayFilter> getFilters(RouteDefinition routeDefinition) {
  	List<GatewayFilter> filters = new ArrayList<>();

    if (!this.gatewayProperties.getDefaultFilters().isEmpty()) {
      // 如果存在spring.cloud.gateway.defaultFilter配置,则添加到拦截器集合内
      filters.addAll(loadGatewayFilters(DEFAULT_FILTERS,
                                        this.gatewayProperties.getDefaultFilters()));
    }

    if (!routeDefinition.getFilters().isEmpty()) {
      // 如果配置的拦截器信息存在,则添加到拦截器集合内
      filters.addAll(loadGatewayFilters(routeDefinition.getId(),
                                        routeDefinition.getFilters()));
    }

    AnnotationAwareOrderComparator.sort(filters);
    return filters;
 }

loadGatewayFilters方法内部会根据gatewayFilterFactories属性和FilterDefinition的name属性加载GatewayFilter

这个gatewayFilterFactories属性与predicate属性的构造过程相同,在RouteDefinitionRouteLocator的构造方法内注入Spring ApplicationContext内的GatewayFilterFactory集合,用于赋值这个属性。这些Spring ApplicationContext内的GatewayFilterFactory全部都在GatewayAutoConfiguration自动化配置类中初始化完成。

List<GatewayFilter> loadGatewayFilters(String id,
      List<FilterDefinition> filterDefinitions) {
   ArrayList<GatewayFilter> ordered = new ArrayList<>(filterDefinitions.size());
   for (int i = 0; i < filterDefinitions.size(); i++) {
      FilterDefinition definition = filterDefinitions.get(i);
      GatewayFilterFactory factory = this.gatewayFilterFactories
            .get(definition.getName());
      if (factory == null) {
         throw new IllegalArgumentException(
               "Unable to find GatewayFilterFactory with name "
                     + definition.getName());
      }
      if (logger.isDebugEnabled()) {
         logger.debug("RouteDefinition " + id + " applying filter "
               + definition.getArgs() + " to " + definition.getName());
      }

      // @formatter:off
      Object configuration = this.configurationService.with(factory)
            .name(definition.getName())
            .properties(definition.getArgs())
            .eventFunction((bound, properties) -> new FilterArgsEvent(
                  // TODO: why explicit cast needed or java compile fails
                  RouteDefinitionRouteLocator.this, id, (Map<String, Object>) properties))
            .bind();
      // @formatter:on

      // some filters require routeId
      // TODO: is there a better place to apply this?
      if (configuration instanceof HasRouteId) {
         HasRouteId hasRouteId = (HasRouteId) configuration;
         hasRouteId.setRouteId(id);
      }

      GatewayFilter gatewayFilter = factory.apply(configuration);
      if (gatewayFilter instanceof Ordered) {
         ordered.add(gatewayFilter);
      }
      else {
         ordered.add(new OrderedGatewayFilter(gatewayFilter, i + 1));
      }
   }

   return ordered;
}

每个GatewayFilterFactory接口的实现也有对应的配置Config,表示这个GatewayFilter需要的配置信息,每个GatewayFilter的配置都有自己单独的属性。

GlobalFilter

Route配置内保持的Filter类型是GatewFilter。Spring Cloud Gateway还提供了另外一种GlobalFilter的拦截器类型。

GlobalFilter类型的拦截器会让所有的路由都生效,GatewayFilter类型的拦截器只会让配置的路由生效。

GlobalFilter拦截器会让所有路由都生效的原因是:在FilteringWebHandler对请求作出了的时候会自动加上所有的GlobalFilter拦截器。这些GlobalFilter拦截器全部通过Spring ApplicationContext注入,它们都是在GatewayAutoConfiguration自动化配置内初始化完成的。

// FilteringWebHandler.java
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
   Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
   List<GatewayFilter> gatewayFilters = route.getFilters();

   List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
   combined.addAll(gatewayFilters);
   // TODO: needed or cached?
   AnnotationAwareOrderComparator.sort(combined);

   if (logger.isDebugEnabled()) {
      logger.debug("Sorted gatewayFilterFactories: " + combined);
   }

   return new DefaultGatewayFilterChain(combined).filter(exchange);
}

内置GatewayFilterFactory

Spring Cloud Gateway提供了一些内置的GatewayFilterFactory:

  • AddRequestHeaderGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为AddRequestHeader,作用是为Request请求添加新的Header内容。对应的Config配置内部维护name和value属性,用于表示RequestHeader中要添加的key和value。

  • MapRequestHeaderGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为MapRequestHeader,作用是将Request Header中对应的key值转移到另一个key上。对应的Config配置内部维护fromHeader和toHeader属性,用于将Header中的fromHeader对应的值转移到toHeader这个key上。

  • AddRequestParameterGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为AddRequestParameter,作用是为Request请求添加新的Query Parameter参数和内容。对应的Config配置内部维护name和value属性,用于表示Query Parameter中要添加的key和value。

  • AddResponseHeaderGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为AddResponseHeader,作用是为Response请求添加新的Header内容。对应的Config配置内部维护name和value属性,用于表示ResponseHeader中要添加的key和value。

  • ModifyRequestBodyGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为ModifyRequestBody,作用是修改Request Body内容。对应的Config配置内部维护inClass、outClass和RewriteFunction属性,用于将原先Request Body中对应的内容转换成另外的内容。

  • DedupeReponseHeaderGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为DedupeReponseHeader,作用是修改Response Header的内容。对应的Config配置内部维护strategy和name属性,strategy表示保留策略,非为三种:RETAIN_FIRST(只保留第一个)、RETAIN_LAST(只保留最后一个)、RETAIN_UNIQUE(删除重复值)。name则是要修改的HEADER key值。

  • ModifyResponseBodyGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为ModifyResponseBody,作用是修改Response Body内容。对应的Config配置内部维护inClass、outClass和RewriteFunction属性,用于将原先Response Body中对应的内容转换成另外的内容。

  • PrefixPathGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为PrefixPath,作用是为Request Path添加前缀。对应的Config配置内部维护prefix属性,表示要添加的前缀。

  • PreserveHostHeaderGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为PreserveHostHeader,作用是为Request 保留Header中key为Host的内容。没有Config配置信息,如果添加了Filter,则会保存Host Header,否则会删除。

  • RedirectToGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为RedirectTo,作用是对请求进行重定向处理。对应的Config配置内部维护istatus和url属性,其中,status表示Response Code,必须为3xx状态码,url表示重定向地址。

  • RemoveRequestHeaderGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为RemoveRequestHeader,作用是为Request请求删除Header内容。对应的Config配置内部维护name属性,用于表示Request Header中要删除的key。

  • RemoveRequestParameterGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为RemoveRequestParameter,作用是为Request请求删除Query Parameter内容。对应的Config配置内部维护name属性,用于表示Query Parameter中要删除的key。

  • RemoveResponseHeaderGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为RemoveResponseHeader,作用是为Response请求删除Header内容。对应的Config配置内部维护name属性,用于表示Response Header中要删除的key。

  • RewritePathGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为RewritePath,作用是基于正则表达式修改Request的请求URL。对应的Config配置内部维护regexp和replacement属性,regexp表示匹配的正则表达式,replacement表示替换内容。

  • RetryGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为Retry,作用是基于配置信息判断是否需要重试。对应的Config配置包括Response Code的类型(1xx、2xx、3xx、4xx或5xx)、具体的Code状态码和HTTP Method等信息。

  • SetPathGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为SetPath,作用是基于UriTemplate覆盖请求路径。对应的Config配置包括template信息、根据请求路径的参数信息和template信息覆盖原先的请求路径。

  • SecureHeadersGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为SecureHeaders,作用是为请求信息添加一些安全相关的header。没有Config配置信息。

  • SetRequestHeaderGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为SetRequestHeader,作用是为Request请求修改Header内容。对应的Config配置内部维护name和value属性,用于表示Request Header中要修改的key和value。

  • SetResponseHeaderGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为SetResponseHeader,作用是为Response请求修改Header内容。对应的Config配置内部维护name和value属性,用于表示Response Header中要修改的key和value。

  • RewriteResponseHeaderGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为RewriteResponseHeader,作用是为Response请求修改Header内容。对应的Config配置内部维护regexp和 replacement属性,regexp表示匹配的正则表达式,replacement表示替换内容。跟其他修改Response的Filter相比,RewriteResponseHeaderGatewayFilterFactory基于正则完成。

  • SetStatusGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为SetStatus,作用是修改Response Status状态码,。对应的Config配置内部维护status属性,用于表示修改后的状态码。

  • SaveSessionGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为SaveSession,作用是基于Spring Web内的WebSession接口保存Session内容。没有Config配置信息。

  • StripPrefixGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为StripPrefix,作用是跳过请求部分的路径。对应的Config配置内部维护parts属性,用于表示跳过的路径个数。

  • RequestHeaderToRequestUriGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为RequestHeaderToRequestUri,作用是将请求路径修改成Request Header内的信息。对应的Config配置内部维护name属性,用于表示Request Header中的key。

  • RequestSizeGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为RequestSize,作用是用于阻止传递内容超过限制值的请求。对应的Config配置内部维护maxSize属性,用于表示请求内容的大小限制值,默认是5MB。

  • RequestHeaderSizeGatewayFilterFactoryRouteDefinitionRouteLocator中的gatewayFilterFactories属性对应的key为RequestHeaderSize,作用是用于阻止请求Header内容超过限制值的请求。对应的Config配置内部维护name属性,用于表示请求Header的大小限制值,默认是16kb。

网关内置的GlobalFilter

Spring Cloud Gateway提供了一些内置的GlobalFilter:

  • ForwardPathFilter:处理schema为forword的请求,会对请求的路径进行解析。配合ForwardRoutingFilter完成请求处理。

  • ForwardRoutingfilter:处理schema为forward的请求,配合ForwardPathFilter完成请求的转发。内部会根据DispatcherHandler处理请求。

  • GatewayMetricsFilter:基于MecroMeter完成Spring Cloud Gateway Metrics信息的统计。

  • LoadBalancerClientFilter:处理schema为lb的请求。基于Spring Cloud LoadBalancer和Spring Cloud服务注册/发现的编程模型完成服务名对应实例的查询。

  • NettyRoutingFilter:处理scheme为http或https的请求,内部使用Netty HttpClient客户端完成请求调用。

  • NettyWriteResponseFilter:通过Netty HttpClient写回Response信息到客户端。

  • ReactiveLoadBalancerClientFilter:基于Sentinel完成限流/降级。

  • WebClientHttpRoutingFilter:处理scheme为http或https到请求,内部使用Spring WebClient完成请求调用。默认情况下,使用NettyRoutingFilter,可通过相关配置修改为WebClientHttpRoutingFilter

  • WebClientWriteResponseFilter:通过Spring WebClient写回Response信息到客户端。

  • WebsocketRoutingFilter:代理WebSocket请求。