🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 一、过滤器简介 微服务网关经常需要对请求进行一些过滤操作,比如:鉴权之后添加Header携带令牌等。在过滤器中可以 * 为为请求增加请求头、增加请求参数 、增加响应头等等功能 * 鉴权、记录审计日志、统计请求响应时长等共性服务操作 微服务系统中有很多的服务,我们不希望在每个服务上都去开发鉴权、记录审计日志、统计请求响应时长等共性服务操作。所以对于这样的重复开发或继承类工作,放在gateway上面统一去做是最好不过了。 ## 二、Filter的生命周期 Spring Cloud Gateway 的 Filter 的生命周期很简单,只有两个:“pre” 和 “post”。 ![](https://img.kancloud.cn/45/27/452757673e16a68e8ad31c6c9ec1eafd_771x495.png) * PRE: 这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。 * POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的 HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。 ## 三、Filter的分类 Spring Cloud Gateway 的 Filter 从作用范围可分为: * GatewayFilter:应用到单个路由或者一个分组的路由上。 * GlobalFilter:应用到所有的路由上 **笔者并不建议你去花很多的时间去学习下面的这些Filter都是如何使用**,下面的这些Filter笔者几乎没有用到过。因为我已经介绍过了,Filter的作用就是在某些需求场景下去修改HTTP的请求头、路径、参数等等,只要你对HTTP协议足够的熟悉,所有的过滤器需求你都可以自定义实现,比起使用内置的Filter往往更加灵活。 ### 3.1.Gateway filter | 过滤器工厂 | 作用 | 参数 | | --- | --- | --- | | AddRequestHeader | 为原始请求添加Header | Header的名称及值 | | AddRequestParameter | 为原始请求添加请求参数 | 参数名称及值 | | AddResponseHeader | 为原始响应添加Header | Header的名称及值 | | DedupeResponseHeader | 剔除响应头中重复的值 | 需要去重的Header名称及去重策略 | | Hystrix | 为路由引入Hystrix的断路器保护 | `HystrixCommand`的名称 | | FallbackHeaders | 为fallbackUri的请求头中添加具体的异常信息 | Header的名称 | | PrefixPath | 为原始请求路径添加前缀 | 前缀路径 | | PreserveHostHeader | 为请求添加一个preserveHostHeader=true的属性,路由过滤器会检查该属性以决定是否要发送原始的Host | 无 | | RequestRateLimiter | 用于对请求限流,限流算法为令牌桶 | keyResolver、rateLimiter、statusCode、denyEmptyKey、emptyKeyStatus | | RedirectTo | 将原始请求重定向到指定的URL | http状态码及重定向的url | | RemoveHopByHopHeadersFilter | 为原始请求删除IETF组织规定的一系列Header | 默认就会启用,可以通过配置指定仅删除哪些Header | | RemoveRequestHeader | 为原始请求删除某个Header | Header名称 | | RemoveResponseHeader | 为原始响应删除某个Header | Header名称 | | RewritePath | 重写原始的请求路径 | 原始路径正则表达式以及重写后路径的正则表达式 | | RewriteResponseHeader | 重写原始响应中的某个Header | Header名称,值的正则表达式,重写后的值 | | SaveSession | 在转发请求之前,强制执行`WebSession::save`操作 | 无 | | SecureHeaders | 为原始响应添加一系列起安全作用的响应头 | 无,支持修改这些安全响应头的值 | | SetPath | 修改原始的请求路径 | 修改后的路径 | | SetResponseHeader | 修改原始响应中某个Header的值 | Header名称,修改后的值 | | SetStatus | 修改原始响应的状态码 | HTTP 状态码,可以是数字,也可以是字符串 | | StripPrefix | 用于截断原始请求的路径 | 使用数字表示要截断的路径的数量 | | Retry | 针对不同的响应进行重试 | retries、statuses、methods、series | | RequestSize | 设置允许接收最大请求包的大小。如果请求包大小超过设置的值,则返回`413 Payload Too Large` | 请求包大小,单位为字节,默认值为5M | | ModifyRequestBody | 在转发请求之前修改原始请求体内容 | 修改后的请求体内容 | | ModifyResponseBody | 修改原始响应体的内容 | 修改后的响应体内容 | | Default | 为所有路由添加过滤器 | 过滤器工厂名称及值 | > 每个过滤器工厂都对应一个实现类,并且这些类的名称必须以`GatewayFilterFactory`结尾,这是Spring Cloud Gateway的一个约定,例如`AddRequestHeader`对应的实现类为`AddRequestHeaderGatewayFilterFactory`。对源码感兴趣的小伙伴就可以按照这个规律拼接出具体的类名,以此查找这些内置过滤器工厂的实现代码 Filter并不如Predicate那么常用,更多的时候我们需要自定义Filter,所以官方内置的Filter我们就不一一介绍了。我们选两个例子来说明一下: * AddRequestHeader GatewayFilter Factory ~~~ spring: cloud: gateway: routes: - id: add_request_header_route uri: http://httpbin.org:80/get filters: - AddRequestHeader=X-Request-Foo, Bar predicates: - Method=GET ~~~ 过滤器工厂会在匹配的HTTP的请求加上一个Header,名称为X-Request-Foo,值为Bar。 * RewritePath GatewayFilter Factory 在Nginx服务启中有一个非常强大的功能就是重写路径,Spring Cloud Gateway默认也提供了这样的功能。 ~~~ spring: cloud: gateway: routes: - id: rewritepath_route uri: http://httpbin.org predicates: - Path=/foo/** filters: - RewritePath=/foo/(?<segment>.*), /$\{segment} ~~~ 根绝predicates的定义所有的/foo/\*\*开始的路径都会命中路由。 请求gateway路径`http://httpbin.org/foo/get`,gateway通过过滤器对路径进行重写,将请求转发至`http://httpbin.org/get`。 ### 3.2.Global filter Spring Cloud Gateway框架内置的GlobalFilter如下: | 全局过滤器 | 作用 | | --- | --- | | Forward Routing Filter | 用于本地forward,也就是将请求在Gateway服务内进行转发,而不是转发到下游服务 | | LoadBalancerClient Filter | 整合Ribbon实现负载均衡 | | Netty Routing Filter | 使用Netty的`HttpClient`转发http、https请求 | | Netty Write Response Filter | 将代理响应写回网关的客户端侧 | | RouteToRequestUrl Filter | 将从request里获取的原始url转换成Gateway进行请求转发时所使用的url | | Websocket Routing Filter | 使用Spring Web Socket将转发 Websocket 请求 | | Gateway Metrics Filter | 整合监控相关,提供监控指标 | 每种Global filter的使用需要具体问题具体分析,通常遇到特殊情况,内置Global filter满足不了我们的需求,还可以自定义GlobalFilter。下一节我们讲解。