• Spring Cloud Gateway内置GatewayFilter工厂类 (一)


    路由过滤器允许以某种方式对Http的请求(request)和响应(response)进行修改。对于特定的路由可以配置相应的路由过滤器。Spring Cloud Gateway中也内置了一些GatewayFilter工厂类。

    注意,更多路由过滤器的详细使用,可以参考单元测试:https://github.com/spring-cloud/spring-cloud-gateway/tree/master/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory

    5.1 AddRequestHeaderGatewayFilter Factory

           AddRequestHeader过滤器工厂的实现类是AddRequestHeaderGatewayFilterFactory,它使用两个参数,一个是name,一个是value。在application.yml中的配置如下所示:

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

    配置(1)

    这个过滤器将会在下行的请求包头中添加键值对,也可以配合路由断言一起使用,给所有断言匹配的下行请求包头中添加此键值对。为了方便测试,在源码项目中使用了另外一种路由方式:根据服务名路由。如下面配置所示:

    spring:
      cloud:
        gateway:
          routes:
           - id: app-a-route     # 根据服务名路由
            uri: lb://app-a   #配置服务id
            predicates:
            - name: Path
              args:
                pattern: /app-a/** # 匹配的路径
            filters:
            - name: RewritePath
              args:
                regexp: /app-a/(?<remaining>.*)
                replacement: /${remaining}
            - name: AddRequestHeader
              args:
                name: X-Request-Foo
                value: Bar

    配置(2)

    可以看到,配置1与配置2中的filters的配置方式不一样,这是因为配置1只有一个过滤器,而配置2有多个过滤器,如果有多个过滤器,必须按对象定义的格式配置,如果只有一个过滤器可以使用配置1的方式,简化配置。

           这时,启动源码(https://gitee.com/wgslucky/SpringCloud)中的如果请求的spring-cloud-gateway项目和spring-cloud-app-a项目,在浏览器输入请求地址:http://localhost:8080/app-a/app/index,可以看到在spring-cloud-app-a的控制台输了从包头中获取的X-Request-Foo的值Bar。

    5.2 AddRequestParameter GatewayFilter Factory

        AddRequestParameter的过滤器工厂的实现类是AddRequestParameterGatewayFilterFactory,它有两个参数,一个是name,一个是value,如下面的配置:

    spring:
      cloud:
        gateway:
          routes:
           - id: app-a-route     # 根据服务名路由
            uri: lb://app-a   #配置服务id
            predicates:
            - name: Path
              args:
                pattern: /app-a/** # 匹配的路径
            filters:
            - name: RewritePath
              args:
                regexp: /app-a/(?<remaining>.*)
                replacement: /${remaining}
            - name: AddRequestHeader
              args:
                name: X-Request-Foo
            value: Bar
            - name: AddRequestParameter
              args: 
                name: foo
                value: bar

    这个过滤器,可以给所有匹配的路径添加字符串类型的查询参数。

        这时,启动源码中的如果请求的spring-cloud-gateway项目和spring-cloud-app-a项目,在浏览器输入请求地址:http://localhost:8080/app-a/app/add-request-parameter,可以看到日志输出了过滤器中添加的参数

    5.3 AddResponseHeader GatewayFilter Factory

        AddResponseHeader过滤器工厂的实现类是AddResponseHeaderGatewayFilterFactory,它有两个参数,一个是name,一个是value,而且都不能为空,在application.yml中的配置如下所示:

    spring:
      cloud:
        gateway:
          routes:
           - id: app-a-route     # 根据服务名路由
            uri: lb://app-a   #配置服务id
            predicates:
            - name: Path
              args:
                pattern: /app-a/** # 匹配的路径
            filters:
            - name: RewritePath
              args:
                regexp: /app-a/(?<remaining>.*)
                replacement: /${remaining}
            - name: AddRequestHeader
              args:
                name: X-Request-Foo
            value: Bar
            - name: AddRequestParameter
              args: 
                name: foo
            value: bar
            - name: AddResponseHeader
              args:
                name: foo
                value: bar2

    这时,启动源码中的如果请求的spring-cloud-gateway项目和spring-cloud-app-a项目,在浏览器输入请求地址:http://localhost:8080/app-a/app/add-request-parameter,在谷歌浏览器中按F12,刷新请求,可以看到响应的Header里面包括了过滤器添加的值。

    5.4 Hystrix GatewayFilter Factory

           Hystrix过滤器工厂的实现类是HystrixGatewayFilterFactory。Hystrix是Netflix的一个库,它实现了circuit breaker pattern。使用Hystrix过滤器,可以向网关引入熔断器,保护网关后面的服务不会因为大流量而失去服务能力。当出现大流量处理不过来的时候,可以向使用Hystrix过滤器提供一个失败的响应,当下行失败事件产生时,就会给客户端直接返回失败响应信息。

           为了使用Hystrix GatewayFilters,需要在项目中添加Hystrix的库依赖,如下面所示:

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

    Hystrix GatewayFilters需要一个name参数,它配置的就是HystrixCommand的名字。在application.yml中配置如下所示:

    spring:
      cloud:
        gateway:
          routes:
          - id: hystrix_route
            uri: http://example.org
            filters:
            - Hystrix=myCommandName

    这里fitlers中配置的就是一个名字为myCommandName的HystrixCommand。Hystrix Filters也可以配置一个fallbackUri参数,但是目前,只支持请求的forward:跳转。如果发生了失败,这个请求将会自动跳转到配置的controller中匹配到fallbackUri中。如下面配置所示:

    spring:
      cloud:
        gateway:
          routes:
           - id: app-a-route     # 根据服务名路由
            uri: lb://app-a   #配置服务id
            predicates:
            - name: Path
              args:
                pattern: /app-a/** # 匹配的路径
            filters:
            - name: Hystrix
              args:
                name: fallbackcmd   #熔断的名字,可以随便命名
                fallbackUri: forward:/fallback   # 如果触发了熔断,自动跳转到这个URI里面,在任务一个controller里面有这个URI即可。

    当Hystrix的fallback被触发时,请求会自动转发到/fallback的URI里面,此URI在Spring Cloud Gateway项目中的定义如下面代码所示:

    @RestController
    @RequestMapping("/")
    public class FallbackController {
        //添加一个Controller方法,用于接收Hystrix失败时的fallback跳转。
        @RequestMapping(value = "/fallback")
        @ResponseStatus
        public Mono<Map<String, Object>> fallback(ServerWebExchange exchange, Throwable throwable) {
            Map<String, Object> result = new HashMap<>(8);
            ServerHttpRequest request = exchange.getRequest();
            result.put("path", request.getPath().pathWithinApplication().value());
            result.put("method", request.getMethodValue());
            if (null != throwable.getCause()) {
                result.put("message", throwable.getCause().getMessage());
            } else {
                result.put("message", throwable.getMessage());
            }
            return Mono.just(result);
        }
    }

    从上面的案例中可以看到,fallbackUri跳转的是Spring Cloud Gateway项目内部的controller或handler,但是有时候也需要跳转到其它的服务中的controller或handler里面。如下面配置所示:

    spring:
      cloud:
        gateway:
          routes:
           - id: app-a-route     # 根据服务名路由
            uri: lb://app-a   #配置服务id
            predicates:
            - name: Path
              args:
                pattern: /app-a/** # 匹配的路径
            filters:
            - name: Hystrix
              args:
                name: fallbackcmd   #熔断的名字,可以随便命名
                fallbackUri: forward:/fallback   # 如果触发了熔断,自动跳转到这个URI里面,在任务一个controller里面有这个URI即可。
          - id: app-a-route-fallback
            uri: lb://app-b
            predicates:
            - Path=/fallback
            filters:
            - name: RewritePath
              args:
                regexp: /fallback
                replacement: /app/fallback

    在源码中,如果启动动网关服务和spring-clouad-app-b服务,不启动spring-cloud-app-a服务,在浏览器中请求:http://localhost:8080/app-a/app/add-request-parameter,可以看到返回的内容是spring-cloud-app-b中AppController的fallback方法中返回的内容。

           Hystrix的参数可以配置成全局默认值,也可以基本应用程序的属性配置,详细的可以参考Hystrix Wiki : https://github.com/Netflix/Hystrix/wiki/Configuration,比如配置上面例子中的fallbackcmd的超时时间为15秒,如下配置所示:

    hystrix: 
      command:
        fallbackcmd:
            execution: 
                isolation:
                  thread:
                    timeoutInMilliseconds: 15000

    5.5 FallbackHeaders GatewayFilter Factory

           FallbackHeaders过滤器工厂的实现类是FallbackHeadersGatewayFilterFactory。当Hytrix触发fallback调用并且fallbackUri跳转的是另外一个服务的地址时,这个过滤器可以向跳转请求的Header中添加失败的详细信息。如下面的配置所示:

    spring:
      cloud:
        gateway:
          routes:
           - id: app-a-route     # 根据服务名路由
            uri: lb://app-a   #配置服务id
            predicates:
            - name: Path
              args:
                pattern: /app-a/** # 匹配的路径
            filters:
            - name: Hystrix
              args:
                name: fallbackcmd   #熔断的名字,可以随便命名
                fallbackUri: forward:/fallback   # 如果触发了熔断,自动跳转到这个URI里面,在任务一个controller里面有这个URI即可。
          - id: app-a-route-fallback
            uri: lb://app-b
            predicates:
            - Path=/fallback
            filters:
            - name: RewritePath
              args:
                regexp: /fallback
                replacement: /app/fallback
            - name: FallbackHeaders
              args:
                executionExceptionTypeHeaderName: Test-Header

    在源码中,启动网关和spring-cloud-app-b服务,然后请求http://localhost:8080/app-a/app/add-request-parameter可以看到网页输了所有header中的信息,其它就是上面定义的test-header(只不过全部小写了)。如果想获取更多详细的信息,可以在args中配置更多的字段,这些字段名在FallbackHeadersGatewayFilterFactory的Config类里面,如下面代码所示:

            private String executionExceptionTypeHeaderName = EXECUTION_EXCEPTION_TYPE;
            private String executionExceptionMessageHeaderName = EXECUTION_EXCEPTION_MESSAGE;
            private String rootCauseExceptionTypeHeaderName = ROOT_CAUSE_EXCEPTION_TYPE;
            private String rootCauseExceptionMessageHeaderName = ROOT_CAUSE_EXCEPTION_MESSAGE;

    源码地址:https://gitee.com/wgslucky/SpringCloud    QQ交流群:677464431

  • 相关阅读:
    博客园的自定义皮肤
    为自己的审美观感到惭愧
    关于GitHub的Hello Word
    使用Windows Live Writer撰写的第一篇博文
    正式入驻博客园了
    一个使用 Web Components 的音乐播放器: MelodyPlayer
    一个(伪)MaterialDesign风格的博客园皮肤
    从零开始,做一个NodeJS博客(一):Heroku上的最简NodeJS服务器
    从零开始,做一个NodeJS博客(零):整体规(chui)划(niu)
    在 Xamarin.Android 中使用 Notification.Builder 构建通知
  • 原文地址:https://www.cnblogs.com/wgslucky/p/11422433.html
Copyright © 2020-2023  润新知