Gateway新一代网关

  概述简介

网关作为流量的入口常用功能包括路由转发,权限校验,限流控制等
    官网

      当前gateway
        https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.2.RELEASE/reference/html/
    是什么

Gateway新一代网关_第1张图片
Gateway新一代网关_第2张图片     

源码架构

Gateway新一代网关_第3张图片
    能干嘛
      反向代理
      鉴权
      流量控制
      熔断
      日志监控
    微服务架构中网关在哪里

Gateway新一代网关_第4张图片
    有zuul了怎么又出来了gateway
      我们为什么选择Gateway
        SpringCloud Gateway具有如下特性

Gateway新一代网关_第5张图片
        SpringCloud Gateway 与 Zuul的区别

Gateway新一代网关_第6张图片
      Zuul1.x模型

Gateway新一代网关_第7张图片
Gateway新一代网关_第8张图片     

Gateway模型

WebFlux是什么

Gateway新一代网关_第9张图片
Gateway新一代网关_第10张图片       

Gateway新一代网关_第11张图片


  三大核心概念


    Route(路由)
      路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由
    Predicate(断言)
      参考java8的java.util.function.Predicate开发人员可以匹配HTTP请求中的所有内容(例如请求头和请求参数),如果请求与断言相匹配则进行路由
    Filter(过滤)
      指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或之后对请求进行修改
    总体

Gateway新一代网关_第12张图片


  Gateway工作流程


    官网总结

Gateway新一代网关_第13张图片
Gateway新一代网关_第14张图片

  核心逻辑
      路由转发+执行过滤器链

请求到网关首先会根据断言判断是否符合路由规则,如果符合就会按照路由规则路由到指定地方,在路由到指定地方之前会有一系列filter进行过滤


  入门配置


    新建Module
      wms-gateway-9527
    POM

 
        
            org.springframework.cloud
            spring-cloud-starter-gateway
        


    
        wms
        com.hk.wms
        1.0-SNAPSHOT
    
    4.0.0

    wms-gateway-9527



    
        
        
            org.springframework.cloud
            spring-cloud-starter-gateway
        

        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
        
        




        
            org.springframework.boot
            spring-boot-starter-actuator
        
        
        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

注意:spring-cloud-starter-gateway包含有spring-boot-starter-web,和spring-boot-starter-webflux,如果发生冲突会报错误

Consider defining a bean of type 'org.springframework.http.codec.ServerCodec

解决方案1,去除依赖 spring-boot-starter-web和spring-boot-starter-webflux

解决方案2:排除spring-cloud-starter-gateway的依赖,


            org.springframework.cloud
            spring-cloud-starter-gateway
            
                
                    org.springframework.boot
                    spring-boot-starter-web
                
                
                    org.springframework.boot
                    spring-boot-starter-webflux
                
            
        

本例未使用 spring-boot-starter-webflux,所以不用排除

    YML

server:
  port: 9527

spring:
  application:
    name: wms-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.1.131:8848 #配置Nacos地址
        #server-addr: 192.168.1.131:1111 #使用nginx负载均衡注册服务,1111是nginx设置的监听端口号
    gateway:
      discovery:
        locator:
          enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
      routes:
        - id: service_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
          #匹配后提供服务的路由地址
          uri: http://localhost:8401
          predicates:
            - Path=/testE/** # 断言,路径相匹配的进行路由
            #- After=2017-01-20T17:42:47.789-07:00[America/Denver]
            #- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
            #- Cookie=username,zzyy
            #- Header=X-Request-Id, \d+ #请求头要有X-Request-Id属性,并且值为正数
            #- Host=**.atguigu.com
            #- Method=GET
            #- Query=username, \d+ # 要有参数名username并且值还要是正整数才能路由
          # 过滤
          #filters:
          #  - AddRequestHeader=X-Request-red, blue
        - id: service_route2
          uri: http://localhost:8401
          predicates:
            Path=/testF/** #断言,路径相匹配的进行路由

management:
  endpoints:
    web:
      exposure:
        include: '*'


    业务类
      无
    主启动类

package com.hk.wms.wmsgateway9527;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class WmsGateway9527Application {

    public static void main(String[] args) {
        SpringApplication.run(WmsGateway9527Application.class, args);
    }

}


    9527网关如何做路由映射呢?

wms-sentinel-service8401 看看controller的访问地址
  @GetMapping("/testE/{id}")
    @SentinelResource(value="testE",blockHandlerClass = CustomerBlockHandler.class,blockHandler = "customBlockHandler2",fallback = "handlerFallBack")
    public String getStrController(@PathVariable("id")int id){
        String str=feignService.getString(id);
        if(id<0){
            throw new IllegalArgumentException("IllegalArgument ,非法参数异常...");
        }
        if(str==null){
            throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
        }
        return str;
    }

    @GetMapping("/testF/{id}")
    @SentinelResource(value="testF",blockHandlerClass = CustomerBlockHandler.class,blockHandler = "customBlockHandler1",fallback = "handlerFallBack")
   public String CircleBreakerController(@PathVariable("id")int id){
        String str=template.getForObject(serverUrl+"/getStr/"+id,String.class);
        if(id<0){
            throw new IllegalArgumentException("IllegalArgument ,非法参数异常...");
        }
        if(str==null){
            throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
        }
        return str;
   }

   我们目前不想暴露8401端口,希望在8401外面套一层9527
    YML新增网关配置

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
      routes:
        - id: service_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
          #匹配后提供服务的路由地址
          uri: http://localhost:8401
          predicates:
            - Path=/testE/** # 断言,路径相匹配的进行路由
            #- After=2017-01-20T17:42:47.789-07:00[America/Denver]
            #- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
            #- Cookie=username,zzyy
            #- Header=X-Request-Id, \d+ #请求头要有X-Request-Id属性,并且值为正数
            #- Host=**.atguigu.com
            #- Method=GET
            #- Query=username, \d+ # 要有参数名username并且值还要是正整数才能路由
          # 过滤
          #filters:
          #  - AddRequestHeader=X-Request-red, blue
        - id: service_route2
          uri: http://localhost:8401
          predicates:
            Path=/testF/** #断言,路径相匹配的进行路由


    YML配置说明
      Gateway网关路由有两种配置方式:
        在配置文件yml中配置

        代码中注入RouteLocator的Bean

          百度国内新闻网站,需要外网
              通过9527网关访问到外网的百度新闻网址
            编码

package com.hk.wms.wmsgateway9527.config;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class GatewayConfig {
    /**
     * 配置了一个id为route-name的路由规则
     * 当访问地址 http://localhost:9527/guonei时会自动转发到地址: http://news.baidu.com/guonei
     * path是断言相当于在yml中配置
     * predicates:
     *          Path=/lady
     *
     * @param builder
     * @return
     */
    @Bean
    public RouteLocator getRouterLocator(RouteLocatorBuilder builder){
        RouteLocatorBuilder.Builder routes = builder.routes();
        routes.route("path_route_eiletxie",
                r -> r.path("/guonei")
                        .uri("http://news.baidu.com")).build();
        return routes.build();
    }

    @Bean
    public RouteLocator getRouteLocator2(RouteLocatorBuilder builder) {
        RouteLocatorBuilder.Builder routes = builder.routes();
        routes.route("path_route_eiletxie2",
                r -> r.path("/guoji")
                        .uri("http://news.baidu.com")).build();
        return routes.build();
    }

}
相当于在yml中配置
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
      routes:
        - id: path_route_eiletxie # 路由的id,没有规定规则但要求唯一,建议配合服务名
          #匹配后提供服务的路由地址
          uri: http://news.baidu.com
          predicates:
            - Path=/guonei # 断言,路径相匹配的进行路由
           
        - id: path_route_eiletxie
          uri: http://news.baidu.com
          predicates:
            Path=/guoji #断言,路径相匹配的进行路由

 


  通过微服务名实现动态路由


    默认情况下Gateway会根据注册中心的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能

    YML

server:
  port: 9527

spring:
  application:
    name: wms-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.1.131:8848 #配置Nacos地址
        #server-addr: 192.168.1.131:1111 #使用nginx负载均衡注册服务,1111是nginx设置的监听端口号
    gateway:
      discovery:
        locator:
          enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
      routes:
        - id: service_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
          #匹配后提供服务的路由地址
          uri: http://localhost:8401
          predicates:
            - Path=/testE/** # 断言,路径相匹配的进行路由
            #- After=2017-01-20T17:42:47.789-07:00[America/Denver]
            #- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
            #- Cookie=username,zzyy
            #- Header=X-Request-Id, \d+ #请求头要有X-Request-Id属性,并且值为正数
            #- Host=**.atguigu.com
            #- Method=GET
            #- Query=username, \d+ # 要有参数名username并且值还要是正整数才能路由
          # 过滤
          #filters:
          #  - AddRequestHeader=X-Request-red, blue
        - id: service_route2
          uri: http://localhost:8401
          predicates:
            Path=/testF/** #断言,路径相匹配的进行路由
        - id: service_route3
          uri: lb://wms-provider
          predicates:
            - Path=/provider/**

        - id: service_route4
          uri: lb://wms-provider
          predicates:
            - Path=/getStr/**

        - id: service_route4
          uri: lb://wms-provider
          predicates:
            - Path=/getStr2/**

management:
  endpoints:
    web:
      exposure:
        include: '*'
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
      routes:
        - id: service_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
          #匹配后提供服务的路由地址
          uri: http://localhost:8401
          predicates:
            - Path=/testE/** # 断言,路径相匹配的进行路由
         
        - id: service_route2
          uri: http://localhost:8401
          predicates:
            Path=/testF/** #断言,路径相匹配的进行路由

         - id: service_route3
          uri: lb://wms-provider
          predicates:
            - Path=/provider/**

        - id: service_route4
          uri: lb://wms-provider
          predicates:
            - Path=/getStr/**

        - id: service_route4
          uri: lb://wms-provider
          predicates:
            - Path=/getStr2/**


      需要注意的是uri的协议为lb,表示启用Gateway的负载均衡功能
      lb://serviceName是springcloud gateway在微服务中自动为我们创建的负载均衡uri

spring.cloud.gateway.discovery.locator.enabled=true:开启从注册中心动态创建路由的功能,利用微服务名称进行路由


  Predicate断言的使用


    是什么
      启动我们的gateway9527
    Route Predicate Factories 这个是什么东东?

Gateway新一代网关_第15张图片
    常用的Route Predicate
      1、After Route Predicate
        YML

- id: payment_route2
  #uri: http://localhost:8001
  uri: lb://cloud-payment-service
  predicates:
  - Path=/payment/lb/** #断言,路径相匹配的进行路由
  - After=2020-03-12T16:44:15.064+08:00[Asia/Shanghai]

设置当前时间再加1小时进行测试,当测试请求的时间小于设定时间时就会报错,因为设置了 必须在 AFTER 某某时间以后请求才有效

      2、Before Route Predicate
      3、Between Route Predicate

        YML

Gateway新一代网关_第16张图片
      4、Cookie Route Predicate  匹配cookie

yml

- id: payment_route2
  #uri: http://localhost:8001
  uri: lb://cloud-payment-service
  predicates:
  - Path=/payment/lb/** #断言,路径相匹配的进行路由
  - After=2020-03-12T15:44:15.064+08:00[Asia/Shanghai]
  - Cookie=username,eiletxie #cookie的key是username,cookie的value是eiletxie


 - id: service_route3
          uri: lb://wms-provider
          predicates:
            - Path=/provider/**
            - Cookie=username,yangdong #只有加上Cookie才能访问,Cookie的key是username,Cookie的value是yangd

不带cookies访问
  curl http://localhost:9527/provider/1     报404错误

C:\Users\hk>curl http://localhost:9527/provider/1
{"timestamp":"2020-05-21T05:39:14.625+0000","path":"/provider/1","status":404,"error":"Not Found","message":null,"requestId":"bf2a25f5","trace":"org.springframework.web.server.ResponseStatusException: 404 NOT_FOUND\r\n\tat org.springframework.web.reactive.resource.ResourceWebHandler.lambda$handle$0(ResourceWebHandler.java:325)\r\n\tSuppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: \nError has been observed at the following site(s):\n\t|_ checkpoint 鈬?org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]\n\t|_ checkpoint 鈬?org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]\n\t|_ checkpoint 鈬?HTTP GET \"/provider/1\" [ExceptionHandlingWebHandler]\nStack trace:\r\n\t\tat org.springframework.web.reactive.resource.ResourceWebHandler.lambda$handle$0(ResourceWebHandler.java:325)\r\n\t\tat reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44)\r\n\t\tat reactor.core.publisher.Mono.subscribe(Mono.java:4105)\r\n\t\tat reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:75)\r\n\t\tat reactor.core.publisher.MonoFlatMap$FlatMapMain.onComplete(MonoFlatMap.java:174)\r\n\t\tat reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:96)\r\n\t\tat reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:359)\r\n\t\tat reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:211)\r\n\t\tat reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:139)\r\n\t\tat reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:63)\r\n\t\tat reactor.core.publisher.Mono.subscribe(Mono.java:4105)\r\n\t\tat reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:172)\r\n\t\tat reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)\r\n\t\tat reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)\r\n\t\tat reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67)\r\n\t\tat reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:76)\r\n\t\tat reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.innerNext(FluxConcatMap.java:274)\r\n\t\tat reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:851)\r\n\t\tat reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121)\r\n\t\tat reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2186)\r\n\t\tat reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:162)\r\n\t\tat reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:1994)\r\n\t\tat reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:1868)\r\n\t\tat reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:90)\r\n\t\tat reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54)\r\n\t\tat reactor.core.publisher.Mono.subscribe(Mono.java:4105)\r\n\t\tat reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:441)\r\n\t\tat reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:211)\r\n\t\tat reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:139)\r\n\t\tat reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:63)\r\n\t\tat reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:55)\r\n\t\tat reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)\r\n\t\tat reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:55)\r\n\t\tat reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)\r\n\t\tat reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:55)\r\n\t\tat reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)\r\n\t\tat reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:55)\r\n\t\tat reactor.cocurl: (23) Failed writing body (4096 != 7668)

带上cookies访问
  curl http://localhost:9527/provider/1 --cookie "username=yangdong"

C:\Users\hk>curl http://localhost:9527/provider/1 --cookie "username=yangdong"
9002:1
C:\Users\hk>curl http://localhost:9527/provider/1 --cookie "username=yangdong"
9003:1:this is wms-provider-dev.yaml
C:\Users\hk>curl http://localhost:9527/provider/1 --cookie "username=yangdong"
9002:1
C:\Users\hk>curl http://localhost:9527/provider/1 --cookie "username=yangdong"
9003:1:this is wms-provider-dev.yaml


      5、 Header Route Predicate 匹配请求头

    YML

- id: payment_route2
  #uri: http://localhost:8001
  uri: lb://cloud-payment-service
  predicates:
  - Path=/payment/lb/** #断言,路径相匹配的进行路由
  - After=2020-03-12T15:44:15.064+08:00[Asia/Shanghai]
  #- Cookie=username,eiletxie   #带Cookie,并且username的值为eiletxie
  - Header=X-Request-Id,\d+ #请求头要有 X-Request-Id属性并且值为整数的正则表达式

Gateway新一代网关_第17张图片
   

带上head请求头访问

curl http://localhost:9527/payment/lb -H "X-Request-Id:123"
      6、 Host Route Predicate 

Gateway新一代网关_第18张图片

Gateway新一代网关_第19张图片
      7、 Method Route Predicate 匹配请求方式

Gateway新一代网关_第20张图片
      8、 Path Route Predicate  匹配路径

Gateway新一代网关_第21张图片
      9、 Query  Route Predic 匹配请求路径上的参数Gateway新一代网关_第22张图片ate

- id: baidu
  uri: https://www.baidu.com
  predicates:
    - Query=url,baidu
- id: qq
  uri: https://www.qq.com
  predicates:
    - Query=url,q.

http://localhost:9527/?url=qq访问腾讯主页

http://localhost:9527/?url=baidu 访问百度主页
      10、 小总结
        ALL

Gateway新一代网关_第23张图片
        说白了,Predicate就是为了实现一组匹配原则,让请求过来找到对应的Route进行处理


  Filter的使用

生命周期,
        pre
        post 
种类
        GatewayFilter

Gateway新一代网关_第24张图片
        GlobalFilte


 常用的GatewayFilter AddRequestParameter
        YML

Gateway新一代网关_第25张图片
     
    自定义过滤器
      自定义全局GlobalFilter

          implements GlobalFilter,Ordered说明网关的filter和servlet的filter无关

package com.hk.wms.wmsgateway9527.config;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class MyLogGatewayFilter implements GlobalFilter, Ordered {
    Logger logger= LoggerFactory.getLogger(getClass());
    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        logger.info("进入filter");
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if(StringUtils.isEmpty(uname)){
            logger.info("*****用户名为null,非法用户,o(╥﹏╥)o");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    /**
     * 加载过滤器的顺序,数字越小,优先级越高
     */
    public int getOrder() {
        return 0;
    }
}

作用
          全局日志记录
          统一网关鉴权
           

C:\Users\hk>curl http://localhost:9527/provider/1 --cookie "username=yangdong"
#没有添加参数
2020-05-21 14:54:12.328  INFO 4588 --- [ctor-http-nio-2] c.h.w.w.config.MyLogGatewayFilter        : 进入filter
2020-05-21 14:54:12.330  INFO 4588 --- [ctor-http-nio-2] c.h.w.w.config.MyLogGatewayFilter        : *****用户名为null,非法用户,o(╥﹏╥)o

C:\Users\hk>curl http://localhost:9527/provider/1?uname=lily --cookie "username=yangdong"
9002:1
C:\Users\hk>curl http://localhost:9527/provider/1?uname=lily --cookie "username=yangdong"
9003:1:this is wms-provider-dev.yaml
C:\Users\hk>curl http://localhost:9527/provider/1?uname=lily --cookie "username=yangdong"
9002:1
C:\Users\hk>curl http://localhost:9527/provider/1?uname=lily --cookie "username=yangdong"
9003:1:this is wms-provider-dev.yaml
2020-05-21 14:56:21.315  INFO 4588 --- [ctor-http-nio-5] c.h.w.w.config.MyLogGatewayFilter        : 进入filter
2020-05-21 14:56:29.195  INFO 4588 --- [ctor-http-nio-6] c.h.w.w.config.MyLogGatewayFilter        : 进入filter
2020-05-21 14:56:33.585  INFO 4588 --- [ctor-http-nio-7] c.h.w.w.config.MyLogGatewayFilter        : 进入filter

 

你可能感兴趣的:(springcloud)