当前位置: 首页 > news >正文

03-详解网关的过滤器工厂和常见的网关过滤器路由过滤器,默认过滤器,全局过滤器的执行顺序

过滤器工厂

过滤器种类

GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务响应的结果做加工处理

在这里插入图片描述

Spring提供了31中不同的路由过滤器工厂

在这里插入图片描述

AddResponseHeader表示给请求添加响应头

default-filters: # 默认过滤器
- AddResponseHeader=X-Response-Default-Red, Default-Blue # 添加响应头X-Response-Default-Red: Default-Blue

PrefixPath表示给请求添加路径前缀

default-filters: # 默认过滤器
- PrefixPath=/httpbin

AddRequestHeader表示给请求添加key为X-Request-red,value为blue的请求头,可以应用于流量染色

filters: # 服务过滤器
- AddRequestHeader=X-Request-red, blue # 添加请求头X-Request-red: blue

AddRequestHeadersIfNotPresent表示给请求添加请求头,但只有当请求头里没有对应的请求头时才会添加,如果有则会传递原始的请求头

filters:# 添加多个请求头X-Request-Color-1:blue,X-Request-Color-2:green
- AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-2:green 

AddRequestParameter表示给请求添加请求参数

filters:
- AddRequestParameter=red, blue # 添加请求参数red=blue

AddResponseHeader表示给请求添加响应头

filters:
- AddResponseHeader=X-Response-Red, Blue # 给请求添加响应头X-Response-Red: Blue

CircuitBreaker(断路器)用于给接口做降级,当接口报错时降级去请求另一个接口

  • 在使用断路器之前,需要先引入spring-cloud-starter-circuitbreaker-reactor-resilience4j依赖
spring:cloud:gateway:routes:- id: circuitbreaker_routeuri: lb://backing-service:8088predicates:- Path=/consumingServiceEndpointfilters:- name: CircuitBreakerargs:name: myCircuitBreakerfallbackUri: forward:/inCaseOfFailureUseThis- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint

RequestRateLimiter表示使用Redis做限流,使用的令牌桶算法如漏桶算法RedisLimitHandler

filters:
- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 10redis-rate-limiter.burstCapacity: 20redis-rate-limiter.requestedTokens: 1

RedirectTo根据请求头里包含的状态码重定向到某个地址

spring:cloud:gateway:routes:- id: prefixpath_routeuri: https://example.orgfilters:- RedirectTo=302, https://acme.org # 当请求头里包含302的状态码时重定向到该地址

RemoveRequestHeader表示删除请求中对应的请求头

filters:
- RemoveRequestHeader=X-Request-Foo

RemoveRequestParameter表示删除请求中对应的请求参数

filters:
- RemoveRequestParameter=red

RemoveResponseHeader表示删除响应中对应的响应头

filters:
- RemoveResponseHeader=X-Response-Foo

RequestHeaderSize表示限制请求的请求头大小

filters:
- RequestHeaderSize=1000B # 如果请求头超过1000B,则会发送431状态码

网关三大过滤器

路由过滤器

需求: 给所有进入userservice服务的请求都添加一个请求头如Truth=Hello World!,当前过滤器写在userservice服务下因此仅对当前路由的请求生效

server:port: 10010 # 网关端口
spring:application:name: gateway # 服务名称cloud:nacos:server-addr: localhost:80 # nacos地址gateway:routes: # 网关路由配置- id: user-serviceuri: lb://userservice # 配置userservice服务的路由规则predicates:- Path=/user/**filters:- AddRequestHeader=Truth,Hello World! # 添加请求头Truth,值是Hello World!

在UserController中编写对应的控制器方法获取请求头信息,重启网关服务和userservice服务并访问http://localhost:10010/user/test

@GetMapping("/test")
public void test(@RequestHeader("Truth") String tmp) {System.out.println(tmp);
}

默认过滤器

默认过滤器: 如果希望过滤器的操作对所有的路由都生效,则可以将过滤器工厂写到spring.cloud.gateway.default-filters属性

server:port: 10010 # 网关端口
spring:application:name: gateway # 服务名称cloud:nacos:server-addr: localhost:80 # nacos地址gateway:routes:- id: user-serviceuri: lb://userservicepredicates:- Path=/user/**default-filters: # 默认过滤器,对所有的路由请求都生效- AddRequestHeader=Truth,Hello World!

全局过滤器

全局过滤器和GatewayFilter一样都可以对进入网关的请求和微服务的响应做加工处理

  • GatewayFilter网关过滤器: 通过配置文件定义所以处理的逻辑是固定的且只有默认过滤器对所有路由请求生效
  • GlobalFilter全局过滤器: 可以编写代码做自己的业务逻辑,如登录状态判断,权限校验,请求限流等,对所有的路由请求都生效
public interface GlobalFilter {/***  处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理** @param exchange 请求上下文,里面可以获取Request、Response等信息* @param chain 用来把请求委托给下一个过滤器 * @return {@code Mono<Void>} 返回标示当前过滤器业务结束*/Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

需求: 定义全局过滤器拦截请求,判断请求参数中是否有authorization且参数值是否为admin, 如果同时满足则放行请求否则拦截

第一步: 在gateway模块下新建cn.itcast.gateway.filter包,然后编写AuthorizationFilter类实现GlobalFilter接口并重写其中的filter方法

@Order(-1)
@Component
public class AuthorizationFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 1. 获取请求参数ServerHttpRequest request = exchange.getRequest();MultiValueMap<String, String> params = request.getQueryParams();// 2. 获取authorization参数的值String authorization = params.getFirst("authorization");// 3. 校验if ("admin".equals(authorization)) {// 4. 满足需求则放行return chain.filter(exchange);}// 拦截请求// 5.1 先设置状态码,这里的常量底层就是401(在restFul中401表示未登录)exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);// 5.2 拦截请求return exchange.getResponse().setComplete();}
}

第二步: 重启网关测试我们的全局过滤器是否生效,只有访问http://localhost:10010/user/1?authorization=admin时可以看到正常数据

{"id": 1,"username": "柳岩","address": "湖南省衡阳市"
}

过滤器执行顺序

请求进入网关后会经过路由过滤器,DefaultFilter,GlobalFilter三类过滤器,它们本质都是GatewayFilter(GlobalFilter被封装在GatewayFilterAdapter中)

  • 请求路由后会将当前路由过滤器,DefaultFilter,GlobalFilter合并到一个过滤器链集合中,在集合中根据order值对每个过滤器排序后依次按顺序执行

在这里插入图片描述

过滤器必须指定一个int类型的order值,order值越小优先级越高即执行顺序越靠前(默认值为int最大值2147483647)

  • 路由过滤器和de默认过滤器的order值: 由Spring指定默认是按照声明顺序从1递增
  • 全局过滤器的order值: 通过实现Ordered接口实现getOrder()方法或者添加@Order注解来指定order值
//@Order(-1)
@Component
public class AuthorizationFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 1. 获取请求参数MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();// 2. 获取authorization参数String authorization = params.getFirst("authorization");// 3. 校验if ("admin".equals(authorization)) {// 4. 满足需求则放行return chain.filter(exchange);}// 5. 不满足需求,设置状态码,这里的常量底层就是401,在restFul中401表示未登录exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);// 6. 结束处理return exchange.getResponse().setComplete();}@Overridepublic int getOrder() {return -1;}
}

过滤器的order值相同: 按照defaultFilter > routeFilter > GlobalFilter的顺序执行

  • org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters()方法: 负责加载defaultFilters然后再加载某个路由过滤器最后合并
  • org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()方法: 负责加载全局过滤器最后与路由过滤器和默认过滤器合并
# 配置路由过滤器和默认过滤器
server:port: 10010 # 网关端口
spring:application:name: gateway # 服务名称cloud:nacos:server-addr: localhost:80 # nacos地址gateway:routes:- id: user-serviceuri: lb://userservicepredicates:- Path=/user/**filters: # 路由过滤器默认是按照声明顺序从1递增- AddRequestHeader=Truth,Hello World! # order值为1- RemoveRequestHeader=X-Request-Foo # order值为2default-filters: # 默认过滤器- AddRequestHeader=Truth,Hello World! # order值为1- RemoveRequestHeader=X-Request-Foo # order值为2# 将自定义的全局过滤器的order也设定为1
http://www.lryc.cn/news/258917.html

相关文章:

  • 基于SSM的小儿肺炎知识管理系统设计与实现
  • HuffMan tree
  • 各地加速“双碳”落地,数字能源供应商怎么选?
  • 19.java绘图
  • 提升工作效率,尽在Microsoft Office LTSC 2021 for Mac!
  • day24_java的反射机制
  • VUE学习二、创建一个前端项目
  • 「红队笔记」靶机精讲:Prime1 - 信息收集和分析能力的试炼
  • JVM虚拟机系统性学习-对象的创建流程及对象的访问定位
  • perf与火焰图-性能分析工具
  • UniGui使用CSSUniTreeMenu滚动条
  • Spring框架中的五种常用设计模式
  • 华纳云:docker启动报错的原因和解决方法
  • 代码规范及开发工具
  • 证件照制作小程序源代码
  • 自治调优!人大金仓解放DBA双手
  • 深度学习环境配置------windows系统(GPU)------Pytorch
  • el-menu标题过长显示不全问题处理
  • 微信游戏开发:连接社交与娱乐的创新之路
  • 1688一件采购实现指南:含代码实现采购流程
  • div中一个图片怎么铺满整个div而且不超出div按比例铺满div
  • 云原生之深入解析Kubernetes的架构及特性
  • 分布工具类的定义与实现及测试。
  • 如何在忘记密码的情况下恢复解锁 iPhone
  • 通过compileall库将python文件编译为pyc文件
  • 【Docker】深入理解Docker:一种革新性的容器技术
  • 数据库——安全性
  • Vue路由跳转重定向动态路由VueCli
  • mysql 当前时间加3个工作日
  • 2023年11月国产数据库大事记-墨天轮