Как построить высокопроизводительный шлюз на основе Spring WebFlux

Spring Cloud

Статус шлюзов с открытым исходным кодом:

В настоящее время шлюзы Java с открытым исходным кодом в основном состоят из zuul и SpringCloudGateway, но эти два шлюза все еще нуждаются в расширении в соответствии с потребностями их собственного бизнеса. Поэтому существует множество компаний и компаний по их вторичной разработке, конечно, некоторые компании выбирают разработку собственных шлюзов. Большинство из них можно сделать на основе нативной netty, но я лично считаю, что писать на основе нативной netty отнимает много времени и сложно, поэтому рекомендуется использовать Spring WebFlux (на основе разработки netty) в качестве адаптивного шлюза.

Как прокси-запросы на основе весны WebFlux:

Фактически, основная точка бытия ворота заключается в прокси-запросах. Если прокси запросить другие функции, просто, то, как прокси-запросы на основе WebFlux? Есть два основных API, которые необходимо расширить:

1.AbstractHandlerMapping

2.WebHandler

Ниже описано, как SpringCloudGateway расширяет эти два класса:

1.RoutePredicateHandlerMapping:

Этот класс в основном перехватывает запрос и передает его FilteringWebHandler для обработки.


private final FilteringWebHandler webHandler;

private final RouteLocator routeLocator;

@Override
protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
   if (this.managementPortType == DIFFERENT && this.managementPort != null
         && exchange.getRequest().getURI().getPort() == this.managementPort) {
      return Mono.empty();
   }
   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);//这里交给FilteringWebHandler处理
         }).switchIfEmpty(Mono.empty().then(Mono.fromRunnable(() -> {
            exchange.getAttributes().remove(GATEWAY_PREDICATE_ROUTE_ATTR);
            if (logger.isTraceEnabled()) {
               logger.trace("No RouteDefinition found for ["
                     + getExchangeDesc(exchange) + "]");
            }
         })));
}

2. Веб-обработчик фильтрации:

Этот класс обрабатывает определенные запросы и одновременно выполняет всю цепочку фильтров, и именно здесь использование выполнения фильтров расширяет возможности Spring CloudGateway.

@Override
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);
}

Наконец

Выше он показал, как SpringCloudGateway, как запросить прокси, поэтому, если вы хотите создать шлюзы, основываясь на основе SpringWebflux, могут достичь вышеупомянутой ссылки, этот шлюз поддерживает все регистрационные центры в SpringCloud, Dubbo, HTTP Service также трудно?