Spring Cloud服务入口Gateway的过滤器工厂剖析
目录
Gateway Filter Factories
Predicate决定了请求由哪一个路由来处理,要是在请求处理前后需要添加一些逻辑,这就是Filter(过滤器)发挥作用的范围啦。
Filter分为两种类型:Pre类型和Post类型。
Pre类型过滤器:在路由处理之前执行(也就是请求转发到后端服务之前执行),在Pre类型过滤器里能做鉴权、限流等操作。
Post类型过滤器:请求执行完毕后,在把结果返回给客户端之前执行。
Spring Cloud Gateway中内置了好多Filter,用来拦截和链式处理web请求。比如说权限校验、访问超时等设定。
Spring Cloud Gateway从作用范围来看,把Filter分成GatewayFilter和GlobalFilter。
GatewayFilter:应用到单个路由或者一个分组的路由上。
GlobalFilter:应用到所有的路由上,也就是对所有的请求都生效。
GatewayFilter
GatewayFilter和Predicate类似,都是在配置文件application.yml中进行配置的,每个过滤器的逻辑都是固定的。比如AddRequestParameterGatewayFilterFactory只需要在配置文件里写上AddRequestParameter,就能给所有请求添加一个参数,咱们先通过一个例子来演示GatewayFilter怎么使用。
application.yml
server:
port: 8888
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: 47.98.109.138:8848
gateway:
metrics:
enabled: true
routes:
- id: order-service # 路由规则id,随便起,不重复就行
uri: lb://order-service/ # 目标服务地址
predicates: # 路由条件
- Path=/order/**,/feign/**
filters:
- AddRequestParameter=userName, xiaoming
- id: product-service
uri: lb://product-service/
predicates:
- Path=/product/**
接收参数并打印
@Slf4j
@RequestMapping("/feign")
@RestController
public class FeignController {
@Autowired
private ProductApi productApi;
@RequestMapping("test")
public String test(Integer id, String userName) {
log.info("userName: " + userName);
return "接收到参数" + id;
}
}
启动服务并访问
(此处保留图片相关的Markdown占位,格式不变)
GatewayFilter说明
AddRequestHeader GatewayFilter Factory
给当前请求添加Header。
AddRequestHeadersIfNotPresent GatewayFilter Factory
给当前请求添加请求参数。
AddResponseHeader GatewayFilter Factory
给响应结果添加Header。
RemoveRequestHeader GatewayFilter Factory
从当前请求删除某个Header。
RemoveResponseHeader GatewayFilter Factory
从响应结果删除某个Header。
RequestRateLimiter GatewayFilter Factory
对当前网关的所有请求执行限流过滤,如果被限流,默认会响应HTTP429-TooManyRequests,默认提供了RedisRateLimiter的限流实现,采用令牌桶算法来实现限流功能。
说明:
redis-rate-limiter.replenishRate:令牌填充速度,也就是每秒钟允许多少个请求(不丢弃任何请求)
redis-rate-limiter.burstCapacity:令牌桶容量,也就是每秒用户最大能够执行的请求数量(不丢弃任何请求)。把这个值设置为零会阻止所有请求
redis-rate-limiter.requestedTokens:每次请求占用几个令牌,默认是1。
Retry GatewayFilter Factory
针对不同的响应进行重试。当后端服务不可用时,网关会根据配置参数发起重试请求。
说明:
retries:重试次数,默认是3
status:HTTP请求返回的状态码,针对指定状态码进行重试。对应org.springframework.http.HttpStatus
RequestSize GatewayFilter Factory
设置允许接收最大请求包的大小。要是请求包大小超过设置的值,就返回413 Payload Too Large。请求包大小的单位是字节,默认值是5M。
Default Filters
添加一个filter并把它应用到所有路由上,这个属性需要一个filter的列表。
Default Filter的使用
application.yml
server:
port: 8888
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: 47.98.109.138:8848
gateway:
metrics:
enabled: true
routes:
- id: order-service # 路由规则id,随便起,不重复就行
uri: lb://order-service/ # 目标服务地址
predicates: # 路由条件
- Path=/order/**,/feign/**
filters:
- AddRequestParameter=userName, xiaoming
- name: Custom # 过滤器名称
args:
name: test_custom
- id: product-service
uri: lb://product-service/
predicates:
- Path=/product/**
default-filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY
设置响应状态码为BAD_GATEWAY
@RequestMapping("/order")
@RestController
public class OrderController {
@Autowired
private OrderService orderService;
@RequestMapping("/{orderId}")
public OrderInfo getOrderById(@PathVariable("orderId") Integer orderId, ServerHttpResponse response) {
response.setStatusCode(BAD_GATEWAY);
return orderService.selectOrderById(orderId);
}
}
启动服务并访问
(此处保留图片相关的Markdown占位,格式不变)
可以看到,一共是四次,第一次是访问,后三次才是Retry的次数。
GlobalFilter
GlobalFilter是Spring Cloud Gateway中的全局过滤器,它和GatewayFilter的作用是一样的。GlobalFilter会应用到所有的路由请求上,全局过滤器通常用来实现和安全性、性能监控、日志记录等相关的全局功能。
Spring Cloud Gateway内置的全局过滤器也有很多,比如:
• Gateway Metrics Filter:网关指标,提供监控指标
• Forward Routing Filter:用于本地forword,请求不转发到下游服务器
• LoadBalancer Client Filter:针对下游服务,实现负载均衡
GlobalFilter的使用
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
添加配置
spring:
cloud:
gateway:
metrics:
enabled: true
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
shutdown:
enabled: true
启动服务并访问
查看所有监控的信息链接
访问“http://127.0.0.1:8888/actuator”,会显示所有监控的信息链接
(此处保留图片相关的Markdown占位,格式不变)