什么是网关?理解成火车站的检票口,统一 检票
网关优点: 统一进行操作,去处理一些问题
路由(请求转发)
起到转发的作用,比如有接口 A 和接口 B, 网关会记录这些信息,根据用户访问的地址和参数,转发请求到对应的接口(服务器 / 集群)
用户 a 调用接口 A
/a => 接口 A
/b => 接口 B
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories
负载均衡
在路由的基础上可以转发到某一个服务器
/c => 服务A / 集群 A(随机转发到其中的某一个机器)
uri 从固定地址改成 b:xx
统一鉴权
判断用户是否有权限进行操作,无论访问什么接口,我都统一去判断权限,不用重复写
统一处理跨域
网关统一处理跨域,不用在每个项目单独处理
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#cors-configuration
统一业务处理
把每个项目中都要做的通用逻辑放到上层(网关),统一处理,比如本项目的次数统计
访问控制
黑白名单,比如限制 DDOS IP – 将已知的恶意 IP 地址添加到黑名单中,从而防止这些 IP 地址对系统发起 DDoS 攻击。
黑白名单是一种常见的网络安全策略,用于限制或允许 特定的 IP 地址或 IP 地址范围 访问网络资源。限制 DDoS(分布式拒绝服务攻击)IP 是黑名单的一个典型用例。
发布控制
灰度发布,比如上线新接口,先给新接口分配 20%流量,老接口80%,再慢慢调整比例
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#the-weight-route-predicate-factory
流量染色
区分用户来源
给请求(流量)添加一些标识,一般是设置请求头中,添加新的请求头
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#the-addrequestheader-gatewayfilter-factory
全局染色:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#default-filters
接口保护
限制请求
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#requestheadersiz-gatewayfilter-factory
信息脱敏
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#the-removerequestheader-gatewayfilter-factory
降级(熔断)进行兜底
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#fallback-headers
限流
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#the-requestratelimiter-gatewayfilter-factory
超时时间 超时就中断
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#http-timeouts-configuration
重试(业务保护):
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#the-retry-gatewayfilter-factory
统一日志
统一的请求,响应信息记录
统一文档
将下游项目的文档进行聚合,在一个页面统一查看
建议用:https://doc.xiaominfo.com/docs/middleware-sources/aggregation-introduction
网关的分类
参考文章:https://blog.csdn.net/qq_21040559/article/details/122961395
实现
网关技术选型:https://zhuanlan.zhihu.com/p/500587132
全部内容基本来自官网
官网:https://spring.io/projects/spring-cloud-gateway
官方文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference//html/
中文文档:https://springdoc.cn/spring-cloud-gateway/#gateway-starter
新建项目
在 IDEA 中新建项目 勾选 Gateway、Lombok
参考官网 get started 中的实例代码
@SpringBootApplication
public class DemogatewayApplication {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("/get")
.uri("http://httpbin.org"))
.route("host_route", r -> r.host("*.myhost.org")
.uri("http://httpbin.org"))
.route("rewrite_route", r -> r.host("*.rewrite.org")
.filters(f -> f.rewritePath("/foo/(?.*)" , "/${segment}"))
.uri("http://httpbin.org"))
.route("hystrix_route", r -> r.host("*.hystrix.org")
.filters(f -> f.hystrix(c -> c.setName("slowcmd")))
.uri("http://httpbin.org"))
.route("hystrix_fallback_route", r -> r.host("*.hystrixfallback.org")
.filters(f -> f.hystrix(c -> c.setName("slowcmd").setFallbackUri("forward:/hystrixfallback")))
.uri("http://httpbin.org"))
.route("limit_route", r -> r
.host("*.limited.org").and().path("/anything/**")
.filters(f -> f.requestRateLimiter(c -> c.setRateLimiter(redisRateLimiter())))
.uri("http://httpbin.org"))
.build();
}
}
编写代码:
@SpringBootApplication
public class XuanapiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(XuanapiGatewayApplication.class, args);
}
// 构建自定义路由
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("to_baidu", r -> r.path("/baidu") // 定义路由名称为 "to_baidu"
.uri("http://www.baidu.com/")) // 将匹配的请求转发到 "http://www.baidu.com/"
.build();
}
}
在此配置类中,定义了一个名为 "to_baidu"
的路由规则,当请求的路径是 "/baidu"
时,将被路由到 “http://www.baidu.com/”。
官方文档如下
ServerWebExchange
. This lets you match on anything from the HTTP request, such as headers or parameters.GatewayFilter
that have been constructed with a specific factory. Here, you can modify requests and responses before or after sending the downstream request.解析:
路由(根据什么条件,转发到哪里)
谓词 / 断言(一组规则,条件,用来确定如何转发路由)
过滤器:对请求进行一系列的处理,比如添加请求头,添加请求参数
配置式 (方便,规范)能用就用
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
编程式(灵活,相对麻烦) – 就是自己编写代码定义
官网地址: https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories
目录
The After Route Predicate Factory
当前时间在这个时间之后,就会访问当前这个路由
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
The Before Route Predicate Factory
当前时间在这个时间之前,就会访问当前这个路由
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
The Between Route Predicate Factory
当前时间在这个时间之间,就会访问当前这个路由
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]
The Cookie Route Predicate Factory
如果你的请求头cookie的是chocolate,它的值是ch.p,就会访问当前这个路由
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
The Header Route Predicate Factory
如果你的请求头包含 X-Request-Id
这样一个请求头,并且,它的值符合正则表达式的规则,就会访问当前这个路由
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
The Host Route Predicate Factory
如果你的访问的是这个 **.somehost.org,.anotherhost.org
,域名,就会访问当前这个路由
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
The Method Route Predicate Factory
如果你的请求类别是这个 GET、POST,就会访问当前这个路由
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
The Path Route Predicate Factory
如果你的访问的地址是以这些 /red/{segment},/blue/{segment}
路径作为前缀,就会访问当前这个路由({segment}
花括号定义占位符)
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
参考:https://springdoc.cn/spring-cloud-gateway/#path
The Query Route Predicate Factory
根据查询条件,比如 red greet green,就会访问当前这个路由
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree.
The RemoteAddr Route Predicate Factory
根据远程地址,比如你的用户的 ip地址是 192.168.1.1/24,就会访问当前这个路由
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
The Weight Route Predicate Factory
根据你设置的权重,给你把同一个访问的地址,重定到不同的服务,轻松实现发布控制
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
The XForwarded Remote Addr Route Predicate Factory
从请求头中如果拿到 XForwarded 这个请求头的地址 192.168.1.1/24 就会访问当前这个路由
spring:
cloud:
gateway:
routes:
- id: xforwarded_remoteaddr_route
uri: https://example.org
predicates:
- XForwardedRemoteAddr=192.168.1.1/24
官网文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories
基本功能:对请求头、请求参数、响应头的增删改查
1.添加请求求头
2.添加请求参数
3.添加响应头
4.降级
5.限流
6.重试
The AddRequestHeader
GatewayFilter
Factory
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-red, blue
The AddRequestParameter
GatewayFilter
Factory
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=red, blue
这将为所有匹配的请求在下游请求的查询字符串中添加 red=blue
。
The AddResponseHeader
GatewayFilter
Factory
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Red, Blue
这将把 X-Response-Red:Blue
header 添加到所有匹配请求的下游响应的 header 中。
The DedupeResponseHeader
GatewayFilter
Factory
spring:
cloud:
gateway:
routes:
- id: dedupe_response_header_route
uri: https://example.org
filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
保留策略:第一,最后,随机
The DedupeResponseHeader
filter also accepts an optional strategy
parameter. The accepted values are RETAIN_FIRST
(default), RETAIN_LAST
, and RETAIN_UNIQUE
.
在 Spring Cloud Gateway 的 DedupeResponseHeader 过滤器中,可以使用 strategy 参数来指定响应头的保留策略。该过滤器的作用是去重响应头,确保在多次请求后只保留一个相同的响应头。
可接受的 strategy 参数值有三种:
RETAIN_FIRST:默认值。表示保留第一个出现的响应头,后续相同的响应头会被忽略,只保留第一个。
RETAIN_LAST:表示保留最后一个出现的响应头,之前的相同响应头会被忽略,只保留最后一个。
RETAIN_UNIQUE:表示保留所有不重复的响应头,不论其出现的顺序。
通过设置不同的保留策略,可以控制响应头的去重方式,以满足具体的需求。默认情况下,使用 RETAIN_FIRST 策略,保留第一个出现的响应头。
Spring Cloud CircuitBreaker GatewayFilter Factory
需要引入 spring-cloud-starter-circuitbreaker-reactor-resilience4j
包
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4jartifactId>
dependency>
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingServiceEndpoint
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis
- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint
这个路由规则定义了一个对 “/consumingServiceEndpoint” 路径的请求转发到名为 “backing-service” 的服务的 8088 端口。同时,还使用了熔断器来保护后端服务,当后端服务发生故障时,会使用 “/inCaseOfFailureUseThis” 作为回退 URI,以保证系统的稳定性和可用性。
降级处理器,写一下降级规则
The FallbackHeaders
GatewayFilter
Factory
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
id: ingredients: 这个路由规则的唯一标识符为 “ingredients”。
uri: lb://ingredients: 当请求匹配到该路由规则时,它会被转发到名为 “ingredients” 的服务。“lb://” 是 Spring Cloud Gateway 中定义的 LoadBalancer URI Scheme,表示通过负载均衡方式选择后端服务。
predicates: 这里使用 Path 断言器,表示请求的路径必须以 “/ingredients/” 开头时,才会匹配到这个路由规则。
filters: 这里定义了一个过滤器。
CircuitBreaker: 这是 Spring Cloud Gateway 的熔断器过滤器,它用于实现熔断机制。在这个配置中,指定了一个名为 “fetchIngredients” 的熔断器,当后端服务发生故障时,将会使用 “/fallback” 作为备用的回退 URI。
id: ingredients-fallback: 这个路由规则的唯一标识符为 “ingredients-fallback”。
uri: http://localhost:9994: 当请求匹配到该路由规则时,它会被转发到 “http://localhost:9994”,即本地的另一个服务。
predicates: 这里使用 Path 断言器,表示请求的路径必须为 “/fallback” 时,才会匹配到这个路由规则。
filters: 这里定义了一个过滤器。
FallbackHeaders: 这是一个自定义的过滤器,用于在请求发生回退时设置响应头信息。在这个配置中,指定了响应头中的 “Test-Header” 字段为 “executionExceptionTypeHeaderName”,用于标识回退的原因类型。
API 网关中的降级和熔断功能主要体现在以下几个方面:
The MapRequestHeader
GatewayFilter
Factory
如果你的 请求头 里面有 Blue,会把 Blue 的值给 X-Request-Red,相当于做了映射
spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Blue, X-Request-Red
The PrefixPath
GatewayFilter
Factory
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
这会将 /mypath
作为所有匹配请求的路径的前缀。因此,对 /hello
的请求将发送到 /mypath/hello
。
The PreserveHostHeader
GatewayFilter
Factoryatewayfilter-factory
请求头转发的时候,有时候 host值 会变,这个可以保证不变
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
# 用于保留请求中的Host头信息。
- PreserveHostHeader
The RequestRateLimiter
GatewayFilter
Factory
一般会使用 redis+令牌桶算法
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
RequestHeaderSize
GatewayFilter
Factory
请求保护
spring:
cloud:
gateway:
routes:
- id: requestheadersize_route
uri: https://example.org
filters:
- RequestHeaderSize=1000B
The RemoveRequestHeader Gateway Filter Factory
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
This removes the X-Request-Foo
header before it is sent downstream.
这将在发送到下游之前删除 X-Request-Foo
标头。
The RewritePath
GatewayFilter
Factory
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/red/**
filters:
- RewritePath=/red/?(?>.*), /$\{segment}
这个配置中定义了一个路由规则,它会将所有以 “/red/” 开头的请求转发到 “https://example.org”,并将 “/red/” 后面的路径作为子路径添加到目标 URI 上,实现了路径重写的功能。例如,对于请求 “/red/test”,将被转发到 “https://example.org/test”。
The Retry GatewayFilter
Factory
自动帮你重试接口,降级重试
spring:
cloud:
gateway:
routes:
# 定义一个名为"retry_test"的路由规则
- id: retry_test
# 转发到"http://localhost:8080/flakey"的目标URL
uri: http://localhost:8080/flakey
predicates:
# 当请求的Host为任意子域名.retry.com时,匹配该路由规则
- Host=*.retry.com
filters:
# 定义一个重试过滤器
- name: Retry
args:
# 当请求失败时,最多重试3次(包括初始请求)
retries: 3
# 定义需要重试的HTTP状态码,这里设置为BAD_GATEWAY
statuses: BAD_GATEWAY
# 定义需要重试的HTTP请求方法,这里设置为GET和POST
methods: GET,POST
# 定义重试的时间间隔策略
backoff:
# 第一次重试的时间间隔为10毫秒
firstBackoff: 10ms
# 最大重试时间间隔为50毫秒
maxBackoff: 50ms
# 重试时间间隔的增长因子,每次重试的时间间隔将是上一次的倍数
factor: 2
# 这里设置为false,表示每次重试的时间间隔都是根据初始值来计算的,而不是上一次重试的值
basedOnPreviousValue: false
这个配置中定义了一个路由规则,它会将所有 Host 为任意 子域名.retry.com
的请求转发到 “http://localhost:8080/flakey”,并在请求失败时进行最多 3 次的重试,重试的时间间隔为 10ms、20ms 和 40ms,最大不超过 50ms,仅对 GET 和 POST 方法的请求进行重试,并且仅在返回的 HTTP 状态码为 BAD_GATEWAY 时进行重试。
目的
Default Filters
spring:
cloud:
gateway:
default-filters: # 设置默认的过滤器
- AddResponseHeader=X-Response-Default-Red, Default-Blue # 添加响应头的过滤器,给响应头添加 X-Response-Default-Red 和 Default-Blue 两个字段
- PrefixPath=/httpbin # 前缀路径过滤器,给请求路径添加前缀 /httpbin
全局染色:在这里,它添加了一个名为 X-Response-Default-Red
的响应头,并设置其值为 Default-Blue
。
Global Filters
自定义过滤器
@Bean
public GlobalFilter customFilter() {
return new CustomGlobalFilter();
}
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("custom global filter");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1;
}
}
Global timeouts
配置 http 超时
spring:
cloud:
gateway:
httpclient:
connect-timeout: 1000
response-timeout: 5s
跨域配置
spring:
cloud:
gateway:
globalcors: # 全局CORS跨域配置
cors-configurations: # 定义跨域配置
'[/**]': # 匹配所有路径
allowedOrigins: "https://docs.spring.io" # 允许的来源(域名),这里只允许来自 https://docs.spring.io 的请求
allowedMethods: # 允许的HTTP
对于所有 GET 请求的路径,允许来自 docs.spring.io
的请求的 CORS(跨源资源共享)请求。