阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

过滤器

121次阅读
没有评论

共计 4514 个字符,预计需要花费 12 分钟才能阅读完成。

1、认识过滤器

1.1、过滤器的基本知识

微服务系统中的服务非常多。如果每个服务都自己做鉴权、限流、日志输出,则非常不科学。所以可以通过网关的过滤器来处理这些工作。在用户访问各个服务前,应在网关层统一做好鉴权、限流等工作。

1.2、Filter 生命周期

根据生命周期可以将 Spring Cloud Gateway 中的 Filter 分为 ”PRE” 和 ”POST” 两种:

**PRE:** 代表在请求被路由之前执行该过滤器。此种过滤器可用来实现参数校验、权限校验、流量监控、日志输出、协议转换等工能

**POST:** 代表在请求被路由到微服务之后执行该过滤器。此种过滤器可用来实现响应头的修改(如添加标准的 HTTP Header)、收集统计信息和指标、将响应发送给客户端、输出日志、流量监控等功能

1.3、Filter 分类

根据作用范围,Filter 可以分为以下两种:

**GatewayFilter:** 网关过滤器。此种过滤器只应用在单个路由或者一个分组的路由上

**GlobalFilter:** 全局过滤器。此种过滤器会应用在所有的路由上

2、网关过滤器

网关过滤器允许以某种方式修改传入的 HTTP 请求,或输出的 HTTP 响应。网关过滤器作用于特定路由。Spring Cloud Gateway 内置了许多过滤器工厂来编写网关过滤器。

2.1、AddRequestHeader 网关过滤器工厂

它用于在请求头中添加自定义的键值对。

2.2、AddRequestParameter 网关过滤器工厂

它用于在请求中添加请求参数的键值对。

2.3、AddResponseHeader 网关过滤器工厂

它用于在响应头中添加键值对。

2.4、Hystrix 网关过滤器工厂

它用于将断路器引入网关路由中,让服务免受级联故障的影响,并在故障时提供回退响应。在使用时需要一个名为 ”HystrixCommand” 的参数。

2.5、Prefix 网关过滤器工厂

它用于使简单的 Prefix 参数。

2.6、PreserveHostHeader 网关过滤器工厂

它用于设置路由过滤器的请求属性,检查是否发送原始主机头或由 HTTP 客户端确定主机头。

2.7、RequestRateLimiter 网关过滤器工厂

它用于确定当前请求是否允许继续。如果不允许,则返回提示 ”HTTP 429 -Too Many Requests”。

2.8、RedirectTo 网关过滤器工厂

它用于接收请求的状态和 URL 的参数。该状态是一个重定向的 300 系列的 HTTP 代码,如 301。URL 是 Location 头部的值。

2.9、RemoveNonProxyHeaders 网关过滤器工厂

它用于从转发的请求中删除请求头。

2.10、RemoveRequestHeader 网关过滤器工厂

它用于删除请求头,它需要请求头名。

2.11、RemoveResponseHeader 网关过滤器工厂

它用于删除响应头,它需要响应头名。

2.12、RewritePath 网关过滤器工厂

它用于使用 Java 正则表达式重写请求路径。

2.13、SaveSession 网关过滤器工厂

它用于在转发到下游之前强制执行保存 Session 操作。

2.14、SecureHeaders 网关过滤器工厂

它用于为响应添加安全头。

2.15、SetPath 网关过滤器工厂

它提供了一种方法,该方法允许通过路径的模板来操作请求路径。它使用了 Spring 框架的 URI 模板,支技多种匹配。

2.16、SetResponseHeader 网关过滤器工厂

它用于设置响应头,需要有一个 Key-Value 对。

2.17、SetStatus 网关过滤器工厂

它用于设置请求响应状态,它需要一个 Status 参数,该参数的值必须是有效的 Spring HttpStatus。例如,整型的 404 或枚举类型的字符串 NOT_FOUND。

2.18、StripPrefix 网关过滤工厂

它用于剥离前缀。它需要 parts 参数,表明在请求被发送到下游之前从请求路径中剥离的元素数量。

2.19、Retry 网关过滤工厂

它用于进行重试,它需要 Retries、Statuses、Methods 和 Series 参数

**Retries:** 重试次数

**Statuses:** 重试的 HTTP 状态代码,用 org.springframework.http.HttpStatus 表示

**Methods:** 重试的 HTTP 方法,用 org.springframework.http.HttpMethod 表示

**Series:** 重试的状态代码,用 org.springframework.http.HttpStatus.Series 表示

2.20、RequestSize 网关过滤器工厂

它用于限制请求的大小。当请求超过限制时启用,限制请求到达下游服务。该过滤器将 RequestSize 作为参数。

3、全局过滤器

全局过滤器由一系列特殊的过滤器组成。它会应用到所有路由中。

3.1、Forward 路由过滤器(Forward Routing Filter)

它在 exchange 的属性中查找 URI。如果 URI 是 forward 协议,则它将用 Spring DispatcherHandler 处理请求。

3.2、LoadBalancerClient 路由过滤器(LoadBalancerClient Filter)

它在 exchange 的属性中查找 URI。如果 URI 是 lb 协议,则它用 Spring Cloud LoadBalancerClient 将名称 (lb://myservice 中的 myservice) 解析为实际的主机和端口,并替换 URI 中的相同属性。

3.3、Netty 路由过滤器(Netty Routing Filter)

如果 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 中的 URI 使用的是 HTTP 或 HTTPS 协议,则运行 Netty 路由过滤器。它用 Netty HttpClient 发出下游代理请求。

3.4、Netty 写响应过滤器(Netty Write Response Filter)

如果在 ServerWebUtils.CLIENT_RESPONSE_ATTR 的值存在 Netty HttpClientResponse,则运行 Netty 写响应过滤器。它在所有其他过滤器完成后运行,并将代理响应写回到网关客户端的响应数据中。

3.5、RouteToRequestUrl 过滤器(RouteToRequestUrl Filter)

如果在 ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR 的值中存在 Route 对象,则运行路由到请求地址。

3.6、Websocket 路由过滤器(Websocket Routing Filter)

如果 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 值的 URI 是 ws 协议或 wss 协议,则运行 Websocket 路由过滤器。它利用 Spring Web Socket 底层代码将 Web Socket 请求转发到下游。

3.7、网关指标过滤器(Gateway Metrics Filter)

要启用它需要添加 spring-boot-starter-actuator 的依赖。默认情况下,只要属性 spring.cloud.gateway.metrics.enabled 未设置为 false,网关指标过滤器就会运行。此过滤器会添加一个名为 ”gateway.requests” 的指标(Metrics),其中包含以下属性:

routeId:路由 ld

routeUri:API 将被路由到的 URI

outcome:由 HttpStatus.Series 分类的结果

status:HTTP 请求返回给客户端的状态

3.8、组合式全局过滤器和网关过滤器排序(Combined Global Filter and GatewayFilter Ordering)

当请求进入并匹配到一个路由时,Filtering Web Handler 会将 GlobalFilter 的所有实例和 GatewayFilter 的所有路由特定实例添加到过滤器链中。这个组合的过滤器链由 org.springframework.core.Ordered 接口排序。

3.9、路由交换(Marking An Exchange As Routed)

网关在路由了 ServerWebExchange 后,会通过将 gatewayAlreadyRouted 添加到 exchange 属性来将该交换标识为 ” 路由 ”。一旦请求被标识为路由,则其他路由过滤器会跳过该请求。

4、使用 Global 过滤器实现用户认证

4.1、添加网关依赖

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

4.2、添加配置

#id: 自定义路由 ID
spring.cloud.gateway.routes[0].id=addrequestheader_route1
#uri: 目标服务地址
spring.cloud.gateway.routes[0].uri=http://localhost:50006
#predicates: 路由条件。Predicate 根据输入参数返回一个布尔值。其包含多种默认方法来将 Predicate 组合成复杂的路由逻辑
spring.cloud.gateway.routes[0].predicates[0]=Path=/hello

4.3、添加 TokenFilter

public class TokenFilter implements GlobalFilter, Ordered {@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 从请求中 token 参数 String token = exchange.getRequest().getQueryParams().getFirst("token"); // 如果为 null 或空直接返回 401 未认证错误 if (StringUtils.isEmpty(token)){exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } // 如果包含则放行 return chain.filter(exchange); } @Override public int getOrder() {return -100; } }

4.4、添加 Gateway 配置类

@Configuration public class GatewayConfig {@Bean public TokenFilter tokenFilter(){return new TokenFilter();} }

4.5、测试

访问:http://localhost:50024/hello

过滤器

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-06-06发表,共计4514字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中