spring cloud gateway内置网关filter

简介

spring cloud gateway中内置了很多的路由过滤工程,这些路由过滤工程允许以某种方式修改请求进来的http请求的内容(请求头,请求体)或返回的http响应。路由过滤器主要作用于需要处理的特定路由。spring cloud gateway内置了很多种类的过滤器,大致可以分为:Header、Paramter、Path、Status、Redirect、Hystrix熔断和限流RateLimiter。spring cloud gateway的路由过滤器的命令也遵循一定的规范,xxxxGatewayFilterFactory

AddRequestHeaderGatewayFilter

该过滤器用于:在请求中添加配置的请求头,使用示例如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - AddRequestHeader=need-trace, true
            - StripPrefix=1
   

RemoveRequestHeaderGatewayFilterFactory

该过滤器用于:在请求中移除配置的请求头,使用示例如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
            - RemoveRequestHeader=x-lw-agent
   

该配置表示移除请求中的请求头:x-lw-agent

AddResponseHeaderGatewayFilterFactory

该过滤器用于:在响应中添加配置的请求头,使用示例如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
            - AddResponseHeader=wtf,1111
   

RemoveResponseHeaderGatewayFilterFactory

该过滤器用于:在响应中移除配置的请求头,使用示例如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
            - RemoveResponseHeader=Date
   

RequestHeaderToRequestUriGatewayFilterFactory

该过滤器用于把请求转到请求头中对应配置的映射地址,比如如下的配置:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
#            - RemoveResponseHeader=Date
            - RequestHeaderToRequestUri=ddd
   

此时,如果发起如下请求时:

curl -i -H "X-New-Url: http://192.168.56.1:9001" http://192.168.56.1:9000/sc-c/hello/gatewayTest

会把该请求转到http://192.168.56.101:9001上,如果配置其他的过滤器:AddRequestHeaderGatewayFilterFactory可以实现灰度发布、路由分流等功能

HystrixGatewayFilterFactory

该过滤器用于处理spring cloud 的熔断逻辑,配置如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
            - name: Hystrix # Hystrix Filter的名称
              args: # Hystrix配置参数
                name: fallbackcmd #HystrixCommand的名字
                fallbackUri: forward:/fallback #fallback对应的uri

hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000
   

其中:

fallbackUri配置项配置gateway网关处的熔断逻辑

java 复制代码
    @RequestMapping("/fallback")
    public String fallback() {
        return "Spring Cloud Gateway Fallback!";
    }
XML 复制代码
hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000

该配置项表示熔断降级的超时时间

tips:使用Hystrix过滤器需要添加熔断组件依赖:

XML 复制代码
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

Parameter

AddRequestParameterGatewayFilterFactory

该过滤器用于在请求中添加请求参数中,使用示例如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
            - AddRequestParameter=address,123
   

此时在请求时,会添加请求参数address,值时123

RemoveRequestParameterGatewayFilterFactory

移除原始请求请求参数

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
            - RemoveRequestParameter=xxx
   

Path

StripPrefixGatewayFilterFactory

截取部分请求uri,使用示例如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1

   

执行请求:/sc-c/hello/gatewayTest会截取第一个路径地址(sc-c),最终的请求uri地址是:/hello/gatewayTest

RewritePathGatewayFilterFactory

通过正则表达式重写原始的请求路径,配置示例:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - RewritePath=/sc-c/(?<segment>.*), /$\{segment}
   

这里的效果和使用StripPrefix效果一样,不过RewritePath更灵活

PrefixPathGatewayFilterFactory

该过滤器为请求添加路由前缀,和StripPrefix相反,配置示例如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
            - PrefixPath=/hello
   

此时请求:/sc-c/gatewayTest 最终请求的地址是:/hello/gatewayTest

Body

ModifyRequestBodyGatewayFilterFactory

用于在转发请求之前修改原始请求体内容,使用示例如下:

java 复制代码
@Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes().route("test11",r -> r.path("/sc-c/**")
                        .filters(f -> f.stripPrefix(1)
                                .modifyRequestBody(String.class,String.class,
                       

当然也可以采用另外一种配置文件的方式实现:

1 在classpath下新增route.txt,配置示例内容如下:

XML 复制代码
[
  {
    "filters": [
      {
        "name": "ModifyRequestBody",
        "args": {
          "inClass": "java.lang.String",
          "outClass": "java.lang.String",
          "rewriteFunction": "#{@testRewriteFunction}"
        }
      },
      {
       "name": "StripPrefix",
        "args": {
           "_genkey_0": "1"
       }
      }
 ],
    "id": "test",
    "order": 0,
"predicates": [
      {
        "args": {
          "pattern": "/sc-c/**"
        },
        "name": "Path"
      }
    ],
      "uri": "lb://sc-consumer"
  }
]

2 增加配置代码保存路由

java 复制代码
@Component
public class RouteService {

    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    @PostConstruct
    public void init() {
        String routeConfig = FileUtil.readString("route.txt", StandardCharsets.UTF_8);
        List<RouteDefinition> list = JSONUtil.toList(routeConfig, RouteDefinition.class);
        for (RouteDefinition routeDefinition : list) {
            routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
        }
    }
}

ModifyResponseBodyGatewayFilterFactory

用于在转发响应之前修改原始响应体内容,使用示例如下:

java 复制代码
@Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes().route("test11",r -> r.path("/sc-c/**")
                        .filters(f -> f.stripPrefix(1)
                                .modifyRequestBody(String.class,String.class,
                       (exchange,s) -> Mono.just(s + "test"))
                                .modifyResponseBody(String.class,String.class,(exchange,s) -> {
                                    try {
                                        JSONObject entries = JSONUtil.parseObj(s);
                                        entries.set("appName","yc-music");
                                        return Mono.just(JSONUtil.toJsonStr(entries));
                                       } catch (Exception e) {
                                        return Mono.just(s);
                                    }
                                }))
                        .uri("lb://sc-consumer"))
                .build();

    }

当然也可以使用配置文件实现,

XML 复制代码
[
  {
    "filters": [
      {
        "name": "ModifyRequestBody",
        "args": {
          "inClass": "java.lang.String",
          "outClass": "java.lang.String",
          "rewriteFunction": "#{@testRewriteFunction}"
        }
      },
       {
          "name": "ModifyResponseBody",
          "args": {
            "inClass": "java.lang.String",
            "outClass": "java.lang.String",
            "rewriteFunction": "#{@testResponseBodyRewriteFunction}"
          }
       },
      {
       "name": "StripPrefix",
        "args": {
           "_genkey_0": "1"
       }
      }
    ],
    "id": "test",
    "order": 0,
    "predicates": [
      {
        "args": {
          "pattern": "/sc-c/**"
        },
        "name": "Path"
      }
    ],
    "uri": "lb://sc-consumer"
  }
]

代码配置:

java 复制代码
@Component
public class RouteService {

    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    @PostConstruct
    public void init() {
        String routeConfig = FileUtil.readString("route.txt", StandardCharsets.UTF_8);
        List<RouteDefinition> list = JSONUtil.toList(routeConfig, RouteDefinition.class);
        for (RouteDefinition routeDefinition : list) {
            routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
        }
    }
}

组件代码:

java 复制代码
@Component
public class TestRewriteFunction implements RewriteFunction<String, String> {

    @Override
    public Publisher<String> apply(ServerWebExchange serverWebExchange, String s) {
        return Mono.just(s);
    }
}


@Component
public class TestResponseBodyRewriteFunction implements RewriteFunction<String,String> {
    @Override
    public Publisher<String> apply(ServerWebExchange serverWebExchange, String s) {
        try {
            JSONObject entries = JSONUtil.parseObj(s);
            entries.set("appName","yc-music");
            return Mono.just(JSONUtil.toJsonStr(entries));
        } catch (Exception e) {
            return Mono.just(s);
        }
    }
}

其他

RetryGatewayFilterFactory

spring cloud gateway的重试组件,可以通过配置对应的条件,满足时可以重试,使用示例如下:

java 复制代码
    @Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes().route("test11",r -> r.path("/sc-c/**")
                        .filters(f -> f.stripPrefix(1)
                                .modifyRequestBody(String.class,String.class,
                                                           (exchange,s) -> Mono.just(s + "test"))
                                .retry((retryConfig -> {
                                    retryConfig.setRetries(3);
                                    retryConfig.setMethods(HttpMethod.POST,HttpMethod.GET);
                                    retryConfig.setExceptions(RuntimeException.class);
                                }))
                                .modifyResponseBody(String.class,String.class,(exchange,s) -> {
                                    try {
                                        JSONObject entries = JSONUtil.parseObj(s);
                                        entries.set("appName","yc-music");
                                        return Mono.just(JSONUtil.toJsonStr(entries));
                                    } catch (Exception e) {
                                        return Mono.just(s);
                                    }
                                }))
                                     .uri("lb://sc-consumer"))
                .build();

    }

当然也可以在配置文件中配置使用:

java 复制代码
[
  {
    "filters": [
     {
       "name": "StripPrefix",
        "args": {
           "_genkey_0": "1"
         }
      },
      {
        "name": "ModifyRequestBody",
        "args": {
          "inClass": "java.lang.String",
          "outClass": "java.lang.String",
          "rewriteFunction": "#{@testRewriteFunction}"
        }
      },
      {
        "name":"Retry",
         "args":{
            "retries": 3,
            "methods": ["GET", "POST"]
         }
      },
      {
          "name": "ModifyResponseBody",
          "args": {
            "inClass": "java.lang.String",
            "outClass": "java.lang.String",
            "rewriteFunction": "#{@testResponseBodyRewriteFunction}"
          }
       }
    ],
    "id": "test",
    "order": 0,
    "predicates": [
      {
        "args": {
          "pattern": "/sc-c/**"
        },
        "name": "Path"
      }
    ],
    "uri": "lb://sc-consumer"
  }
]
     
相关推荐
雨落花开3231 小时前
服务器集群,负载均衡,CDN简介
运维·服务器·负载均衡
麻瓜生活睁不开眼1 小时前
Android 14 开机自启动第三方 APK 全流程踩坑与最终解决方案(含 RescueParty 避坑)
android·java·深度学习
晚秋大魔王1 小时前
ubutnu 服务器配置openclaw 使用阿里云百炼模型
运维·服务器·阿里云
宁雨桥1 小时前
浏览器渲染原理
前端·浏览器·原理
Moment1 小时前
此 KFC 不是肯德基,Kafka、Flink、ClickHouse 怎么搭、何时省掉 Flink
前端·后端·面试
勇闯逆流河1 小时前
【Linux】基础开发工具(软件包、vim)
linux·运维·服务器
岳清源1 小时前
【无标题】Keepalived
linux·服务器·网络
鹏北海-RemHusband2 小时前
JSBridge 原理详解
前端·信息与通信