springcloud-gateway浅析

背景

  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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&一步

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值