Spring-Cloud-Gateway源码系列学习 - 基础组件学习

Spring-Cloud-Gateway源码系列学习

版本 v2.2.6.RELEASE

Spring-Cloud-Gateay工作流程

Spring Cloud Gateway Diagram

img

基础组件学习

Route

Spring-Cloud-Gateway最基础组件

public class Route implements Ordered {

	private final String id;

	//路由目标uri,最终被转发的目的地
	private final URI uri;

	//序号,越小优先级越高,实现Ordered的getOrder方法返回order
	private final int order;

    //谓语,匹配Route的前置条件
	private final AsyncPredicate<ServerWebExchange> predicate;
	
    //过滤器列表,比如可以修改请求头等
	private final List<GatewayFilter> gatewayFilters;

    //
	private final Map<String, Object> metadata;
}
AsyncPredicate

异步谓词,java8函数式,可以理解Spring-Cloud-Gateway写的Java8 Predicate加强版,ServerWebExchangeUtils#toAsyncPredicate可以把一个Predicate转成AsyncPredicate

public interface AsyncPredicate<T> extends Function<T, Publisher<Boolean>> {

    /*
    * 与操作,具体实现逻辑在内部类AndAsyncPredicate.apply
    * Mono.from(left.apply(t)).flatMap(
	*				result -> !result ? Mono.just(false) : Mono.from(right.apply(t)))
    */
	default AsyncPredicate<T> and(AsyncPredicate<? super T> other) {
		return new AndAsyncPredicate<>(this, other);
	}

    /*
    * 取反操作,具体逻辑在内部类NegateAsyncPredicate的apply
    * Mono.from(predicate.apply(t)).map(b -> !b)
    */
	default AsyncPredicate<T> negate() {
		return new NegateAsyncPredicate<>(this);
	}

    /*
    * 或操作,具体逻辑在内部类OrAsyncPredicate的apply
    * Mono.from(left.apply(t)).flatMap(
	*				result -> result ? Mono.just(true) : Mono.from(right.apply(t)));
    */
	default AsyncPredicate<T> or(AsyncPredicate<? super T> other) {
		return new OrAsyncPredicate<>(this, other);
	}
    
	/*
    * Default操作,传入DefaultAsyncPredicate的是一个java8 Predicate,即GatewayPredicate
    * Mono.just(delegate.test(t));
    */
	static AsyncPredicate<ServerWebExchange> from(
			Predicate<? super ServerWebExchange> predicate) {
		return new DefaultAsyncPredicate<>(GatewayPredicate.wrapIfNeeded(predicate));
	}
}
GatewayFilter 与 GatewayFilterChain

拦截器,责任链设计模式

public interface GatewayFilter extends ShortcutConfigurable {

    String NAME_KEY = "name";
    String VALUE_KEY = "value";

    //当前拦截器处理
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}
public interface GatewayFilterChain {

	//调用GatewayFilterChain#filter传递到下个Filter处理
	Mono<Void> filter(ServerWebExchange exchange);

}

Spring-Cloud-Gateway配置元信息

GatewayProperties

“spring.cloud.gateway” 前缀的 properties 会绑定 到GatewayProperties

@ConfigurationProperties("spring.cloud.gateway")
@Validated
public class GatewayProperties {

	private final Log logger = LogFactory.getLog(getClass());

	//路由列表
	@NotNull
	@Valid
	private List<RouteDefinition> routes = new ArrayList<>();

	//默认拦截器,会作用于每个Route
	private List<FilterDefinition> defaultFilters = new ArrayList<>();

    //Http的text/event-stream与application/stream+json
	private List<MediaType> streamingMediaTypes = Arrays
			.asList(MediaType.TEXT_EVENT_STREAM, MediaType.APPLICATION_STREAM_JSON);
}
RouteDefinition

对Route的信息定义,最终会被RouteLocator解析成Route

@Validated
public class RouteDefinition {

	private String id;

    //PredicateDefinition类型的谓语列表
	@NotEmpty
	@Valid
	private List<PredicateDefinition> predicates = new ArrayList<>();

    //FilterDefinition类型的拦截器列表
	@Valid
	private List<FilterDefinition> filters = new ArrayList<>();

    //路由目标uri,最终被转发的目的地
	@NotNull
	private URI uri;

    //元数据
	private Map<String, Object> metadata = new HashMap<>();

    //序号
	private int order = 0;
}
PredicateDefinition

对配置predicate的信息定义,最终会被解析成AsyncPredicate或Predicate

/*
* 配置示例:
* spring:
*  cloud:
*   gateway:
*     routes:
*     - id: add_request_header_route
*       uri: http://example.org
*       order: 999
*       predicates:
*       - Path=/echo,/test
*/
@Validated
public class PredicateDefinition {

	//对应Path
	@NotNull
	private String name;

	//key是固定字符串 _genkey_ + 数组元素下标,value是/echo和/test
    //key是根据构造方法的NameUtils.generateName(i),而NameUtils.GENERATED_NAME_PREFIX="_genkey_"
	private Map<String, String> args = new LinkedHashMap<>();
}
FilterDefinition

对配置filters的信息定义,最终会被解析成GatewayFilter

/*
* 配置示例:
* spring:
*  cloud:
*   gateway:
*     routes:
*     - id: add_request_header_route
*       uri: http://example.org
*       filters:
*       - AddRequestHeader=X-Request-Foo, Bar
*/
@Validated
public class FilterDefinition {

	//对应AddRequestHeader
	@NotNull
	private String name;

	//key是固定字符串 _genkey_ + 数组元素下标,value是X-Request-Foo和Bar
	private Map<String, String> args = new LinkedHashMap<>();
}

Predicate进一步理解

RoutePredicateFactory

所有 predicate factory 的顶级接口,职责就是生产 Predicate

@FunctionalInterface
public interface RoutePredicateFactory<C> extends ShortcutConfigurable, Configurable<C> {

	/**
	 * Pattern key.
	 */
	String PATTERN_KEY = "pattern";

	//生成一个java8的Predicate
	default Predicate<ServerWebExchange> apply(Consumer<C> consumer) {
		C config = newConfig();
		consumer.accept(config);
		beforeApply(config);
		return apply(config);
	}

    //生产异步谓词AsyncPredicate,支持与、或、非操作
	default AsyncPredicate<ServerWebExchange> applyAsync(Consumer<C> consumer) {
		C config = newConfig();
		consumer.accept(config);
		beforeApply(config);
		return applyAsync(config);
	}

	default void beforeApply(C config) {
	}

	//由子类实现,RoutePredicateFactory有很多实现类,这也是它为什么可以支持Before/After某个时间进行判断的原因
	Predicate<ServerWebExchange> apply(C config);

    //生成并把java8的Predicate转成AsyncPredicate
	default AsyncPredicate<ServerWebExchange> applyAsync(C config) {
		return toAsyncPredicate(apply(config));
	}

}
RoutePredicateFactory的常用实现类
  • AfterRoutePredicateFactory:某个时间后的请求会匹配成功

  • BeforeRoutePredicateFactory:某个时间前的请求会匹配成功

  • BetweenRoutePredicateFactory:两个时间间的请求会匹配成功,开区间

  • CookieRoutePredicateFactory:根据Cookie进行匹配

  • HeaderRoutePredicateFactory:根据Http Header进行匹配

  • HostRoutePredicateFactory:根据Host进行匹配

  • MethodRoutePredicateFactory:根据Http请求方法进行匹配

  • PathRoutePredicateFactory:根据请求路径进行匹配

  • QueryRoutePredicateFactory:根据请求携带的参数进行匹配

  • RemoteAddrRoutePredicateFactory:根据ip进行匹配

//TODO配置示例

Filter进一步理解

GatewayFilterFactory

所有 filter factory 的顶级接口,职责就是生产 GatewayFilter

@FunctionalInterface
public interface GatewayFilterFactory<C> extends ShortcutConfigurable, Configurable<C> {

	/**
	 * Name key.
	 */
	String NAME_KEY = "name";

	/**
	 * Value key.
	 */
	String VALUE_KEY = "value";

	default GatewayFilter apply(String routeId, Consumer<C> consumer) {
		C config = newConfig();
		consumer.accept(config);
		return apply(routeId, config);
	}

	default GatewayFilter apply(Consumer<C> consumer) {
		C config = newConfig();
		consumer.accept(config);
        //调用子类实现
		return apply(config);
	}

    //子类实现
	GatewayFilter apply(C config);

	default GatewayFilter apply(String routeId, C config) {
		if (config instanceof HasRouteId) {
			HasRouteId hasRouteId = (HasRouteId) config;
			hasRouteId.setRouteId(routeId);
		}
        //调用子类实现
		return apply(config);
	}

}
GatewayFilterFactory常用实现类
  • AddRequestHeaderGatewayFilterFactory:为请求Header添加指定值

    spring:
      cloud:
        gateway:
          routes:
          - id: add_request_header_route
            uri: http://example.org
            filters:
            - AddRequestHeader=X-Request-Foo, Bar
    
  • RemoveRequestHeaderGatewayFilterFactory:为请求Header去掉指定值

    spring:
      cloud:
        gateway:
          routes:
          - id: removeresponseheader_route
            uri: http://example.org
            filters:
            - RemoveRequestHeader=X-Response-Foo
    
  • AddResponseHeaderGatewayFilterFactory:为响应Header添加指定值

    spring:
      cloud:
        gateway:
          routes:
          - id: removeresponseheader_route
            uri: http://example.org
            filters:
            - AddResponseHeader=X-Response-Foo
    
  • RemoveResponseHeaderGatewayFilterFactory:为响应Header去掉指定值

    spring:
      cloud:
        gateway:
          routes:
          - id: removeresponseheader_route
            uri: http://example.org
            filters:
            - RemoveResponseHeader=X-Response-Foo
    
  • SetResponseHeaderGatewayFilterFactory:对响应Header进行替换,没有则添加

    spring:
      cloud:
        gateway:
          routes:
          - id: setresponseheader_route
            uri: http://example.org
            filters:
            - SetResponseHeader=X-Response-Foo, Bar
    
  • RemoveNonProxyHeadersGatewayFilterFactory:移除请求 Proxy 相关的 Header的值,包括Connection、Keep-Alive、Proxy、Authenticate、Proxy-Authorization、TE、Trailer、Transfer-Encoding、Upgrade

    spring.cloud.gateway.filter.remove-non-proxy-headers.headers = Connection
    
  • SecureHeadersGatewayFilterFactory:添加响应 Secure 相关的 Header

    //Secure 相关的 Header 定义在 SecureHeadersGatewayFilterFactory 代码里
    public class SecureHeadersGatewayFilterFactory extends AbstractGatewayFilterFactory {
    
    	/**
    	 * Xss-Protection header name.
    	 */
    	public static final String X_XSS_PROTECTION_HEADER = "X-Xss-Protection";
    
    	/**
    	 * Strict transport security header name.
    	 */
    	public static final String STRICT_TRANSPORT_SECURITY_HEADER = "Strict-Transport-Security";
    
    	/**
    	 * Frame options header name.
    	 */
    	public static final String X_FRAME_OPTIONS_HEADER = "X-Frame-Options";
    
    	/**
    	 * Content-Type Options header name.
    	 */
    	public static final String X_CONTENT_TYPE_OPTIONS_HEADER = "X-Content-Type-Options";
    
    	/**
    	 * Referrer Policy header name.
    	 */
    	public static final String REFERRER_POLICY_HEADER = "Referrer-Policy";
    
    	/**
    	 * Content-Security Policy header name.
    	 */
    	public static final String CONTENT_SECURITY_POLICY_HEADER = "Content-Security-Policy";
    
    	/**
    	 * Download Options header name.
    	 */
    	public static final String X_DOWNLOAD_OPTIONS_HEADER = "X-Download-Options";
    
    	/**
    	 * Permitted Cross-Domain Policies header name.
    	 */
    	public static final String X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER = "X-Permitted-Cross-Domain-Policies";
    }
    //使用示例
    spring.cloud.gateway.filter.secure-headers=X-Xss-Protection
    
  • AddRequestParameterGatewayFilterFactory:为请求添加参数

    spring:
      cloud:
        gateway:
          routes:
          - id: add_request_parameter_route
            uri: http://example.org
            filters:
            - AddRequestParameter=foo, bar
    
  • RewritePathGatewayFilterFactory:根据配置的正则表达式 regexp ,使用配置的 replacement 重写请求 Path

    spring:
      cloud:
        gateway:
          routes:
          - id: rewritepath_route
            uri: http://example.org
            predicates:
            - Path=/foo/**
            filters:
            - RewritePath=/foo/(?<segment>.*), /$\{segment}
    
  • PrefixPathGatewayFilterFactory:在请求路径前加上PrefixPath,重写请求 Path

    spring:
      cloud:
        gateway:
          routes:
          - id: prefixpath_route
            uri: http://example.org
            filters:
            - PrefixPath=/mypath
    
  • SetPathGatewayFilterFactory:依然是重写请求 Path,/foo/bar -> /bar

    spring:
      cloud:
        gateway:
          routes:
          - id: setpath_route
            uri: http://example.org
            predicates:
            - Path=/foo/{segment}
            filters:
            - SetPath=/{segment}
    
  • SetStatusGatewayFilterFactory:设置响应Http Status,如下配置无论什么情况,响应的http状态码为401

    spring:
      cloud:
        gateway:
          routes:
          - id: setstatusstring_route
            uri: http://example.org
            filters:
            - SetStatus=BAD_REQUEST
          - id: setstatusint_route
            uri: http://example.org
            filters:
            - SetStatus=401
    
  • RedirectToGatewayFilterFactory:将响应重定向到指定 URL ,并设置响应状态码为指定 Status 。注意,Status 必须为 3XX 重定向状态码。

    spring:
      cloud:
        gateway:
          routes:
          - id: prefixpath_route
            uri: http://example.org
            filters:
            - RedirectTo=302, http://www.iocoder.cn
    
  • HystrixGatewayFilterFactory:熔断网关过滤器工厂,详细源码研究//TODO

    spring:
      cloud:
        gateway:
          routes:
          - id: default_path_to_httpbin
            uri: http://127.0.0.1:8081
            order: 10000
            predicates:
            - Path=/**
            filters:
            - Hystrix=myCommandName
    
  • RequestRateLimiterGatewayFilterFactory:请求限流网关过滤器工厂

    spring:
      cloud:
        gateway:
          routes:
          - id: default_path_to_httpbin
            uri: http://127.0.0.1:8081
            order: 10000
            predicates:
            - Path=/**
            filters:
            - RequestRateLimiter=10, 20, #{@principalNameKeyResolver}
    //- RequestRateLimiter=10, 20, #{@principalNameKeyResolver}
    // 第一个参数:令牌桶上限
    // 第二个参数:令牌桶填充平均速率,单位:秒
    // 第三个参数:限流键解析器 Bean 对象名字
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值