小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
Spring Cloud Gateway
是Spring官方提供了高性能网关。Spring Cloud Gateway
为微服务架构提供一种简单有效的统一的API路由
管理方式。作为统一的流量入口,可以在Spring Cloud Gateway
中完成负载均衡
、日志追踪
、安全认证
等功能。
工作模型
Spring Cloud Gateway
的本质是服务代理
,即服务不在请求具体的应用服务,而是统一请求Gateway
网关,由网关根据匹配规则将请求路由到具体的应用服务。下图是官网给出的工作原理图:
客户端
向Spring Cloud Gateway
发出请求,Spring Cloud Gateway
通过Gateway Handler Mapping
进行 路由配置
,匹配到路由之后,请求进入Gateway Web Handler
处理。Gateway Web Handler
即Gateway
提供的一组过滤器
。
基本组成
**Route
**:网关的基础。由ID
、目标URI
、一组Predicate
和一组Filter
构成。如果所有的Predicate
都为true,则将请求路由到目标URI
Predicate:函数式接口。可以匹配来自HTTP请求的任何内容,例如请求方法、请求头、请求参数等。
Filter: 过滤器。可以在请求路由到目标URI之前或之后修改请求和响应。
Route
路由是网关的基本组成,包含id
、uri
、predicates
、filters
和metadata(元数据)
属性。
id
: 路由的唯一标识uri
:目标URI
,Predicate
集合都为true时,将原请求路由到的目标URI
predicates
: 断言集合,可以根据datetime(请求时间)
Cookie
、Header
、Host(主机地址)
、--Method(请求方法)
、Path(请求路径)
、Query(查询参数)
、RemoteAddr(远程地址)
、Weight(路由权重)
进行判断filters
: 这个filter
是内置的网关过滤器
。包含添加或过滤Header
、参数
、响应数据
、请求路径
以及CircuitBreaker 断路器
、RequestRateLimiter 限流
等功能metadata
: 元数据,一般是一些描述信息
Predicate
Predicate
的作用是判断请求是否和该Route
匹配,如果匹配则将该请求路由到目标URI
。Spring Cloud Gateway
提供了一下Predicate Factory
:
After Predicate
/Before Predicate
/Between Predicate
: 判断请求时间是否在跟定时间之前、之后或之间After
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
Before
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
Between
spring:
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
Cookie Predicate
: 根据Cookie
匹配Cookie Predicate
接受两个参数,Cookie名称和regexp(一个Java正则表达式)。即具有给定名称的Cookie
且其值与正则表达式匹配
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=name, value
Header Predicate
: 根据请求头匹配Header Predicate
接受两个参数,Header名称和regexp(一个Java正则表达式)。即具有给定名称的Header
且其值与正则表达式匹配
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+ # 请求头中具有名为X-request-Id的标头,且其值与\d+正则表达式匹配(即,其值为一个或多个数字)
Host Predicate
: 根据主机地址匹配Host Predicate
接受一个参数:主机名模式列表。该模式是Ant-style
风格:?
: 匹配任何单字符,*
: 匹配0或者任意数量的字符,**
: 匹配0或者更多的目录
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
Method Predicate
: 根据请求方法匹配 接受一个参数(如GET
、POST
、DELETE
等),匹配多个方法时以逗号隔开
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
Path Predicate
: 根据请求路径匹配 接受一个参数:请求路径。支持Ant-style
风格,匹配多个路径时以逗号隔开
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/book/{id} # /book/1、/book/2等都可以匹配成功
Query Predicate
: 根据请求参数匹配 接受两个参数:一个必需的参数和一个可选的regexp(这是一个Java正则表达式)
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green # 请求参数包含green,则匹配成功
RemoteAddr Predicate
:根据请求中的远程地址匹配 接受一个参数:CIDR
模式的ip源。CIDR
表示法(IPv4或IPv6)字符串,例如192.168.0.1/16(其中192.168.0.1是IP地址,16是子网掩码)
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
Weight Predicate
: 配置路由的权重,根据权重选择Route
接受两个参数:group (分组)和Weight(权重)
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
Filter
Filter
主要用来修改请求或响应信息如请求路径、请求参数、响应头、响应结果等
。Spring Cloud Gateway 提供的内置Filter
如下:
AddRequestHeader Filter
:增加请求头 接收一个name
和value
参数,将name
和value
放入该请求的请求头中
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-red, blue # 向请求中添加一个名为`X-Request-red`值为`blue`的请求头
AddRequestParameter Filter
: 添加参数 接收一个name
和value
参数,将name
和value
放入该请求的请求参数中
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=color, blue # 向请求中添加`color=blue`参数
= AddResponseHeader Filter
: 添加响应头
接收一个name
和value
参数,将name
和value
放入该请求的响应头中
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Red, Blue
DedupeResponseHeader Filter
: 移除重复的响应头 接收以一个参数:请求头。要移除多个重复请求头时用空格隔开
spring:
cloud:
gateway:
routes:
- id: dedupe_response_header_route
uri: https://example.org
filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin # 当网关CORS逻辑和下游逻辑都添加了访问控制允许凭据和访问控制允许源响应头时,将删除它们的重复值
CircuitBreaker Filter
: 断路器。当请求超时或出现异常时进行降级Spring Cloud Gateway
和Spring Cloud CircuitBreaker
一起完成CircuitBreaker
,其中Spring Cloud CircuitBreaker
支持多种CircuitBreaker
库。。Resilience4J
-开箱即用的CircuitBreaker
库。
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingServiceEndpoint
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker 在java中配置的CircuitBreaker bean
fallbackUri: forward:/inCaseOfFailureUseThis # 请求失败后调用, 可以不写
statusCodes: # 请求失败时返回的请求状态码, 可以不写
- 500
- "NOT_FOUND"
FallbackHeaders Filter
: 在转发到外部应用程序中的fallbackUri
的请求的标头中添加Spring Cloud CircuitBreaker
执行的异常详细信息
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: CircuitBreaker
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
filters:
- name: FallbackHeaders
args:
executionExceptionTypeHeaderName: Test-Header
MapRequestHeader Filter
:映射请求头 接收两个参数:fromHeader
和toHeader
。如果请求中包含名为fromHeader
的Header,则在请求中添加名为toHeader
的Header,值为fromHeader
的值
spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=fromHeader, toHeader
PrefixPath Filter
: 在请求路径中添加前缀路径
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath # 在请求路径中添加/mypath前缀。即对/hello的请求将被发送到/mypath/hello
PreserveHostHeader Filter
: 保持Host Header
没有参数。设置路由筛选器检查的请求属性,以确定是否应发送原始Host Header
,而不是HTTP客户端确定的Host Header
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader
RequestRateLimiter Filter
: 请求限流RequestRateLimiter
使用RateLimiter接口
的实现类来确定是否允许当前请求继续进行。c请求速率超出设置时默认返回HTTP 429状态-太多请求
RequestRateLimiter
接受可选的keyResolver
参数和RateLimiter
参数,如下图:
RedisRateLimiter
:基于Redis
的RateLimiter
Spring Cloud Gateway
提供了基于Redis
的限流实现-RedisRateLimiter
。
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10 # 允许用户每秒执行的请求数,而不会删除任何请求。这是令牌桶的填充速率
redis-rate-limiter.burstCapacity: 20 # 允许用户在一秒钟内执行的最大请求数。这是令牌桶可以容纳的令牌数。将此值设置为零将阻止所有请求
redis-rate-limiter.requestedTokens: 1 # 一个请求需要多少令牌。这是每个请求从bucket中提取的令牌数,默认为1
RedirectTo Filter
: 重定向到指定请求 接受两个参数:status
和url
。status
应该是300系列的重定向HTTP状态码(如301)。
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
RemoveRequestHeader Filter
: 移除指定请求头 接受一个参数:header 名。删除请求头中该header
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
RemoveResponseHeader Filter
:移除请求参数
spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route
uri: https://example.org
filters:
- RemoveRequestParameter=red
同上
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: https://example.org
filters:
- RemoveResponseHeader=X-Response-Foo
RemoveRequestParameter Filter
:移除请求参数 接受一个参数:参数名。
spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route
uri: https://example.org
filters:
- RemoveRequestParameter=red
RewritePath Filter
:重写请求路径 接受两个参数: 匹配path regexp
和替换path regexp
。使用Java正则表达式来灵活地重写请求路径
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/red/**
filters:
- RewritePath=/red/?(?<segment>.*), /${segment} # 请求/red/a的路径将被替换成/a
RewriteLocationResponseHeader Filter
: 修改位置响应标头的值,通常是为了去除后端特定的详细信息。它采用stripVersionMode、locationHeaderName、hostValue和protocolsRegex参数
spring:
cloud:
gateway:
routes:
- id: rewritelocationresponseheader_route
uri: http://example.org
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
RewriteResponseHeader Filter
:重写响应头 接受三个参数:header 名称
、regexp
和替换参数
。使用Java正则表达式灵活地重写响应头值
spring:
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: https://example.org
filters:
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
SaveSession Filter
: 保存Session
不接受参数,在向下游转发请求之前强制执行WebSession::save
操作
spring:
cloud:
gateway:
routes:
- id: save_session
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession
-
SecureHeaders Filter
:向响应中添加一些安全相关的请求头 -
SetPath Filter
:通过模板的方式改写请求路径
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment} # 路径/red/{segment}被改写成/{segment}。例如请求/red/test将变成请求/test
-
SetRequestHeader Filter
: 设置请求头 -
SetResponseHeader Filter
:设置响应头 -
SetStatus Filter
:设置HTTP 响应码 -
StripPrefix Filter
: 去除请求路径前缀 接受一个参数:层级数。去除指定层级的路径前缀
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
-
Retry Filter
: 重试 -
SetRequestHostHeader Filter
:设置请求Host
-
ModifyRequestBody Filter
: 修改请求体
需要使用java bean 配置
ModifyResponseBody Filter
:修改响应体
需要使用java bean 配置
-
Token Relay Filter
:Token
中继过滤器 -
Default Filters
: 默认过滤器,应用于所有路由
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin
全局Filter
Spring Cloud Gateway
提供了一个全局过滤器接口GlobalFilter
。GlobalFilter
接受两个参数:ServerWebExchange
和GatewayFilterChain
,代表请求和响应。一些通用操作可以如(鉴权、记录日志等)可以通过实现GlobalFilter
接口完成。
GlobalFilter
通常和Ordered
接口一齐实现
GlobalFilter
默认实现类
Spring Cloud Gateway
为GlobalFilter
提供了如下实现类: