Spring Cloud系列_33 Gateway过滤器

过滤器的概念这里不展开说,简而言之就是在路由的过程中为了做一些逻辑,Gateway提供过滤器给开发者使用

Spring Cloud Gateway 过滤器根据作用范围划分为GatewayFilter和GlobalFilter,二者区别如下:

  1. GatewayFilter(网关过滤器):需要通过spring.cloud.routes.filters配置在具体的路由下,只作用在当前路由上或通过spring.cloud.default-filters配置在全局,作用在所有路由上
  2. GlobalFilter(全局过滤器):不需要在配置文件中配置,作用在所有路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain可识别的过滤器,它为请求业务以及路由的URI转换为真实业务服务请求地址的核心过滤器,不需要配置系统初始化时加载,作用于每个路由上

GatewayFilter(网关过滤器)

网关过滤器用于拦截并链式处理Web请求,可以实现横切与应用无关的需求,如:安全,访问超时的设置等。修改传入的HTTP请求或传出HTTP响应。Spring Cloud Gateway包含许多内置的网关过滤器工厂。一共有22个,包括头部过滤器,路径类过滤器,Hystrix过滤器和重写请求URL的过滤器,还有参数状态码等其他类型的过滤器。根据过滤器工厂的用途来划分可以划分为:Header,Parameter,Path,Body,Status,Session,Redirect,Retry,RateLimiter和Hystrix

  • Path路径过滤器

可以实现URL重写,通过重写URL可以实现隐藏实际路径,提高安全性,用于用户记忆和键入,易于被搜索引擎收录等优点。实现方式如下:

  • 使用RewritePathGatewayFilterFactory

RewritePath网关过滤器工厂采用路径正则表达式参数和替换参数,使用Java正则表达式来灵活的重写请求路径

这里给出一个重写路径的例子:

server:
    port: 8082
spring:
    application:
        name: service-gateway-server
    cloud:
        gateway:
            #路由规则
            routes:
                -   id: service-provider-gateway #路由ID,唯一
                    uri: lb://service-provider-gateway # lb:// 根据服务名称从注册中心获取服务请求地址
                    predicates:                 # 断言(判断条件)
                        - Path=/provider/**, /api-gateway/**    # 匹配对应的URI的请求,将匹配到的请求追加在目标URI之后
                        # - Query=token #匹配请求参数中包含token的请求
                        #- Query=token,abc. #匹配请求参数中必须包含token,并且token的值满足正则 abc.
                        #- Method=GET #匹配GET方式
                        # 匹配中国上海时间 2020-02-02 20:20:20之后的请求
                        # - After=2020-02-02T20:20:20.000+08:00[Asia/Shanghai]
                        #- RemoteAddr=192.168.10.1/0 #0表示子网掩码
                        # 匹配请求头包含X-Request-Id 并且匹配正则表达式 \d+的请求
                        # - Header=X-Request-Id, \d+
                    filters:
                        # 将/api-gateway/provider/getProductsById/1 重写为 /provider/getProductsById/1
                        - RewritePath=/api-gateway(?<segment>/?.*),$\{segment}

为了方便演示,路由还按照旧的方式来配置,断言里的规则是,URL符合/provider/**, /api-gateway/**这样的路径就会被路由,而商品服务没有api-gateway/这个路径的资源,直接访问肯定会报错,我们通过重写路径将/api-gateway/的路径抹除

重启服务后测试,http://localhost:8082/api-gateway/provider/getProductsById/1 访问此路径正确返回结果

  • 使用PrefixPathGatewayFilterFactory

使用PrefixPath来给每个匹配的URI增加指定前缀

server:
    port: 8082
spring:
    application:
        name: service-gateway-server
    cloud:
        gateway:
            #路由规则
            routes:
                -   id: service-provider-gateway #路由ID,唯一
                    uri: lb://service-provider-gateway # lb:// 根据服务名称从注册中心获取服务请求地址
                    predicates:                 # 断言(判断条件)
                        - Path=/**    # 匹配对应的URI的请求,将匹配到的请求追加在目标URI之后
                        # - Query=token #匹配请求参数中包含token的请求
                        #- Query=token,abc. #匹配请求参数中必须包含token,并且token的值满足正则 abc.
                        #- Method=GET #匹配GET方式
                        # 匹配中国上海时间 2020-02-02 20:20:20之后的请求
                        # - After=2020-02-02T20:20:20.000+08:00[Asia/Shanghai]
                        #- RemoteAddr=192.168.10.1/0 #0表示子网掩码
                        # 匹配请求头包含X-Request-Id 并且匹配正则表达式 \d+的请求
                        # - Header=X-Request-Id, \d+
                    filters:
                        # 将/api-gateway/provider/getProductsById/1 重写为 /provider/getProductsById/1
                        #- RewritePath=/api-gateway(?<segment>/?.*),$\{segment}
                        # 将getProductsById/1 重写为 /provider/getProductsById/1
                        - PrefixPath=/provider

为了方便测试,断言我改成了所有路径都符合,访问http://localhost:8082/getProductsById/1能够正常返回

上一篇:OCP 071【中文】考试题库(cuug整理)第33题


下一篇:LeetCode 33. 搜索旋转排序数组