Gateway

概念

  • Route: Route the basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates and a collection of filters. A route is matched if aggregate predicate is true.react

    Route 是网关的基础元素,由 ID、目标URI、断言、过滤器 组成,请求到达网关时,由 Gateway Handler Mapping 经过断言进行路由匹配(Mapping),当断言为真时,匹配到路由。web

  • Predicate: This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This allows developers to match on anything from the HTTP request, such as headers or parameters.spring

    Predicate 属于Java8,我习惯称之为断言,或者条件。app

  • Filter: These are instances Spring Framework GatewayFilter constructed in with a specific factory. Here, requests and responses can be modified before or after sending the downstream request.cors

    Filter 过滤器。async

请求处理过程

Spring Cloud Gateway 基于 Spring WebFlux,和Spring Web MVC相似,每一个请求经过 HandlerMapping 打到具体的 Handler 上(Handler/Controller)。ide

public interface HandlerMapping {
	Mono<Object> getHandler(ServerWebExchange exchange);
}
public abstract class AbstractHandlerMapping extends ApplicationObjectSupport implements HandlerMapping, Ordered {

	@Override
	public Mono<Object> getHandler(ServerWebExchange exchange) {
	
	    // 获取handler,并校验cors,此处为伪代码
    	return getHandlerInternal(exchange).map(handler -> isCorsRequest)
	}

	protected abstract Mono<?> getHandlerInternal(ServerWebExchange exchange);
}
public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {

	private final FilteringWebHandler webHandler;

	private final RouteLocator routeLocator;
	
	@Override
	protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
        
        return lookupRoute(exchange)
				.flatMap((Function<Route, Mono<?>>) r -> {
				
				    // 网关的 Filter Chain
					return Mono.just(webHandler);
				})
	}
	
	// 获取并匹配路由
	protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
	    
	    return this.routeLocator.getRoutes()
				.filterWhen(route ->  {
				
				    // 经过 Predicate 匹配路由
					return route.getPredicate().apply(exchange);
				})
	}
}

AbstractHandlerMapping的实现类以下ui

一个web应用有多个handlerMapping,Spring WebFlux经过org.springframework.web.reactive.DispatcherHandler来分发请求到HandlerMapping,而后Mapping到handler上面。this

public class DispatcherHandler implements WebHandler, ApplicationContextAware {

	@Nullable
	private List<HandlerMapping> handlerMappings;
	
	@Override
	public Mono<Void> handle(ServerWebExchange exchange) {
	    
	    
		return Flux.fromIterable(this.handlerMappings)
				.concatMap(mapping -> mapping.getHandler(exchange))         // 遍历 handlerMappings#getHandler
				.next()
				.switchIfEmpty(Mono.error(HANDLER_NOT_FOUND_EXCEPTION))
				.flatMap(handler -> invokeHandler(exchange, handler))       // 调用 handler
				.flatMap(result -> handleResult(exchange, result));         // 处理结果
	}
}

获取路由过程

由上可见,经过 RouteLocator 获取 Route 时。spa

public interface RouteLocator {

	Flux<Route> getRoutes();
}

经过Debug,RoutePredicateHandlerMapping中routeLocator的实例是 CachingRouteLocator

public class CachingRouteLocator implements RouteLocator {

	private final RouteLocator delegate;

	private final Flux<Route> routes;
		
	private final Map<String, List> cache = new HashMap<>();

	@Override
	public Flux<Route> getRoutes() {
		return this.routes;
	}
}

RoutePredicateHandlerMapping.routeLocator的实例是CachingRouteLocator,网关启动后,第一次请求,因为没有cache,所以向delegate(代理)寻求routes。

这个代理的实例是 RouteDefinitionRouteLocator。

public class RouteDefinitionRouteLocator implements RouteLocator, BeanFactoryAware, ApplicationEventPublisherAware {

	private final RouteDefinitionLocator routeDefinitionLocator;

	@Override
	public Flux<Route> getRoutes() {
	
	    // 获取路由定义,并转换为路由
		return this.routeDefinitionLocator.getRouteDefinitions()
				.map(this::convertToRoute)
    }
    
    // RouteDefine -> Route
	private Route convertToRoute(RouteDefinition routeDefinition) {
	
    	AsyncPredicate<ServerWebExchange> predicate = combinePredicates(routeDefinition);
    	List<GatewayFilter> gatewayFilters = getFilters(routeDefinition);

        // Route 的 AsyncBuilder
		return Route.async(routeDefinition)
				.asyncPredicate(predicate)
				.replaceFilters(gatewayFilters)
				.build();
	}
}
public interface RouteDefinitionLocator {

	Flux<RouteDefinition> getRouteDefinitions();
}

相关文章
相关标签/搜索