背景
springcloud网关组件gateway学习继续,引用官网gateway工作原理图。
从gateway项目构建来看,其依赖webflux来构建的,那gateway组件的工作的开始,得从DispatcherHandler开始。
public Mono<Void> handle(ServerWebExchange exchange) {
if (this.handlerMappings == null) {
return createNotFoundError();
}
return Flux.fromIterable(this.handlerMappings)
.concatMap(mapping -> mapping.getHandler(exchange))
.next()
.switchIfEmpty(createNotFoundError())
.flatMap(handler -> invokeHandler(exchange, handler))
.flatMap(result -> handleResult(exchange, result));
}
可以看到DispatcherHandler分3步处理ServerWebExchange(响应式http请求和相应交互约定),1、通过HandlerMapping找到handler,2、执行handler,3、处理结果,这里spring提供一种模板的方式来扩展HandlerMapping,看AbstractHandlerMapping
public Mono<Object> getHandler(ServerWebExchange exchange) {
return getHandlerInternal(exchange).map(handler -> {
if (logger.isDebugEnabled()) {
logger.debug(exchange.getLogPrefix() + "Mapped to " + handler);
}
ServerHttpRequest request = exchange.getRequest();
if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(exchange) : null);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, exchange);
config = (config != null ? config.combine(handlerConfig) : handlerConfig);
if (!this.corsProcessor.process(config, exchange) || CorsUtils.isPreFlightRequest(request)) {
return REQUEST_HANDLED_HANDLER;
}
}
return handler;
});
}
这里RoutePredicateHandlerMapping来机会了,gateway扩展了AbstractHandlerMapping。
protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
exchange.getAttributes().put(GATEWAY_HANDLER_MAPPER_ATTR, getSimpleName());
return lookupRoute(exchange)
// .log("route-predicate-handler-mapping", Level.FINER) //name this
.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);
return Mono.just(webHandler);
})
}
从这里看RoutePredicateHandlerMapping找到个FilteringWebHandler,至此DispatcherHandler的第一步找handler完成了,找到个FilteringWebHandler,当然gateway找handler还是个具体的过程,将route放到exchange中,RouteLocator找route,下面就是执行handler了,SimpleHandlerAdapter。
public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
WebHandler webHandler = (WebHandler) handler;
Mono<Void> mono = webHandler.handle(exchange);
return mono.then(Mono.empty());
}
可以看到通过handler的适配器,让handler有了处理请求的能力(变成了WebHandler),实际上是第一步返回的FilteringWebHandler。
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);
}
可以看到spring提供了策略接口WebHandler,gateway通过FilteringWebHandler扩展了WebHandler,具体处理过程就是从exchange中拿出route,从route中拿出所有GatewayFilter,加上本来有的filter构造成GatewayFilterChain来过滤请求。当然这里会有非常多的filter,比如ReactiveLoadBalancerClientFilter这个filter就是整合负载均衡组件的filter,比如ribbon,让ribbon帮我们去找服务处理请求。
总结
看到这里gateway提供的组件也就RoutePredicateHandlerMapping、FilteringWebHandler、GatewayFiler,当然路由这里还包含Route、RouteLocater、RouteDefinition、RouteDefinitionLocator,但是路由只是为了拿GatewayFiler,那总体看来gateway就是像官网工作原理图一样,RoutePredicateHandlerMapping、FilteringWebHandler、GatewayFiler就可以工作了,仔细想来也就是webflux的一个扩展,后续继续学习Ribbon和Feign。