`
wx1568905209
  • 浏览: 25152 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

spring cloud gateway-过滤器

 
阅读更多

一、概述

  在Spring-Cloud-Gateway之请求处理流程中最终网关是将请求交给过滤器链表进行处理。

  核心接口:GatewayFilter,GlobalFilter,GatewayFilterChain。

查看整体类图

  

二、网关过滤器作用

  

  当使用微服务构建整个 API 服务时,一般有许多不同的应用在运行,如上图所示的mst-user-servicemst-good-servicemst-order-service,这些服务都需要对客户端的请求的进行 Authentication。最简单粗暴的方法就是像上图一样,为每个微服务应用都实现一套用于校验的过滤器或拦截器。

  通过前置的网关服务来完成这些非业务性质的校验。

  

三、Filter 的生命周期

  Spring Cloud Gateway 的 Filter 的生命周期有两个:“pre” 和 “post”。

  

  “pre”和 “post” 分别会在请求被执行前调用和被执行后调用,和 Zuul Filter 或 Spring Interceptor 中相关生命周期类似,但在形式上有些不一样。

  Zuul 的 Filter 是通过filterType()方法来指定,一个 Filter 只能对应一种类型,要么是 “pre” 要么是“post”。Spring Interceptor 是通过重写HandlerInterceptor中的三个方法来实现的。而 Spring Cloud Gateway 基于 Project Reactor 和 WebFlux,采用响应式编程风格,打开它的 Filter 的接口GatewayFilter你会发现它只有一个方法filter

四、核心接口解读

4.1、GatewayFilterChain--网关过滤链表

复制代码

/**
 * 网关过滤链表接口
 * 用于过滤器的链式调用
 */
public interface GatewayFilterChain {

    /**
     *  链表启动调用入口方法*/
    Mono<Void> filter(ServerWebExchange exchange);

}

复制代码

默认实现

复制代码

  /**
     * 网关过滤的链表,用于过滤器的链式调用
     * 过滤器链表接口的默认实现,
     * 包含2个构建函数:
     *  1.集合参数构建用于初始化吧构建链表
     *  2. index,parent参数用于构建当前执行过滤对应的下次执行的链表 
     */
    private static class DefaultGatewayFilterChain implements GatewayFilterChain {

        /**
         * 当前过滤执行过滤器在集合中索引
         */
        private final int index;
        /**
         * 过滤器集合
         */
        private final List<GatewayFilter> filters;

        public DefaultGatewayFilterChain(List<GatewayFilter> filters) {
            this.filters = filters;
            this.index = 0;
        }

        /**
         * 构建
         * @param parent 上一个执行过滤器对应的FilterChain
         * @param index  当前要执行过滤器的索引
         */
        private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {
            this.filters = parent.getFilters();
            this.index = index;
        }

        public List<GatewayFilter> getFilters() {
            return filters;
        }

        /**
         * @param exchange the current server exchange
         * @return
         */
        @Override
        public Mono<Void> filter(ServerWebExchange exchange) {
            return Mono.defer(() -> {
                if (this.index < filters.size()) {
                    //获取当前索引的过滤器
                    GatewayFilter filter = filters.get(this.index);
                    //构建当前索引的下一个过滤器的FilterChain
                    DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1);
                    //调用过滤器的filter方法执行过滤器
                    return filter.filter(exchange, chain);
                } else {
                    //当前索引大于等于过滤集合大小,标识所有链表都已执行完毕,返回空
                    return Mono.empty(); // complete
                }
            });
        }
    }

复制代码

过滤器的GatewayFilterChain 执行顺序

  1. 通过GatewayFilter集合构建顶层的GatewayFilterChain
  2. 调用顶层GatewayFilterChain,获取第一个Filter,并创建下一个Filter索引对应的GatewayFilterChain
  3. 调用filter的filter方法执行当前filter,并将下次要执行的filter对应GatewayFilterChain传入。

4.2、GatewayFilter--网关路由过滤器

复制代码

/**
 * 网关路由过滤器,
 * Contract for interception-style, chained processing of Web requests that may
 * be used to implement cross-cutting, application-agnostic requirements such
 * as security, timeouts, and others. Specific to a Gateway
 *
 */
public interface GatewayFilter extends ShortcutConfigurable {

    String NAME_KEY = "name";
    String VALUE_KEY = "value";

    /**
     *  过滤器执行方法
     * Process the Web request and (optionally) delegate to the next
     * {@code WebFilter} through the given {@link GatewayFilterChain}.
     * @param exchange the current server exchange
     * @param chain provides a way to delegate to the next filter
     * @return {@code Mono<Void>} to indicate when request processing is complete
     */
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);

}

复制代码

网关过滤器接口,有且只有一个方法filter,执行当前过滤器,并在此方法中决定过滤器链表是否继续往下执行。

1️⃣、OrderedGatewayFilter--排序

复制代码

/**
 * 排序的网关路由过滤器,用于包装真实的网关过滤器,已达到过滤器可排序
 */
public class OrderedGatewayFilter implements GatewayFilter, Ordered {

    //目标过滤器
    private final GatewayFilter delegate;
    //排序字段
    private final int order;

    public OrderedGatewayFilter(GatewayFilter delegate, int order) {
        this.delegate = delegate;
        this.order = order;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return this.delegate.filter(exchange, chain);
    }
}

复制代码

OrderedGatewayFilter实现类主要目的是为了将目标过滤器包装成可排序的对象类型。是目标过滤器的包装类

2️⃣、GatewayFilterAdapter

复制代码

  /**
     * 全局过滤器的包装类,将全局路由包装成统一的网关过滤器
     */
    private static class GatewayFilterAdapter implements GatewayFilter {

        /**
         * 全局过滤器
         */
        private final GlobalFilter delegate;

        public GatewayFilterAdapter(GlobalFilter delegate) {
            this.delegate = delegate;
        }

        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            return this.delegate.filter(exchange, chain);
        }
    }

复制代码

GatewayFilterAdapter实现类主要目的是为了将GlobalFilter过滤器包装成GatewayFilter类型的对应。是GlobalFilter过滤器的包装类

4.3、GlobalFilter

  

  GlobalFilter 为请求业务以及路由的URI转换为真实业务服务的请求地址的核心过滤器,不需要配置,模式系统初始化时加载,并作用在每个路由上

1️⃣、初始化加载,通过GatewayAutoConfiguration自动创建

复制代码

//GatewayAutoConfiguration 类
        /**
         * 全局过滤器,用户通过HttpClient转发请求
         */
        @Bean
        public NettyRoutingFilter routingFilter(HttpClient httpClient,
                                                ObjectProvider<List<HttpHeadersFilter>> headersFilters) {
            return new NettyRoutingFilter(httpClient, headersFilters);
        }

        /**
         * 全局的过滤器,用户将HttpClient客户端转发请求的响应写入到原始的请求响应中
         */
        @Bean
        public NettyWriteResponseFilter nettyWriteResponseFilter(GatewayProperties properties) {
            return new NettyWriteResponseFilter(properties.getStreamingMediaTypes());
        }
        
//GatewayLoadBalancerClientAutoConfiguration 类
    /**
     * 全局过滤器,用于在通过负载均衡客户端选择服务实例信息
     */
    @Bean
    @ConditionalOnBean(LoadBalancerClient.class)
    public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client) {
        return new LoadBalancerClientFilter(client);
    }

复制代码

2️⃣、GlobalFilter转换成GatewayFilter,并作用于每个路由上,在FilteringWebHandler实现

复制代码

//FilteringWebHandler类
    /**
     * 包装加载全局的过滤器,将全局过滤器包装成GatewayFilter
     */
    private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
        return filters.stream()
                .map(filter -> {
                    //将所有的全局过滤器包装成网关过滤器
                    GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
                    //判断全局过滤器是否实现了可排序接口
                    if (filter instanceof Ordered) {
                        int order = ((Ordered) filter).getOrder();
                        //包装成可排序的网关过滤器
                        return new OrderedGatewayFilter(gatewayFilter, order);
                    }
                    return gatewayFilter;
                }).collect(Collectors.toList());
    }
    @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);

        logger.debug("Sorted gatewayFilterFactories: "+ combined);
        //创建过滤器链表对其进行链式调用
        return new DefaultGatewayFilterChain(combined).filter(exchange);
    }

复制代码

  • loadFilters方法是将全局路由使用GatewayFilterAdapter包装成GatewayFilter
  • handle方法
    • 获取当前请求使用的路由Route
    • 获取路由配置的过滤器集合route.getFilters()
    • 合并全过滤器与路由配置过滤器combined
    • 对过滤器排序AnnotationAwareOrderComparator.sort
    • 通过过滤器集合构建顶级链表DefaultGatewayFilterChain,并对其当前请求调用链表的filter方法。

小结

Spring-Cloud-Gateway的过滤器接口分为两种:

  1. GlobalFilter : 全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain可识别的过滤器
  2. GatewayFilter : 需要通过spring.cloud.routes.filters 配置在具体路由下,只作用在当前路由上或通过spring.cloud.default-filters配置在全局,作用在所有路由上

五、GatewayFilterFactory 配置路由过滤器

  路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路径过滤器的范围限定为特定路径。 

1️⃣、加载GatewayFilter

  在路由定位器中以及看到了通过路由定义转换路由方法,其中包含了通过过滤器定义(FilterDefinition)转换过滤器(GatewayFilter)的部分,在RouteDefinitionRouteLocator类中源码如下:

复制代码

/**
     * 加载过滤器,根据过滤器的定义加载
     */
    @SuppressWarnings("unchecked")
    private List<GatewayFilter> loadGatewayFilters(String id, List<FilterDefinition> filterDefinitions) {
        //遍历过滤器定义,将过滤器定义转换成对应的过滤器
        List<GatewayFilter> filters = filterDefinitions.stream()
                .map(definition -> {
                    //通过过滤器定义名称获取过滤器创建工厂
                    GatewayFilterFactory factory = this.gatewayFilterFactories.get(definition.getName());
                    if (factory == null) {
                        throw new IllegalArgumentException("Unable to find GatewayFilterFactory with name " + definition.getName());
                    }
                    //获取参数
                    Map<String, String> args = definition.getArgs();
                    if (logger.isDebugEnabled()) {
                        logger.debug("RouteDefinition " + id + " applying filter " + args + " to " + definition.getName());
                    }

                    //根据args组装配置信息
                    Map<String, Object> properties = factory.shortcutType().normalize(args, factory, this.parser, this.beanFactory);
                    //构建过滤器创建配置信息
                    Object configuration = factory.newConfig();
                    ConfigurationUtils.bind(configuration, properties,
                            factory.shortcutFieldPrefix(), definition.getName(), validator);

                    //通过过滤器工厂创建GatewayFilter
                    GatewayFilter gatewayFilter = factory.apply(configuration);
                    if (this.publisher != null) {
                        //发布事件
                        this.publisher.publishEvent(new FilterArgsEvent(this, id, properties));
                    }
                    return gatewayFilter;
                })
                .collect(Collectors.toList());

        ArrayList<GatewayFilter> ordered = new ArrayList<>(filters.size());
        //包装过滤器使其所有过滤器继承Ordered属性,可进行排序
        for (int i = 0; i < filters.size(); i++) {
            GatewayFilter gatewayFilter = filters.get(i);
            if (gatewayFilter instanceof Ordered) {
                ordered.add(gatewayFilter);
            }
            else {
                ordered.add(new OrderedGatewayFilter(gatewayFilter, i + 1));
            }
        }

        return ordered;
    }

    /**
     * 获取RouteDefinition中的过滤器集合
     */
    private List<GatewayFilter> getFilters(RouteDefinition routeDefinition) {
        List<GatewayFilter> filters = new ArrayList<>();

        //校验gatewayProperties是否含义默认的过滤器集合
        //TODO: support option to apply defaults after route specific filters?
        if (!this.gatewayProperties.getDefaultFilters().isEmpty()) {
            //加载全局配置的默认过滤器集合
            filters.addAll(loadGatewayFilters("defaultFilters",
                    this.gatewayProperties.getDefaultFilters()));
        }

        if (!routeDefinition.getFilters().isEmpty()) {
            //加载路由定义中的过滤器集合
            filters.addAll(loadGatewayFilters(routeDefinition.getId(), routeDefinition.getFilters()));
        }

        //排序
        AnnotationAwareOrderComparator.sort(filters);
        return filters;
    }

复制代码

  • getFilters方法 合并配置中的全局过滤器与路由自身配置的过滤器,并对其排序(全局配置过滤器信息通过gatewayProperties.getDefaultFilters()获取)
  • loadGatewayFilters 依次遍历路由定义下的FilterDefinition并将其通过对应的GatewayFilterFactory转换为GatewayFilter对象。

2️⃣、GatewayFilterFactory配置过滤器创建工厂创建GatewayFilter对象

  默认内置很多GatewayFilterFactory实现类,用于创建作用不同的网关过滤器。

类图

  

子类及其划分

3️⃣、AddResponseHeaderGatewayFilterFactory 创建解析

复制代码

/**
 *
 * 响应header添加数据过滤器
 * 用户在response header中添加配置数据
 */
public class AddResponseHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {

    @Override
    public GatewayFilter apply(NameValueConfig config) {
        return (exchange, chain) -> {
            //获取Response并将配置的数据添加到header中
            exchange.getResponse().getHeaders().add(config.getName(), config.getValue());

            return chain.filter(exchange);
        };
    }
}。

复制代码

配置示例:

spring:
  cloud:
    gateway:
      default-filters:
      - AddResponseHeader=X-Response-Default-Foo, Default-Bar
  • AddResponseHeader=X-Response-Default-Foo, Default-Bar 会被解析成FilterDefinition对象 (name =AddResponseHeader ,args= [X-Response-Default-Foo,Default-Bar])
  • 通FilterDefinition的Name找到AddResponseHeaderGatewayFilterFactory工厂
  • 通过FilterDefinition 的args 创建Config对象(name=X-Response-Default-Foo,value=Default-Bar)
  • 通过 AddResponseHeaderGatewayFilterFactory工厂的apply方法传入config创建GatewayFilter对象。

4️⃣、全部配置

5.1、请求头

复制代码

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: http://example.org
        filters:
        - AddRequestHeader=X-Request-Foo, Bar

复制代码

名称和值,这将为所有匹配请求的下游请求标头添加X-Request-Foo:Bar标头。

移除请求头

filters:
        - RemoveRequestHeader=X-Request-Foo

5.2、请求参数

filters:
        - AddRequestParameter=foo, bar

这会将foo = bar添加到下游请求的所有匹配请求的查询字符串中。

5.3、添加响应头

filters:
        - AddResponseHeader=X-Response-Foo, Bar

这会将X-Response-Foo:Bar标头添加到所有匹配请求的下游响应标头中。

移除响应头

filters:
        - RemoveResponseHeader=X-Response-Foo

设置响应头

filters:
        - SetResponseHeader=X-Response-Foo, Bar

此GatewayFilter将替换具有给定名称的所有标头,而不是添加。

5.4、路径前缀

filters:
        - PrefixPath=/mypath

这将使/ mypath前缀为所有匹配请求的路径。所以对/ hello的请求会被发送到/ mypath / hello。

5.5、原始主机头

没有参数,此过滤器设置路由过滤器将检查的请求属性,以确定是否应发送原始主机头,而不是http客户端确定的主机头。

filters:
        - PreserveHostHeader

5.6、重定向

filters:
        - RedirectTo=302, http://acme.org

这将发送带有Location:http://acme.org标头的状态302以执行重定向。

5.7、重写路径

predicates:
        - Path=/foo/**
        filters:
        - RewritePath=/foo/(?<segment>.*), /$\{segment}

对于/ foo / bar的请求路径,这将在发出下游请求之前将路径设置为/ bar。注意由于YAML规范,$ \替换为$。

5.8、保存Session

predicates:
        - Path=/foo/**
        filters:
        - SaveSession

5.9、路径模板

SetPath GatewayFilter Factory采用路径模板参数。它提供了一种通过允许模板化路径段来操作请求路径的简单方法。

predicates:
        - Path=/foo/{segment}
        filters:
        - SetPath=/{segment}

对于/ foo / bar的请求路径,这将在发出下游请求之前将路径设置为/ bar。

5.10、设置响应状态

复制代码

spring:
  cloud:
    gateway:
      routes:
      - id: setstatusstring_route
        uri: http://example.org
        filters:
        - SetStatus=BAD_REQUEST
      - id: setstatusint_route
        uri: http://example.org
        filters:
        - SetStatus=401

复制代码

5.11、请求参数剥离

parts参数指示在将请求发送到下游之前从请求中剥离的路径中的部分数。

predicates:
        - Path=/name/**
        filters:
        - StripPrefix=2

当通过网关向/ name / bar / foo发出请求时,对nameservice的请求将类似于http:// nameservice / foo。

5.12、重试

retries:重试:应该尝试的重试次数

statuses:状态:应该重试的HTTP状态代码,使用org.springframework.http.HttpStatus表示

methods:方法:应该重试的HTTP方法,使用org.springframework.http.HttpMethod表示

series:系列:要重试的状态代码系列,使用org.springframework.http.HttpStatus.Series表示

复制代码

routes:
      - id: retry_test
        uri: http://localhost:8080/flakey
        predicates:
        - Host=*.retry.com
        filters:
        - name: Retry
          args:
            retries: 3
            statuses: BAD_GATEWAY

复制代码

5.13、Hystrix GatewayFilter Factory

https://cloud.spring.io/spring-cloud-static/Finchley.SR1/single/spring-cloud.html#_hystrix_gatewayfilter_factory

5.14、请求限速 

  RequestRateLimiter GatewayFilter Factory

5.15、安全头

  SecureHeaders GatewayFilter Factory

转载于:https://my.oschina.net/u/2277392/blog/3094843

分享到:
评论

相关推荐

    spring-cloud-gateway-demo.zip

    此外,Spring Cloud Gateway 提供了丰富的过滤器,比如 SecurityFilter、RateLimiterFilter 等,可以根据需求定制,实现如认证、限流、熔断等高级功能。在 "spring-cloud-gateway-demo" 中,你可能会看到这些过滤器...

    springcloud Gateway网关-压测用.zip

    而"简单路由及默认过滤器"则意味着Gateway已经配置了一些基础的路由规则,将请求导向不同的微服务,同时使用了SpringCloud Gateway提供的默认过滤器链,这些过滤器可能包括请求限流、身份验证等。 接下来,我们看到...

    最新Spring Cloud Gateway 官方参考指南-中文版-3.x

    Spring Cloud Gateway 是一款基于Spring生态系统构建的API网关,它主要设计用于提供一种简单而有效的方式来路由API,并为API提供核心关注点,如安全性、监控/度量和弹性。在3.1.3版本中,它利用了Spring Boot 2.x、...

    springcloud gateway 全局过滤器统一签名判定.doc

    在Spring Cloud Gateway中,全局过滤器(Global Filter)是一种强大的机制,用于在请求路由到具体的服务之前或之后执行通用的处理逻辑。在这个场景中,我们关注的是如何利用全局过滤器来实现统一的签名验证,这在...

    spring-cloud-gateway-example-master.zip

    它基于Spring Framework 5、Project Reactor和Spring Boot 2构建,支持高并发、低延迟的特性,并且提供了丰富的过滤器链来扩展功能。 2. **项目结构分析** "spring-cloud-gateway-example-master"项目通常包含以下...

    springcloud下通过gateway转发websocket

    5. 配合过滤器实现额外功能:Spring Cloud Gateway还提供了过滤器机制,可以根据需求自定义过滤器,例如添加认证、日志记录等功能。通过实现`GlobalFilter`接口并注册到Spring容器中,可以在WebSocket请求生命周期的...

    Spring Cloud Gateway 2.1 使用手册中文版

    Spring Cloud Gateway旨在提供一种简单而有效的API路由方式,并为其提供横切关注点,例如:安全,监控/指标和弹性。 特征: (1)构建于Spring Framework 5,Project Reactor 和 Spring Boot 2.0 (2)能够匹配任何...

    spring-cloud.zip

    接下来,Spring Cloud Gateway作为新一代的API网关,它基于Spring Framework 5、Project Reactor和Spring Boot 2构建,提供路由转发、过滤器等功能,简化了API管理和安全控制。在项目中,Gateway可能被用来处理所有...

    Spring Cloud Gateway 整合 Spring Security 统一登录认证鉴权

    在构建分布式系统时,Spring Cloud Gateway 作为微服务架构中的边缘服务或 API 网关,扮演着至关重要的角色。它负责路由请求到相应的微服务,并可以提供过滤器功能,如限流、熔断等。而Spring Security 则是 Java ...

    spring-cloud使用的各种示例

    - [springcloud(十六):服务网关 Spring Cloud GateWay 服务化和过滤器](http://www.ityouknow.com/springcloud/2019/01/19/spring-cloud-gateway-service.html) - [springcloud(十七):服务网关 Spring Cloud ...

    spring-cloud-gateway-oauth2

    在Spring Cloud Gateway中,我们可以利用Spring Security OAuth2模块,创建自定义的OAuth2过滤器,实现对API请求的授权验证。 具体步骤如下: 1. 添加依赖:在项目中引入Spring Security和OAuth2的相关依赖,包括`...

    spring cloud gateway 例子

    Spring Cloud Gateway 是一款基于 Spring Framework 5 和 Spring Boot 2 设计的云原生微服务网关,它旨在提供一种简单而有效的方式来对 API 进行路由,同时提供了过滤器功能,可以进行权限验证、限流、日志记录等...

    spring-cloud-starter-netflix-zuul.zip已经闭源的jar包,pom

    Zuul的核心功能在于为微服务提供动态路由、过滤和安全控制,它允许开发者定义一系列预处理和后处理的过滤器,用于执行如身份验证、动态路由、限流等功能。 Zuul的工作原理是在客户端请求到达服务之前,先经过Zuul...

    Spring Cloud Gateway的全局异常处理

    Spring Cloud Gateway作为一款基于Spring Framework 5、Project Reactor和Spring Boot 2.0构建的云原生网关框架,它提供了强大的路由转发能力和灵活的过滤器模型,能够很好地满足微服务网关的各种需求。然而,在实际...

    SpringCloud-Gateway demo.rar

    这个“SpringCloud-Gateway demo.rar”文件很可能是包含了演示如何设置和使用 Spring Cloud Gateway 的一个示例项目。 在Spring Cloud Gateway中,核心概念有以下几点: 1. **路由(Route)**:路由是 Gateway 的...

    spring cloud gateway跨域实现

    Spring Cloud Gateway 是Spring官方推出的一款现代化的网关服务,它构建于Spring Framework 5、Project Reactor 和 Spring Boot 2之上,提供了高性能、易用的API路由管理、过滤器等功能,是Spring Cloud生态中的重要...

    springcloud getaway 全局过滤器.doc

    本文将深入探讨如何在Spring Cloud Gateway中自定义全局过滤器。 首先,我们需要了解Spring Cloud Gateway的基本架构。Gateway基于Spring Framework 5、Project Reactor和Spring WebFlux构建,它提供了一种高效且...

    spring cloud zookeeper gateway

    3. **Spring Cloud Gateway**:学习Gateway的配置、路由规则定义、过滤器的使用,以及如何与Zookeeper集成进行动态路由。 4. **动态路由**:理解如何配置和实现动态路由,使网关能根据Zookeeper中的服务实例信息实时...

Global site tag (gtag.js) - Google Analytics