Spring.Cloud Gateway——架構分析

Spring WebFlux架構

Spring Cloud Gateway是在Spring WebFlux基礎上構造的新一代網關係統。Spring WebFlux和Spring MVC架構和API上幾乎完全一致,只不過Spring WebFlux底層使用的是響應式接口,Spring MVC是構建在Servlet之上的阻塞式編程架構。這裏的阻塞式和非阻塞式不僅是我們常說的Web服務器I/O,Spring WebFlux構建在Reactor模型之上,Reactor是一種全域的響應式編程模型。

在這裏插入圖片描述
以上是Spring WebFlux和Spring MVC架構的官方對比圖,兩者都採用前端調度器模式(Dispatcher)實現,其他像關鍵部件也十分相似。關於兩者的選型官方也給出了權威的說明:Web on Reactive Stack

Spring Cloud Gateway架構

Spring Cloud Gateway是構建在Spring WebFlux之上,Spring WebFlux已經提供了網絡服務能力,而且提供了很好的封裝。所以Spring Cloud Gateway只需要實現Spring WebFlux擴展所需的組件,並且封裝自身所需的功能就可以了。Spring Cloud Gateway的整體架構如下所示:
在這裏插入圖片描述
藉助Spring WebFlux的網絡服務能力,Spring Cloud Gateway僅需實現自定義的HandlerMapping、WebHandler兩個關鍵組件即可完成Spring WebFlux的擴展。除此之外,Spring Cloud Gateway只需要關注自身需要的路由功能,以及其他API網關通用能力。

RouteLocator負責路由的初始化和路由的選擇,HandlerMapping在處理請求時調用RouteLocator獲取處理此次請求的Route,處理過程是逐個調用所有Route的Predicates判斷本次請求是否由自己處理。

WebHandler取出HandlerMapping階段匹配的Route所有的Filters,拼裝上全局Filters,構建過濾器鏈。濾器鏈中的過濾器完成請求處理、解析、重寫、負載均衡等操作,最後執行過濾器ProxyFilter完成請求的轉發。

HandlerMapping分析

HandlerMapping的實現類是RoutePredicateHandlerMapping,其中關鍵方式是protected Mono<?> getHandlerInternal(ServerWebExchange exchange),其主要功能是lookupRoute

	protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
			   //獲取所有路由
		return this.routeLocator.getRoutes()
			   //過濾可用路由
				.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()))
				//只取出命中的所有Route中的第一個
				.next()
				//驗證路由可用,validateRoute是一個空方法,默認是不做處理
				.map(route -> {
					if (logger.isDebugEnabled()) {
						logger.debug("Route matched: " + route.getId());
					}
					validateRoute(route, exchange);
					return route;
				});
	}

WebHandler分析

Spring Cloud Gateway的WebHandler實現是FilteringWebHandler,其中關鍵方式是handle

	public Mono<Void> handle(ServerWebExchange exchange) {
		//取出RoutePredicateHandlerMapping命中的Route
		Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
		List<GatewayFilter> gatewayFilters = route.getFilters();

		//拼接全局Filters和Route自己的Filters,並且按照Ordered值排序
		List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
		combined.addAll(gatewayFilters);
		AnnotationAwareOrderComparator.sort(combined);

		if (logger.isDebugEnabled()) {
			logger.debug("Sorted gatewayFilterFactories: " + combined);
		}
		
		//組裝過濾器鏈,並且觸發鏈式過濾
		return new DefaultGatewayFilterChain(combined).filter(exchange);
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章