Spring Cloud Gateway介绍(一)
特性
- 基于 Java 8 编码
- 基于 Spring Framework 5 + Project Reactor + Spring Boot 2.0 构建
- 支持动态路由,能够匹配任何请求属性上的路由
- 支持内置到 Spring Handler 映射中的路由匹配
- 支持基于 HTTP 请求的路由匹配(Path、Method、Header、Host 等等)
- 集成了 Hystrix 断路器
- 过滤器作用于匹配的路由
- 过滤器可以修改 HTTP 请求和 HTTP 响应(增加/修改 Header、增加/修改请求参数、改写请求 Path 等等)
- 支持 Spring Cloud DiscoveryClient 配置路由,与服务发现与注册配合使用
- 支持限流
引入
POM配置
<properties>
<spring.boot.version>2.2.4.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR1</spring.cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 引入 Spring Cloud Gateway 相关依赖,使用它作为网关,并实现对其的自动配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
如果引入了starter,但是又不想让gateway生效,可以设置
spring.cloud.gateway.enabled=false
Spring cloud gateway构建于spring boot 2.x,spring webflux,reactor。需要spring webfluxr提供的netty运行环境,不能使用传统的servlet容器或者构建成WAR包。
术语
Route
Route 是 gateway 中最基本的组件之一,表示一个具体的路由信息载体。
Route 主要定义了如下几个部分:
① id,标识符,区别于其他 Route。
② destination uri,路由指向的目的地 uri,即客户端请求最终被转发的目的地。
③ order,用于多个 Route 之间的排序,数值越小排序越靠前,匹配优先级越高。
④ predicate,谓语,表示匹配该 Route 的前置条件,即满足相应的条件才会被路由到目的地 uri。
⑤ gateway filters,过滤器用于处理切面逻辑,如路由转发前修改请求头等。
Predicate
Predicate 即 Route 中所定义的部分,用于条件匹配。
参考 Java 8 提供的 Predicate 和 Function,输入类型是Spring Framework ServerWebExchange,可以匹配HTTP请求的任何信息,例如headers,cookies,parameters
Filter
Filter 最终是通过 filter chain 来形成链式调用的,每个 filter 处理完 pre filter 逻辑后委派给 filter chain,filter chain 再委派给下一下 filter。
怎么工作
① Gateway 接收客户端请求。
② 客户端请求与路由信息进行匹配,匹配成功的才能够被发往相应的下游服务。
③ 请求经过 Filter 过滤器链,执行 pre 处理逻辑,如修改请求头信息等。
④ 请求被转发至下游服务并返回响应。
⑤ 响应经过 Filter 过滤器链,执行 post 处理逻辑。
⑥ 向客户端响应应答。
配置Route Predicate Factories和Gateway Filter Factories
快捷方式
Filter名称后跟等号(=),后跟以逗号分开的参数
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- Cookie=mycookie,mycookievalue
完整方式
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- name: Cookie
args:
name: mycookie
regexp: mycookievalue
Route Predicate Factories
Spring Cloud Gateway使用Handler Mapping来确定Route,内部指定了很多predicate Factories用于匹配HTTP请求的不同属性。
可以通过and语句来合并多个route predicate。
- After:匹配时间晚于指定日期的HTTP请求。
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
- Before:匹配时间早于指定日期的HTTP请求。
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
- Between:匹配时间介于指定日期范围的HTTP请求。
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
- Cookie:匹配包含指定cookie名称和值(regex,java正则表达式)的HTTP请求。
predicates:
- Cookie=chocolate, ch.p
- Header:匹配包含指定header名称和值(regex,java正则表达式)的HTTP请求。
predicates:
- Header=X-Request-Id, \d+
- Host:匹配指定host。
predicates:
- Host=**.somehost.org,**.anotherhost.org
- Method:匹配指定method
predicates:
- Method=GET,POST
- Path:匹配路径,支持Url 模板。
predicates:
- Path=/red/{segment},/blue/{segment}
- Query:如果包含指定查询参数(参数名称或可选的regex),则匹配。
predicates:
- Query=green
- RemoteAddr:匹配远程地址
predicates:
- RemoteAddr=192.168.1.1/24
- Weight : 权重路由,用于实现了负载均衡的情况。
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
默认情况下,RemoteAddr 使用进入的请求获取RemoteAddr。如果gateway在一个代理层后,则有可能获取不到真实的IP。
可以指定一个Resolver自定义RemoteAddressResolver,来解析RemoteAddr,Gateway实现了一个非默认的基于 X-Forwarded-For header的XForwardedRemoteAddressResolver。
GatewayFilter Factories
Route Filters用于修改进入的HTTP Request和返回的HTTP Response。
-
AddRequestHeader
:增加Request Header,可识别PATH或HOST中的变量。
filters:
- AddRequestHeader=X-Request-red, blue
-
AddRequestParameter
:增加request parameter到query string,可识别PATH或HOST中的变量。
filters:
- AddRequestParameter=color, blue
-
AddResponseHeader
:增加Reponse Header,可识别PATH或HOST中的变量。
predicates:
- Host: {segment}.myhost.org
filters:
- AddResponseHeader=foo, bar-{segment}
- DedupeResponseHeader :剔除响应头中重复的值,需要去重的Header名称及去重策略(可选)。
去重策略:
- RETAIN_FIRST:默认值,保留第一个值
- RETAIN_LAST:保留最后一个值
- RETAIN_UNIQUE:保留所有唯一值,以它们第一次出现的顺序保留
filters:
# 若需要去重的Header有多个,使用空格分隔
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
-
Hystrix
:为路由引入Hystrix的断路器保护
Hystrix是Spring Cloud第一代容错组件,不过已经进入维护模式,未来Hystrix会被Spring Cloud移除掉,取而代之的是Alibaba Sentinel/Resilience4J。
filters:
- Hystrix=myCommandName
或者
filters:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/incaseoffailureusethis
- RewritePath=/consumingserviceendpoint, /backingserviceendpoint
- CircuitBreaker:建议使用Resilience4J
filters:
- CircuitBreaker=myCircuitBreaker
-
FallbackHeaders
:为fallbackUri的请求头中添加具体的异常信息
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
:从已存在header中获取值,新增一个header(fromHeader,toHeader)
filters:
- MapRequestHeader=Blue, X-Request-Red
-
PrefixPath
:为原始请求路径添加前缀
filters:
- PrefixPath=/mypath
-
PreserveHostHeader
:为请求添加一个preserveHostHeader=true的属性,路由过滤器会检查该属性以决定是否要发送原始的Host
filters:
- PreserveHostHeader
-
RequestRateLimiter
:用于对请求限流,限流算法为令牌桶
参数:keyResolver、rateLimiter、statusCode、denyEmptyKey、emptyKeyStatus
redisRateLimiter
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1
-
RedirectTo
:将原始请求重定向到指定的URL。参数:http状态码及重定向的url
filters:
- RedirectTo=302, https://acme.org
-
RemoveRequestHeader
:为原始请求删除某个Header,参数:header名称
filters:
- RemoveRequestHeader=X-Request-Foo
-
RemoveResponseHeader
:为原始响应删除某个Header,参数:header名称
filters:
- RemoveResponseHeader=X-Response-Foo
-
RemoveRequestParameter
:为原始请求删除某个parameter,参数:parameter名称
filters:
- RemoveRequestParameter=red
-
RewritePath
:重写原始的请求路径 ,参数:原始路径正则表达式以及重写后路径的正则表达式。$\替换$,不然表示变量。
#正则表达式 替换
filters:
- RewritePath=/red(?<segment>/?.*), $\{segment}
RewriteLocationResponseHeader
:重写Location响应header的值。参数:stripVersionMode
, locationHeaderName
, hostValue
, and protocolsRegex。
stripVersionMode的值:
-
NEVER_STRIP
即使原始请求路径不包含任何版本,也不会剥离版本。 -
AS_IN_REQUEST
仅当原始请求不包含版本时,版本才会被剥离。 -
ALWAYS_STRIP
即使原始请求路径包含版本,也会删除版本。
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
-
RewriteResponseHeader
:正则表达式重写响应头的值。参数:name
,regexp
和replacement
filters:
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=*
-
SaveSession
:强制执行WebSession::save
操作
filters:
- SaveSession
-
SecureHeaders:
添加了许多头到响应中。
- X-Xss-Protection:1 (mode=block)
- Strict-Transport-Security (max-age=631138519)
- X-Frame-Options (DENY)
- X-Content-Type-Options (nosniff)
- Referrer-Policy (no-referrer)
- Content-Security-Policy (default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline)'
- X-Download-Options (noopen)
- X-Permitted-Cross-Domain-Policies (none)
要修改默认值,可以在spring.cloud.gateway.filter.secure-headers命令空间修改。
要禁用yixie值,可以通过spring.cloud.gateway.filter.secure-headers.disable设置,用逗号分开
spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
-
SetPath
:采用路径template
参数。通过允许路径的模板片段,提供了一种操作请求路径的简单方法
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}
-
SetRequestHeader
:设置请求header的值
filters:
- SetRequestHeader= username,admin
-
SetResponseHeader
:
filters:
- SetResponseHeader=X-Response-Red, Blue
-
SetStatus
:设置响应状态。status
, 必须是一个有效的SpringHttpStatus
. 它可以是整数值404
或是枚举的字符串表示形式NOT_FOUND
filters:
- SetStatus=401
-
StripPrefix
:切除请求路径前缀,参数:切除多少段(以/分割)
predicates:
- Path=/name/**
filters:
#可以将/user/name/stripPrefix 地址 切除前面两段,所以最后转发到下游的地址是/stripPrefix
- StripPrefix=2
-
Retry
:重试设置
filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY
methods: GET,POST
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false
-
RequestSize
:限制请求大小。
filters:
- name: RequestSize
args:
#默认为B,可以设置为KB,MB
maxSize: 5000000
-
SetRequestHost
:重写host
filters:
- name: SetRequestHost
args:
host: example.org
-
ModifyRequestBody
:将请求体进行修改。
只能通过java代码设置。
-
ModifyResponseBody
:对响应体进行修改
只支持Java配置。
- Default:通过spring.cloud.gateway.default-filters 设置默认filters。
pring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin
参考
官方文档:https://cloud.spring.io/spring-cloud-gateway/2.2.x/reference/html/
上一篇: JS+CSS3实现的简易钟表效果示例
推荐阅读
-
Spring Cloud GateWay 路由转发规则介绍详解
-
Spring Cloud Gateway网关XSS过滤Filter
-
详解spring cloud构建微服务架构的网关(API GateWay)
-
Spring Cloud zuul自定义统一异常处理实现方法
-
Spring Cloud Gateway入门解读
-
Spring Cloud学习教程之Zuul统一异常处理与回退
-
[Spring cloud 一步步实现广告系统] 16. 增量索引实现以及投送数据到MQ(kafka)
-
Spring Cloud Gateway 服务网关快速实现解析
-
详解Spring Cloud Feign 熔断配置的一些小坑
-
Spring Cloud Gateway 之请求坑位[微服务IP不同请求会失败]