springcloud gateway核心源代码分析-30

源码入口:

springcloud-gateway-core.jar里面的spirng.factories文件里面的EnableAutoconfiguration对应的org.springframework.cloud.gateway.config.GatewayAutoConfiguration,\

    @Bean
    public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties, List<GatewayFilterFactory> GatewayFilters, List<RoutePredicateFactory> predicates, RouteDefinitionLocator routeDefinitionLocator, @Qualifier("webFluxConversionService") ConversionService conversionService) {
        return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, GatewayFilters, properties, conversionService);
    }

GatewayProperties,加载配置网关

@ConfigurationProperties("spring.cloud.gateway")@Validatedpublic class GatewayProperties {

查找匹配到的Route并进行匹配处理

    @Bean
    public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler, RouteLocator routeLocator, GlobalCorsProperties globalCorsProperties, Environment environment) {
        return new RoutePredicateHandlerMapping(webHandler, routeLocator, globalCorsProperties, environment);
    }

创建一个根据RouteDefinition转换的路由定位器

    @Bean
    public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties, List<GatewayFilterFactory> GatewayFilters, List<RoutePredicateFactory> predicates, RouteDefinitionLocator routeDefinitionLocator, @Qualifier("webFluxConversionService") ConversionService conversionService) {
        return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, GatewayFilters, properties, conversionService);
    }

DispatcherHandler

http请求->

webflux+reactor(可以理解为springmvc)请求的调度器,负责请求分发->

DispatcherHandler.handle(ServerWebExchange exchange)类似DispatcherHandler的处理逻辑,exchange就是request请求上下文的封装

    public Mono<Void> handle(ServerWebExchange exchange) {
        return this.handlerMappings == null ? Mono.error(HANDLER_NOT_FOUND_EXCEPTION) : Flux.fromIterable(this.handlerMappings).concatMap((mapping) -> {
            return mapping.getHandler(exchange);
        }).next().switchIfEmpty(Mono.error(HANDLER_NOT_FOUND_EXCEPTION)).flatMap((handler) -> {
            return this.invokeHandler(exchange, handler);
        }).flatMap((result) -> {
            return this.handleResult(exchange, result);
        });
    }

|

return mapping.getHandler(exchange);--------->

 public Mono<Object> getHandler(ServerWebExchange exchange) {
        //dk 
        return this.getHandlerInternal(exchange).map((handler) -> {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug(exchange.getLogPrefix() + "Mapped to " + handler);
            }

RoutePredicateHandlerMapping.getHandlerInternal------>

  protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
        if (this.managmentPort != null && exchange.getRequest().getURI().getPort() == this.managmentPort) {
            return Mono.empty();
        } else {
            exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_HANDLER_MAPPER_ATTR, this.getSimpleName());
            //dk 
            return this.lookupRoute(exchange).flatMap((r) -> {
                exchange.getAttributes().remove(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Mapping [" + this.getExchangeDesc(exchange) + "] to " + r);
                }
​

|

protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
        //dk 
        return this.routeLocator.getRoutes().concatMap((route) -> {
            return Mono.just(route).filterWhen((r) -> {
                exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR, r.getId());
                return (Publisher)r.getPredicate().apply(exchange);
            }).doOnError((e) -> {
                this.logger.error("Error applying predicate for route: " + route.getId(), e);
            }).onErrorResume((e) -> {
                return Mono.empty();

|

RouteDefinitionRouteLocator.getRoutes:返回通过谓词条件过滤的路由信息:

|

//dk 用stream流的方式将RuteDefinition转为Route
routeDefinitionLocator.getRouteDefinitions()

|

this::convertToRoute

从routeDefinition获取Predicates

private Route convertToRoute(RouteDefinition routeDefinition) {
        //dk 
        AsyncPredicate<ServerWebExchange> predicate = this.combinePredicates(routeDefinition);
        //dk 从routeDefinition获取filters
        List<GatewayFilter> gatewayFilters = this.getFilters(routeDefinition);
        return ((AsyncBuilder)Route.async(routeDefinition).asyncPredicate(predicate).replaceFilters(gatewayFilters)).build();
    }

从routeDefinition获取filters

List<GatewayFilter> gatewayFilters = this.getFilters(routeDefinition);

//dk 返回通过谓词条件过滤的路由信息 : Mono.just(route).filterWhen

//dk 通过RoutePredicateHandlerMapping找到 handler(FilteringWebHandler )

public Mono<Void> handle(ServerWebExchange exchange) {
        return this.handlerMappings == null ? Mono.error(HANDLER_NOT_FOUND_EXCEPTION) : Flux.fromIterable(this.handlerMappings).concatMap((mapping) -> {
            return mapping.getHandler(exchange);
        }).next().switchIfEmpty(Mono.error(HANDLER_NOT_FOUND_EXCEPTION)).flatMap((handler) -> {
            return this.invokeHandler(exchange, handler);
        }).flatMap((result) -> {
            return this.handleResult(exchange, result);
        });
    }

    public Mono<Void> handle(ServerWebExchange exchange) {
        return this.handlerMappings == null ? Mono.error(HANDLER_NOT_FOUND_EXCEPTION) : Flux.fromIterable(this.handlerMappings).concatMap((mapping) -> {
            return mapping.getHandler(exchange);
        }).next().switchIfEmpty(Mono.error(HANDLER_NOT_FOUND_EXCEPTION)).flatMap((handler) -> {
            //dk 
            return this.invokeHandler(exchange, handler);
        }).flatMap((result) -> {
            return this.handleResult(exchange, result);
        });
    }

    private Mono<HandlerResult> invokeHandler(ServerWebExchange exchange, Object handler) {
        if (this.handlerAdapters != null) {
            Iterator var3 = this.handlerAdapters.iterator();
​
            while(var3.hasNext()) {
                HandlerAdapter handlerAdapter = (HandlerAdapter)var3.next();
                if (handlerAdapter.supports(handler)) {
                    return handlerAdapter.handle(exchange, 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());
    }

FilteringWebHandler

public Mono<Void> handle(ServerWebExchange exchange) {
        //从上下文拿到route
        Route route = (Route)exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
        //dk 获取过滤器
        List<GatewayFilter> gatewayFilters = route.getFilters();
        //dk 把自己的过滤器和系统的过滤器放在一起
        List<GatewayFilter> combined = new ArrayList(this.globalFilters);
        combined.addAll(gatewayFilters);
        //dk 进行过滤器排序
        AnnotationAwareOrderComparator.sort(combined);
        if (logger.isDebugEnabled()) {
            logger.debug("Sorted gatewayFilterFactories: " + combined);
        }
​
        //dk 责任链模式,执行过滤器链
        return (new FilteringWebHandler.DefaultGatewayFilterChain(combined)).filter(exchange);
    }

第二部分执行ribbon路由

LoadBalancerClientFilter.filter

public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        URI url = (URI)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
        String schemePrefix = (String)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);
        if (url != null && ("lb".equals(url.getScheme()) || "lb".equals(schemePrefix))) {
            ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);
            log.trace("LoadBalancerClientFilter url before: " + url);
            //dk 负载均衡核心代码
            ServiceInstance instance = this.choose(exchange);
            if (instance == null) {
                String msg = "Unable to find instance for " + url.getHost();
                if (this.properties.isUse404()) {
                    throw new LoadBalancerClientFilter.FourOFourNotFoundException(msg);
                } else {
                    throw new NotFoundException(msg);
                }
            } else {
                URI uri = exchange.getRequest().getURI();
                String overrideScheme = instance.isSecure() ? "https" : "http";
                if (schemePrefix != null) {
                    overrideScheme = url.getScheme();
                }
​
                URI requestUrl = this.loadBalancer.reconstructURI(new LoadBalancerClientFilter.DelegatingServiceInstance(instance, overrideScheme), uri);
                log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
                exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);
                return chain.filter(exchange);
            }
        } else {
            return chain.filter(exchange);
        }
    }

RibbonLoadBalancerClient

   public ServiceInstance choose(String serviceId, Object hint) {
        //dk 核心
        Server server = this.getServer(this.getLoadBalancer(serviceId), hint);
        return server == null ? null : new RibbonLoadBalancerClient.RibbonServer(serviceId, server, this.isSecure(server, serviceId), this.serverIntrospector(serviceId).getMetadata(server));
    }

    protected Server getServer(ILoadBalancer loadBalancer, Object hint) {
        return loadBalancer == null ? null : loadBalancer.chooseServer(hint != null ? hint : "default");
    }

|

ZoneAwareLoadBalancer

 @Override
    public Server chooseServer(Object key) {
        if (!ENABLED.get() || getLoadBalancerStats().getAvailableZones().size() <= 1) {
            logger.debug("Zone aware logic disabled or there is only one zone");
            return super.chooseServer(key);
        }
        Server server = null;
        try {
            LoadBalancerStats lbStats = getLoadBalancerStats();
            Map<String, ZoneSnapshot> zoneSnapshot = ZoneAvoidanceRule.createSnapshot(lbStats);
            logger.debug("Zone snapshots: {}", zoneSnapshot);
            if (triggeringLoad == null) {
                triggeringLoad = DynamicPropertyFactory.getInstance().getDoubleProperty(
                        "ZoneAwareNIWSDiscoveryLoadBalancer." + this.getName() + ".triggeringLoadPerServerThreshold", 0.2d);
            }
​
            if (triggeringBlackoutPercentage == null) {
                triggeringBlackoutPercentage = DynamicPropertyFactory.getInstance().getDoubleProperty(
                        "ZoneAwareNIWSDiscoveryLoadBalancer." + this.getName() + ".avoidZoneWithBlackoutPercetage", 0.99999d);
            }
            Set<String> availableZones = ZoneAvoidanceRule.getAvailableZones(zoneSnapshot, triggeringLoad.get(), triggeringBlackoutPercentage.get());
            logger.debug("Available zones: {}", availableZones);
            if (availableZones != null &&  availableZones.size() < zoneSnapshot.keySet().size()) {
                String zone = ZoneAvoidanceRule.randomChooseZone(zoneSnapshot, availableZones);
                logger.debug("Zone chosen: {}", zone);
                if (zone != null) {
                    BaseLoadBalancer zoneLoadBalancer = getLoadBalancer(zone);
                    server = zoneLoadBalancer.chooseServer(key);
                }
            }
        } catch (Exception e) {
            logger.error("Error choosing server using zone aware logic for load balancer={}", name, e);
        }
        if (server != null) {
            return server;
        } else {
            logger.debug("Zone avoidance logic is not invoked.");
            return super.chooseServer(key);
        }
    }

最终跑到代理服务里面去

NettyRoutingFilter.filter
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值