zoukankan      html  css  js  c++  java
  • 003-spring cloud gateway-概述、Route模型、网关初始化配置过程、基本原理

    一、概述

      

      网关服务核心是将进入的请求正确合理的路由到下层具体的服务进行业务处理,由此可见网关服务的核心就是路由信息的构建。

      Spring Cloud Gateway旨在提供一种简单而有效的方式来路由到API,并为他们提供横切关注点,例如:安全性,监控/指标和弹性。

      Spring Cloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Netflix Zuul,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全、监控、埋点和限流等。

      Spring Cloud Gateway 的特征:

    • 基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
    • 动态路由
    • Predicates 和 Filters 作用于特定路由
    • 集成 Hystrix 断路器
    • 集成 Spring Cloud DiscoveryClient
    • 易于编写的 Predicates 和 Filters
    • 限流
    • 路径重写

    1.1、Route模型

    1、查看具体Route模型类

    源码:

    public class Route implements Ordered {
        private final String id;
        private final URI uri;
        private final int order;
        private final AsyncPredicate<ServerWebExchange> predicate;
        private final List<GatewayFilter> gatewayFilters;
    }

      一个Route路由的基本构建块:

    • id:路由ID编号,唯一。不写是UUID
    • uri:路由导向的目标URI,对应的具体业务服务的URL。http请求为lb://前缀 + 服务id;ws请求为lb:ws://前缀 + 服务id;表示将请求负载到哪一个服务上。当然也可以具体地址
    • order:顺序,当请求匹配多个路由时,使用顺序小的
    • predicate: 请求匹配路由的断言条件,如果聚合谓词为真,则匹配路由。Java 8 的函数, Spring Framework ServerWebExchange允许开发人员匹配HTTP请求中的任何内容,例如标头或参数。
    • gatewayFilters: 当前路由上存在的过滤器,用于对请求做拦截处理。使用特定工厂构建org.springframework.cloud.gateway.filter.GatewayFilter的实例。这里,可以在发送下游请求之前或之后修改请求和响应。

    2、Route模型是通过RouteDefinition(路由定义)模型构建的

    源码:

    @Validated
    public class RouteDefinition {
        @NotEmpty
        private String id = UUID.randomUUID().toString();
        @NotEmpty
        @Valid
        private List<PredicateDefinition> predicates = new ArrayList();
        @Valid
        private List<FilterDefinition> filters = new ArrayList();
        @NotNull
        private URI uri;
        private int order = 0;
    }
    RouteDefinition模型是对Route模型中route的定义以及描述,Spring-Cloud-Gateway最终会通过RouteDefinition来构建起Route实例信息。
    其中RouteDefinition代码包含两个数组分别是PredicateDefinition,FilterDefinition。

    3、 PredicateDefinition和FilterDefinition

    PredicateDefinition : 断言条件(谓语)定义,构建 Route 时,PredicateDefinition 转换成 Predicate
    FilterDefinition : 过滤条件的定义,构建Route 时,FilterDefinition 转换成 GatewayFilter

    PredicateDefinition源码:

    @Validated
    public class PredicateDefinition {
        @NotNull
        private String name;
        private Map<String, String> args = new LinkedHashMap();
    }
    • name:名称,Spring-Cloud-Gateway会根据name找到Predicate的构建工厂类
    • args:参数,构建Predicate的参数

    FilterDefinition源码:

    @Validated
    public class FilterDefinition {
        @NotNull
        private String name;
        private Map<String, String> args = new LinkedHashMap();
    }
    • name:名称,Spring-Cloud-Gateway会根据name找到GatewayFilter的构建工厂类
    • args:参数,构建GatewayFilter的参数

    综合上述,Spring-Cloud-Gateway构建路由的数据流向

    1.2、网关初始化过程

    Spring-Cloud项目使用EnableAutoConfiguration注解自动初始化配置信息,Spring-Cloud-Gateway下的spring.factories(在包spring-cloud-gateway-core)如下:
    # Auto Configure
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=
    org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration,
    org.springframework.cloud.gateway.config.GatewayAutoConfiguration,
    org.springframework.cloud.gateway.config.GatewayLoadBalancerClientAutoConfiguration,
    org.springframework.cloud.gateway.config.GatewayMetricsAutoConfiguration,
    org.springframework.cloud.gateway.config.GatewayRedisAutoConfiguration,
    org.springframework.cloud.gateway.discovery.GatewayDiscoveryClientAutoConfiguration

    附注:springboot常用的注解的含义

    执行顺序
    @AutoConfigureAfter:在指定的配置类初始化后再加载
    @AutoConfigureBefore:在指定的配置类初始化前加载
    @AutoConfigureOrder:数越小越先初始化
    
    条件配置
    @ConditionalOnClass : classpath中存在该类时起效
    @ConditionalOnMissingClass : classpath中不存在该类时起效
    @ConditionalOnBean : DI容器中存在该类型Bean时起效
    @ConditionalOnMissingBean : DI容器中不存在该类型Bean时起效
    @ConditionalOnSingleCandidate : DI容器中该类型Bean只有一个或@Primary的只有一个时起效
    @ConditionalOnExpression : SpEL表达式结果为true时
    @ConditionalOnProperty : 参数设置或者值一致时起效
    @ConditionalOnResource : 指定的文件存在时起效
    @ConditionalOnJndi : 指定的JNDI存在时起效
    @ConditionalOnJava : 指定的Java版本存在时起效
    @ConditionalOnWebApplication : Web应用环境下起效
    @ConditionalOnNotWebApplication : 非Web应用环境下起效

    配置文件分析

    1、GatewayClassPathWarningAutoConfiguration配置

      GatewayClassPathWarningAutoConfiguration配置用于检查项目是否正确导入 spring-boot-starter-webflux 依赖,而不是错误导入 spring-boot-starter-web 依赖,同时 GatewayClassPathWarningAutoConfiguration配置在EnableAutoConfiguration配置加载前加载。

    @Configuration
    //执行顺序注解
    //当前注解标识需要在GatewayAutoConfiguration前加载此配置
    @AutoConfigureBefore({GatewayAutoConfiguration.class})
    public class GatewayClassPathWarningAutoConfiguration {
        private static final Log log = LogFactory.getLog(GatewayClassPathWarningAutoConfiguration.class);
        private static final String BORDER = "
    
    **********************************************************
    
    ";
        public GatewayClassPathWarningAutoConfiguration() {}
    
        @Configuration
        //条件判断注解
        //classpath中不存在org.springframework.web.reactive.DispatcherHandler时起效,标识项目未导入了spring-boot-starter-webflux包
        @ConditionalOnMissingClass({"org.springframework.web.reactive.DispatcherHandler"})
        protected static class WebfluxMissingFromClasspathConfiguration {
            public WebfluxMissingFromClasspathConfiguration() {
                GatewayClassPathWarningAutoConfiguration.log.warn("
    
    **********************************************************
    Spring Webflux is missing from the classpath, which is required for Spring Cloud Gateway at this time. Please add spring-boot-starter-webflux dependency. ********************************************************** "); } } @Configuration //条件判断注解 //classpath中存在org.springframework.web.servlet.DispatcherServlet时起效,标识项目导入了spring-boot-starter-web包 @ConditionalOnClass(name = {"org.springframework.web.servlet.DispatcherServlet"}) protected static class SpringMvcFoundOnClasspathConfiguration { public SpringMvcFoundOnClasspathConfiguration() { GatewayClassPathWarningAutoConfiguration.log.warn(" **********************************************************
    Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway at this time. Please remove spring-boot-starter-web dependency. ********************************************************** "); } } }

    2、GatewayLoadBalancerClientAutoConfiguration

      GatewayLoadBalancerClientAutoConfiguration配置作用是初始化 LoadBalancerClientFilter 路由的负载均衡拦截器
    @Configuration
    //条件判断注解
    //classpath中存在LoadBalancerClient和RibbonAutoConfiguration和DispatcherHandler时此配置起效
    @ConditionalOnClass({LoadBalancerClient.class, RibbonAutoConfiguration.class, DispatcherHandler.class})
    //执行顺序注解
    @AutoConfigureAfter({RibbonAutoConfiguration.class})
    public class GatewayLoadBalancerClientAutoConfiguration {
        public GatewayLoadBalancerClientAutoConfiguration() {
        }
    
        // GlobalFilter beans
        @Bean
        //条件判断注解
        //DI容器中存在LoadBalancerClient类型Bean时起效
        @ConditionalOnBean({LoadBalancerClient.class})
        public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client) {
            return new LoadBalancerClientFilter(client);
        }
    }

    3、GatewayRedisAutoConfiguration

      GatewayRedisAutoConfiguration 配置作用是初始化初始化 RedisRateLimiter 限流功能的RequestRateLimiterGatewayFilterFactory 基于 RedisRateLimiter 实现网关的限流功能。

    4、GatewayAutoConfiguration

    GatewayAutoConfiguration配置是Spring Cloud Gateway 核心配置类,初始化如下 :

    • NettyConfiguration 底层通信netty配置
    • GlobalFilter (AdaptCachedBodyGlobalFilter,RouteToRequestUrlFilter,ForwardRoutingFilter,ForwardPathFilter,WebsocketRoutingFilter,WeightCalculatorWebFilter等)
    • FilteringWebHandler
    • GatewayProperties
    • PrefixPathGatewayFilterFactory
    • RoutePredicateFactory
    • RouteDefinitionLocator
    • RouteLocator
    • RoutePredicateHandlerMapping 查找匹配到 Route并进行处理
    • GatewayWebfluxEndpoint 管理网关的 HTTP API
    源码如下:
    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package org.springframework.cloud.gateway.config;
    
    import com.netflix.hystrix.HystrixObservableCommand;
    import io.netty.channel.ChannelOption;
    import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
    import java.security.cert.X509Certificate;
    import java.util.List;
    import java.util.function.Consumer;
    import java.util.function.Function;
    import java.util.function.Supplier;
    import org.springframework.beans.factory.ObjectProvider;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
    import org.springframework.boot.actuate.health.Health;
    import org.springframework.boot.autoconfigure.AutoConfigureAfter;
    import org.springframework.boot.autoconfigure.AutoConfigureBefore;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.boot.context.properties.PropertyMapper;
    import org.springframework.cloud.gateway.actuate.GatewayControllerEndpoint;
    import org.springframework.cloud.gateway.config.HttpClientProperties.Pool;
    import org.springframework.cloud.gateway.config.HttpClientProperties.Proxy;
    import org.springframework.cloud.gateway.config.HttpClientProperties.Ssl;
    import org.springframework.cloud.gateway.config.HttpClientProperties.Pool.PoolType;
    import org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter;
    import org.springframework.cloud.gateway.filter.ForwardPathFilter;
    import org.springframework.cloud.gateway.filter.ForwardRoutingFilter;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.cloud.gateway.filter.NettyRoutingFilter;
    import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
    import org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter;
    import org.springframework.cloud.gateway.filter.WebsocketRoutingFilter;
    import org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter;
    import org.springframework.cloud.gateway.filter.factory.AddRequestHeaderGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.AddResponseHeaderGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.HystrixGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.PrefixPathGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.PreserveHostHeaderGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.RedirectToGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.RemoveRequestHeaderGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.RemoveResponseHeaderGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.RequestHeaderToRequestUriGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.RetryGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.SaveSessionGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.SecureHeadersGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.SecureHeadersProperties;
    import org.springframework.cloud.gateway.filter.factory.SetPathGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.SetRequestHeaderGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.SetResponseHeaderGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.SetStatusGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.StripPrefixGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyRequestBodyGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyResponseBodyGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.headers.ForwardedHeadersFilter;
    import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter;
    import org.springframework.cloud.gateway.filter.headers.RemoveHopByHopHeadersFilter;
    import org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter;
    import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
    import org.springframework.cloud.gateway.filter.ratelimit.PrincipalNameKeyResolver;
    import org.springframework.cloud.gateway.filter.ratelimit.RateLimiter;
    import org.springframework.cloud.gateway.handler.FilteringWebHandler;
    import org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping;
    import org.springframework.cloud.gateway.handler.predicate.AfterRoutePredicateFactory;
    import org.springframework.cloud.gateway.handler.predicate.BeforeRoutePredicateFactory;
    import org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactory;
    import org.springframework.cloud.gateway.handler.predicate.CloudFoundryRouteServiceRoutePredicateFactory;
    import org.springframework.cloud.gateway.handler.predicate.CookieRoutePredicateFactory;
    import org.springframework.cloud.gateway.handler.predicate.HeaderRoutePredicateFactory;
    import org.springframework.cloud.gateway.handler.predicate.HostRoutePredicateFactory;
    import org.springframework.cloud.gateway.handler.predicate.MethodRoutePredicateFactory;
    import org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory;
    import org.springframework.cloud.gateway.handler.predicate.QueryRoutePredicateFactory;
    import org.springframework.cloud.gateway.handler.predicate.ReadBodyPredicateFactory;
    import org.springframework.cloud.gateway.handler.predicate.RemoteAddrRoutePredicateFactory;
    import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory;
    import org.springframework.cloud.gateway.handler.predicate.WeightRoutePredicateFactory;
    import org.springframework.cloud.gateway.route.CachingRouteLocator;
    import org.springframework.cloud.gateway.route.CompositeRouteDefinitionLocator;
    import org.springframework.cloud.gateway.route.CompositeRouteLocator;
    import org.springframework.cloud.gateway.route.InMemoryRouteDefinitionRepository;
    import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
    import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
    import org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator;
    import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
    import org.springframework.cloud.gateway.route.RouteLocator;
    import org.springframework.cloud.gateway.route.RouteRefreshListener;
    import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
    import org.springframework.context.ApplicationEventPublisher;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.DependsOn;
    import org.springframework.context.annotation.Primary;
    import org.springframework.http.codec.ServerCodecConfigurer;
    import org.springframework.util.StringUtils;
    import org.springframework.validation.Validator;
    import org.springframework.web.reactive.DispatcherHandler;
    import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient;
    import org.springframework.web.reactive.socket.client.WebSocketClient;
    import org.springframework.web.reactive.socket.server.WebSocketService;
    import org.springframework.web.reactive.socket.server.support.HandshakeWebSocketService;
    import reactor.core.publisher.Flux;
    import reactor.ipc.netty.http.client.HttpClient;
    import reactor.ipc.netty.http.client.HttpClientOptions.Builder;
    import reactor.ipc.netty.resources.PoolResources;
    import rx.RxReactiveStreams;
    
    @Configuration
    @ConditionalOnProperty(
        name = {"spring.cloud.gateway.enabled"},
        matchIfMissing = true
    )
    @EnableConfigurationProperties
    @AutoConfigureBefore({HttpHandlerAutoConfiguration.class})
    @AutoConfigureAfter({GatewayLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class})
    @ConditionalOnClass({DispatcherHandler.class})
    public class GatewayAutoConfiguration {
        public GatewayAutoConfiguration() {
        }
    
        @Bean
        public RouteLocatorBuilder routeLocatorBuilder(ConfigurableApplicationContext context) {
            return new RouteLocatorBuilder(context);
        }
    
        @Bean
        @ConditionalOnMissingBean
        public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(GatewayProperties properties) {
            return new PropertiesRouteDefinitionLocator(properties);
        }
    
        @Bean
        @ConditionalOnMissingBean({RouteDefinitionRepository.class})
        public InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository() {
            return new InMemoryRouteDefinitionRepository();
        }
    
        @Bean
        @Primary
        public RouteDefinitionLocator routeDefinitionLocator(List<RouteDefinitionLocator> routeDefinitionLocators) {
            return new CompositeRouteDefinitionLocator(Flux.fromIterable(routeDefinitionLocators));
        }
    
        @Bean
        public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties, List<GatewayFilterFactory> GatewayFilters, List<RoutePredicateFactory> predicates, RouteDefinitionLocator routeDefinitionLocator) {
            return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, GatewayFilters, properties);
        }
    
        @Bean
        @Primary
        public RouteLocator cachedCompositeRouteLocator(List<RouteLocator> routeLocators) {
            return new CachingRouteLocator(new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
        }
    
        @Bean
        public RouteRefreshListener routeRefreshListener(ApplicationEventPublisher publisher) {
            return new RouteRefreshListener(publisher);
        }
    
        @Bean
        public FilteringWebHandler filteringWebHandler(List<GlobalFilter> globalFilters) {
            return new FilteringWebHandler(globalFilters);
        }
    
        @Bean
        public GlobalCorsProperties globalCorsProperties() {
            return new GlobalCorsProperties();
        }
    
        @Bean
        public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler, RouteLocator routeLocator, GlobalCorsProperties globalCorsProperties) {
            return new RoutePredicateHandlerMapping(webHandler, routeLocator, globalCorsProperties);
        }
    
        @Bean
        public GatewayProperties gatewayProperties() {
            return new GatewayProperties();
        }
    
        @Bean
        public SecureHeadersProperties secureHeadersProperties() {
            return new SecureHeadersProperties();
        }
    
        @Bean
        @ConditionalOnProperty(
            name = {"spring.cloud.gateway.forwarded.enabled"},
            matchIfMissing = true
        )
        public ForwardedHeadersFilter forwardedHeadersFilter() {
            return new ForwardedHeadersFilter();
        }
    
        @Bean
        public RemoveHopByHopHeadersFilter removeHopByHopHeadersFilter() {
            return new RemoveHopByHopHeadersFilter();
        }
    
        @Bean
        @ConditionalOnProperty(
            name = {"spring.cloud.gateway.x-forwarded.enabled"},
            matchIfMissing = true
        )
        public XForwardedHeadersFilter xForwardedHeadersFilter() {
            return new XForwardedHeadersFilter();
        }
    
        @Bean
        public AdaptCachedBodyGlobalFilter adaptCachedBodyGlobalFilter() {
            return new AdaptCachedBodyGlobalFilter();
        }
    
        @Bean
        public RouteToRequestUrlFilter routeToRequestUrlFilter() {
            return new RouteToRequestUrlFilter();
        }
    
        @Bean
        @ConditionalOnBean({DispatcherHandler.class})
        public ForwardRoutingFilter forwardRoutingFilter(DispatcherHandler dispatcherHandler) {
            return new ForwardRoutingFilter(dispatcherHandler);
        }
    
        @Bean
        public ForwardPathFilter forwardPathFilter() {
            return new ForwardPathFilter();
        }
    
        @Bean
        public WebSocketService webSocketService() {
            return new HandshakeWebSocketService();
        }
    
        @Bean
        public WebsocketRoutingFilter websocketRoutingFilter(WebSocketClient webSocketClient, WebSocketService webSocketService, ObjectProvider<List<HttpHeadersFilter>> headersFilters) {
            return new WebsocketRoutingFilter(webSocketClient, webSocketService, headersFilters);
        }
    
        @Bean
        public WeightCalculatorWebFilter weightCalculatorWebFilter(Validator validator) {
            return new WeightCalculatorWebFilter(validator);
        }
    
        @Bean
        public AfterRoutePredicateFactory afterRoutePredicateFactory() {
            return new AfterRoutePredicateFactory();
        }
    
        @Bean
        public BeforeRoutePredicateFactory beforeRoutePredicateFactory() {
            return new BeforeRoutePredicateFactory();
        }
    
        @Bean
        public BetweenRoutePredicateFactory betweenRoutePredicateFactory() {
            return new BetweenRoutePredicateFactory();
        }
    
        @Bean
        public CookieRoutePredicateFactory cookieRoutePredicateFactory() {
            return new CookieRoutePredicateFactory();
        }
    
        @Bean
        public HeaderRoutePredicateFactory headerRoutePredicateFactory() {
            return new HeaderRoutePredicateFactory();
        }
    
        @Bean
        public HostRoutePredicateFactory hostRoutePredicateFactory() {
            return new HostRoutePredicateFactory();
        }
    
        @Bean
        public MethodRoutePredicateFactory methodRoutePredicateFactory() {
            return new MethodRoutePredicateFactory();
        }
    
        @Bean
        public PathRoutePredicateFactory pathRoutePredicateFactory() {
            return new PathRoutePredicateFactory();
        }
    
        @Bean
        public QueryRoutePredicateFactory queryRoutePredicateFactory() {
            return new QueryRoutePredicateFactory();
        }
    
        @Bean
        public ReadBodyPredicateFactory readBodyPredicateFactory(ServerCodecConfigurer codecConfigurer) {
            return new ReadBodyPredicateFactory(codecConfigurer);
        }
    
        @Bean
        public RemoteAddrRoutePredicateFactory remoteAddrRoutePredicateFactory() {
            return new RemoteAddrRoutePredicateFactory();
        }
    
        @Bean
        @DependsOn({"weightCalculatorWebFilter"})
        public WeightRoutePredicateFactory weightRoutePredicateFactory() {
            return new WeightRoutePredicateFactory();
        }
    
        @Bean
        public CloudFoundryRouteServiceRoutePredicateFactory cloudFoundryRouteServiceRoutePredicateFactory() {
            return new CloudFoundryRouteServiceRoutePredicateFactory();
        }
    
        @Bean
        public AddRequestHeaderGatewayFilterFactory addRequestHeaderGatewayFilterFactory() {
            return new AddRequestHeaderGatewayFilterFactory();
        }
    
        @Bean
        public AddRequestParameterGatewayFilterFactory addRequestParameterGatewayFilterFactory() {
            return new AddRequestParameterGatewayFilterFactory();
        }
    
        @Bean
        public AddResponseHeaderGatewayFilterFactory addResponseHeaderGatewayFilterFactory() {
            return new AddResponseHeaderGatewayFilterFactory();
        }
    
        @Bean
        public ModifyRequestBodyGatewayFilterFactory modifyRequestBodyGatewayFilterFactory(ServerCodecConfigurer codecConfigurer) {
            return new ModifyRequestBodyGatewayFilterFactory(codecConfigurer);
        }
    
        @Bean
        public ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory(ServerCodecConfigurer codecConfigurer) {
            return new ModifyResponseBodyGatewayFilterFactory(codecConfigurer);
        }
    
        @Bean
        public PrefixPathGatewayFilterFactory prefixPathGatewayFilterFactory() {
            return new PrefixPathGatewayFilterFactory();
        }
    
        @Bean
        public PreserveHostHeaderGatewayFilterFactory preserveHostHeaderGatewayFilterFactory() {
            return new PreserveHostHeaderGatewayFilterFactory();
        }
    
        @Bean
        public RedirectToGatewayFilterFactory redirectToGatewayFilterFactory() {
            return new RedirectToGatewayFilterFactory();
        }
    
        @Bean
        public RemoveRequestHeaderGatewayFilterFactory removeRequestHeaderGatewayFilterFactory() {
            return new RemoveRequestHeaderGatewayFilterFactory();
        }
    
        @Bean
        public RemoveResponseHeaderGatewayFilterFactory removeResponseHeaderGatewayFilterFactory() {
            return new RemoveResponseHeaderGatewayFilterFactory();
        }
    
        @Bean(
            name = {"principalNameKeyResolver"}
        )
        @ConditionalOnBean({RateLimiter.class})
        public PrincipalNameKeyResolver principalNameKeyResolver() {
            return new PrincipalNameKeyResolver();
        }
    
        @Bean
        @ConditionalOnBean({RateLimiter.class, KeyResolver.class})
        public RequestRateLimiterGatewayFilterFactory requestRateLimiterGatewayFilterFactory(RateLimiter rateLimiter, PrincipalNameKeyResolver resolver) {
            return new RequestRateLimiterGatewayFilterFactory(rateLimiter, resolver);
        }
    
        @Bean
        public RewritePathGatewayFilterFactory rewritePathGatewayFilterFactory() {
            return new RewritePathGatewayFilterFactory();
        }
    
        @Bean
        public RetryGatewayFilterFactory retryGatewayFilterFactory() {
            return new RetryGatewayFilterFactory();
        }
    
        @Bean
        public SetPathGatewayFilterFactory setPathGatewayFilterFactory() {
            return new SetPathGatewayFilterFactory();
        }
    
        @Bean
        public SecureHeadersGatewayFilterFactory secureHeadersGatewayFilterFactory(SecureHeadersProperties properties) {
            return new SecureHeadersGatewayFilterFactory(properties);
        }
    
        @Bean
        public SetRequestHeaderGatewayFilterFactory setRequestHeaderGatewayFilterFactory() {
            return new SetRequestHeaderGatewayFilterFactory();
        }
    
        @Bean
        public SetResponseHeaderGatewayFilterFactory setResponseHeaderGatewayFilterFactory() {
            return new SetResponseHeaderGatewayFilterFactory();
        }
    
        @Bean
        public SetStatusGatewayFilterFactory setStatusGatewayFilterFactory() {
            return new SetStatusGatewayFilterFactory();
        }
    
        @Bean
        public SaveSessionGatewayFilterFactory saveSessionGatewayFilterFactory() {
            return new SaveSessionGatewayFilterFactory();
        }
    
        @Bean
        public StripPrefixGatewayFilterFactory stripPrefixGatewayFilterFactory() {
            return new StripPrefixGatewayFilterFactory();
        }
    
        @Bean
        public RequestHeaderToRequestUriGatewayFilterFactory requestHeaderToRequestUriGatewayFilterFactory() {
            return new RequestHeaderToRequestUriGatewayFilterFactory();
        }
    
        @Configuration
        @ConditionalOnClass({Health.class})
        protected static class GatewayActuatorConfiguration {
            protected GatewayActuatorConfiguration() {
            }
    
            @Bean
            @ConditionalOnEnabledEndpoint
            public GatewayControllerEndpoint gatewayControllerEndpoint(RouteDefinitionLocator routeDefinitionLocator, List<GlobalFilter> globalFilters, List<GatewayFilterFactory> GatewayFilters, RouteDefinitionWriter routeDefinitionWriter, RouteLocator routeLocator) {
                return new GatewayControllerEndpoint(routeDefinitionLocator, globalFilters, GatewayFilters, routeDefinitionWriter, routeLocator);
            }
        }
    
        @Configuration
        @ConditionalOnClass({HystrixObservableCommand.class, RxReactiveStreams.class})
        protected static class HystrixConfiguration {
            protected HystrixConfiguration() {
            }
    
            @Bean
            public HystrixGatewayFilterFactory hystrixGatewayFilterFactory(DispatcherHandler dispatcherHandler) {
                return new HystrixGatewayFilterFactory(dispatcherHandler);
            }
        }
    
        @Configuration
        @ConditionalOnClass({HttpClient.class})
        protected static class NettyConfiguration {
            protected NettyConfiguration() {
            }
    
            @Bean
            @ConditionalOnMissingBean
            public HttpClient httpClient(@Qualifier("nettyClientOptions") Consumer<? super Builder> options) {
                return HttpClient.create(options);
            }
    
            @Bean
            public Consumer<? super Builder> nettyClientOptions(HttpClientProperties properties) {
                return (opts) -> {
                    if (properties.getConnectTimeout() != null) {
                        opts.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, properties.getConnectTimeout());
                    }
    
                    Ssl ssl = properties.getSsl();
                    X509Certificate[] trustedX509Certificates = ssl.getTrustedX509CertificatesForTrustManager();
                    if (trustedX509Certificates.length > 0) {
                        opts.sslSupport((sslContextBuilder) -> {
                            sslContextBuilder.trustManager(trustedX509Certificates);
                        });
                    } else if (ssl.isUseInsecureTrustManager()) {
                        opts.sslSupport((sslContextBuilder) -> {
                            sslContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);
                        });
                    }
    
                    Pool pool = properties.getPool();
                    if (pool.getType() == PoolType.DISABLED) {
                        opts.disablePool();
                    } else {
                        PoolResources poolResources;
                        if (pool.getType() == PoolType.FIXED) {
                            poolResources = PoolResources.fixed(pool.getName(), pool.getMaxConnections(), pool.getAcquireTimeout());
                            opts.poolResources(poolResources);
                        } else {
                            poolResources = PoolResources.elastic(pool.getName());
                            opts.poolResources(poolResources);
                        }
                    }
    
                    Proxy proxy = properties.getProxy();
                    if (StringUtils.hasText(proxy.getHost())) {
                        opts.proxy((typeSpec) -> {
                            reactor.ipc.netty.options.ClientProxyOptions.Builder builder = typeSpec.type(reactor.ipc.netty.options.ClientProxyOptions.Proxy.HTTP).host(proxy.getHost());
                            PropertyMapper map = PropertyMapper.get();
                            proxy.getClass();
                            map.from(proxy::getPort).whenNonNull().to(builder::port);
                            proxy.getClass();
                            map.from(proxy::getUsername).whenHasText().to(builder::username);
                            proxy.getClass();
                            map.from(proxy::getPassword).whenHasText().to((password) -> {
                                builder.password((s) -> {
                                    return password;
                                });
                            });
                            proxy.getClass();
                            map.from(proxy::getNonProxyHostsPattern).whenHasText().to(builder::nonProxyHosts);
                            return builder;
                        });
                    }
    
                };
            }
    
            @Bean
            public HttpClientProperties httpClientProperties() {
                return new HttpClientProperties();
            }
    
            @Bean
            public NettyRoutingFilter routingFilter(HttpClient httpClient, ObjectProvider<List<HttpHeadersFilter>> headersFilters, HttpClientProperties properties) {
                return new NettyRoutingFilter(httpClient, headersFilters, properties);
            }
    
            @Bean
            public NettyWriteResponseFilter nettyWriteResponseFilter(GatewayProperties properties) {
                return new NettyWriteResponseFilter(properties.getStreamingMediaTypes());
            }
    
            @Bean
            public ReactorNettyWebSocketClient reactorNettyWebSocketClient(@Qualifier("nettyClientOptions") Consumer<? super Builder> options) {
                return new ReactorNettyWebSocketClient(options);
            }
        }
    }
    View Code

    5、GatewayDiscoveryClientAutoConfiguration

      GatewayDiscoveryClientAutoConfiguration配置的作用是初始化配置路由中的注册发现服务信息
    源码信息
    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package org.springframework.cloud.gateway.discovery;
    
    import java.util.ArrayList;
    import java.util.List;
    import org.springframework.boot.autoconfigure.AutoConfigureAfter;
    import org.springframework.boot.autoconfigure.AutoConfigureBefore;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.cloud.client.discovery.DiscoveryClient;
    import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration;
    import org.springframework.cloud.gateway.config.GatewayAutoConfiguration;
    import org.springframework.cloud.gateway.filter.FilterDefinition;
    import org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory;
    import org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory;
    import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
    import org.springframework.cloud.gateway.support.NameUtils;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.reactive.DispatcherHandler;
    
    @Configuration
    @ConditionalOnProperty(
        name = {"spring.cloud.gateway.enabled"},
        matchIfMissing = true
    )
    @AutoConfigureBefore({GatewayAutoConfiguration.class})
    @AutoConfigureAfter({CompositeDiscoveryClientAutoConfiguration.class})
    @ConditionalOnClass({DispatcherHandler.class, DiscoveryClient.class})
    @EnableConfigurationProperties
    public class GatewayDiscoveryClientAutoConfiguration {
        public GatewayDiscoveryClientAutoConfiguration() {
        }
    
        @Bean
        @ConditionalOnBean({DiscoveryClient.class})
        @ConditionalOnProperty(
            name = {"spring.cloud.gateway.discovery.locator.enabled"}
        )
        public DiscoveryClientRouteDefinitionLocator discoveryClientRouteDefinitionLocator(DiscoveryClient discoveryClient, DiscoveryLocatorProperties properties) {
            return new DiscoveryClientRouteDefinitionLocator(discoveryClient, properties);
        }
    
        @Bean
        public DiscoveryLocatorProperties discoveryLocatorProperties() {
            DiscoveryLocatorProperties properties = new DiscoveryLocatorProperties();
            properties.setPredicates(initPredicates());
            properties.setFilters(initFilters());
            return properties;
        }
    
        public static List<PredicateDefinition> initPredicates() {
            ArrayList<PredicateDefinition> definitions = new ArrayList();
            PredicateDefinition predicate = new PredicateDefinition();
            predicate.setName(NameUtils.normalizeRoutePredicateName(PathRoutePredicateFactory.class));
            predicate.addArg("pattern", "'/'+serviceId+'/**'");
            definitions.add(predicate);
            return definitions;
        }
    
        public static List<FilterDefinition> initFilters() {
            ArrayList<FilterDefinition> definitions = new ArrayList();
            FilterDefinition filter = new FilterDefinition();
            filter.setName(NameUtils.normalizeFilterFactoryName(RewritePathGatewayFilterFactory.class));
            String regex = "'/' + serviceId + '/(?<remaining>.*)'";
            String replacement = "'/${remaining}'";
            filter.addArg("regexp", regex);
            filter.addArg("replacement", replacement);
            definitions.add(filter);
            return definitions;
        }
    }
    View Code

    二、使用

    2.1、pom引用

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>

    关闭:spring.cloud.gateway.enabled=false

    注意:Spring Cloud Gateway需要Spring Boot和Spring Webflux提供的Netty运行时。它不能在传统的Servlet容器中工作或构建为WAR。

     

     

  • 相关阅读:
    JDBC 复习4 批量执行SQL
    JDBC 复习3 存取Oracle大数据 clob blob
    Oracle复习
    Linux命令(1)grep
    JDBC 复习2 存取mysql 大数据
    JDBC 复习1 DBUtil
    php 环境搭建问题
    Windows 批处理 bat 开启 WiFi 菜单选项 设置ID PWD
    Bat 批处理启动和停止Oracle 服务
    docker 学习1 WSL docker ,Windows docker
  • 原文地址:https://www.cnblogs.com/bjlhx/p/9581655.html
Copyright © 2011-2022 走看看