Gateway
概述
1、这个项目提供了一个建立在 Spring 生态系统之上的 API 网关,包括 Spring 5、Spring Boot 2、Project Reactor
2、Spring Cloud Gateway 旨在提供一种简单而有效的方式对 API 进行路由,并为其提供横切关注点,如:安全、监控 / 指标、限流
3、作用:反向代理、鉴权、流量控制、熔断、日志监控等
三大核心概念
1、Route
(1)路由:构建网关的基本模块
(2)组成:ID、目标 URI、一系列断言 + 过滤器
(3)断言为 true,则匹配该路由
2、Predicate
(1)断言:参考 java.util.function.Predicate
(2)匹配 HTTP 请求中的所有内容,如:请求头、请求参数,若请求与断言匹配,则进行路由
3、Filter
(1)过滤器:Spring 框架中 GatewayFilter 实例
(2)使用过滤器,可以在请求被路由之前或之后,对请求进行修改
工作流程
1、客户端向 Spring Cloud Gateway 发出请求
(1)如果 Gateway Handler Mapping 确定一个请求与路由相匹配,它将被发送到 Gateway Web Handler
(2)Gateway Web Handler 通过一个特定于该请求的过滤器链,来将请求发送到实际服务执行业务逻辑,然后返回
(3)过滤器被虚线分割的原因:过滤器可以在代理请求发送之前和之后运行逻辑
(4)所有的“pre”过滤器逻辑都被执行,然后发出代理请求,“pre”类型的过滤器:参数校验、权限校验、流量监控、日志输出、协议转换等
(5)在代理请求发出后,“post”过滤器逻辑被运行,“post”类型的过滤器:修改响应内容、修改响应头、输出日志、流量监控等
2、在路由中定义的没有端口的 URI,其 HTTP 和 HTTPS URI 的默认端口值分别为 80 和 443
3、Handler 再通过指定的过滤器链
核心依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
配置方式(示例)
1、yaml 配置(建议)
(1)访问地址:http://localhost:9001/payment/get/**
(2)路由地址:http://localhost:8001/payment/get/**
server:
port: 9001
spring:
cloud:
gateway:
routes:
#路由ID,没有固定规则,但要求唯一,建议配合服务名
- id: payment
#匹配后提供服务的路由地址
uri: http://localhost:8001
predicates:
# 断言,路径相匹配的进行路由
- Path=/payment/get/**
2、配置类 Bean(示例)
(1)访问地址:http://localhost:9001/payment
(2)路由地址:http://localhost:8001/payment
server:
port: 9001
@Configuration
public class GateWayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
RouteLocatorBuilder.Builder routes = builder.routes();
routes.route(
//路由ID
"payment",
//断言,路径相匹配的进行路由:- Path =
r -> r.path("/payment")
//匹配后提供服务的路由地址
.uri("http://localhost:8001/payment")).build();
return routes.build();
}
}
动态路由
1、默认情况下,Gateway 根据注册中心的服务列表,以注册中心上的微服务名称为路径,创建动态路由进行转发
2、yaml 配置
(1)访问地址:http://localhost:9001/payment/get
(2)lb://serviceName 是 Spring Cloud Gateway 在微服务中自动创建的负载均衡 uri
(3)lb 为 uri 协议,表示启用 Gateway 负载均衡
(4)Gateway 在注册中心查找 serviceName 的微服务,进行负载均衡转发
server:
port: 9001
spring:
cloud:
gateway:
discovery:
locator:
#开启从注册中心动态创建路由的功能,利用微服务名进行路由
enabled: true
routes:
#路由ID,没有固定规则,但要求唯一,建议配合服务名
- id: payment
#匹配后提供服务的路由地址,lb为uri协议,表示启用Gateway负载均衡
uri: lb://cloud-payment-service
predicates:
#断言,路径相匹配的进行路由
- Path=/payment/get/**
Route Predicate Factories
1、路由断言工厂
(1)Spring Cloud Gateway 将路由匹配作为 Spring WebFlux HandlerMapping 基础设施的一部分
(2)Spring Cloud Gateway 包括许多内置的路由断言工厂,所有这些断言都与 HTTP 请求的不同属性相匹配,可以用逻辑和语句组合多个路由断言工厂
(1)接受一个参数,即 datetime(java.time.ZonedDateTime)
(2)这个断言匹配发生在指定日期时间之后的请求
(3)例:该路由与山区时间(丹佛)2017 年 1 月 20 日 17:42 之后提出的任何请求相匹配
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
3、The Before Route Predicate Factory
(1)接收一个参数,即 datetime(java.time.ZonedDateTime)
(2)这个断言匹配发生在指定日期时间之前的请求
(3)例:该路由与山区时间(丹佛)2017 年 1 月 20 日 17:42 之前提出的任何请求相匹配
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
4、The Between route predicate factory
(1)需要两个参数,datetime1 和 datetime2,它们是 java.time.ZonedDateTime 对象
(2)这个断言匹配发生在 datetime1 之后和 datetime2 之前的请求
(3)例:这个路由与 2017 年 1 月 20 日山区时间(丹佛)17:42 之后和 2017 年 1 月 21 日山区时间(丹佛)17:42 之前的任何请求相匹配,这对维护窗口可能是有用的
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]
5、The Cookie Route Predicate Factory
(1)接受两个参数,即 cookie name 和一个 regexp(Java 正则表达式)
(2)这个断言匹配具有给定名称,且其值符合正则表达式的 cookie
(3)例:这个路由匹配有一个名为 chocolate 的 cookie 的请求,其值符合 ch.p 正则表达式
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
6、The Header Route Predicate Factory
(1)需要两个参数,header 和一个 regexp(Java 正则表达式)
(2)这个谓词与具有给定名称且其值与正则表达式相匹配的头匹配
(3)例:如果请求有一个名为 X-Request-Id 的头,其值与 \d+ 正则表达式相匹配(即它有一个或多个数字的值),则该路由匹配
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
7、The Host Route Predicate Factory
(1)接受一个参数:一个主机名称模式的列表。该模式是 Ant 风格的模式,以 . 为分隔符
(2)这个断言匹配符合该模式的 Host 头
(3)例:如果请求的 Host 头的值为 www.somehost.org 或 beta.somehost.org 或 www.anotherhost.org,则该路由匹配
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
8、The Method Route Predicate Factory
(1)接受一个 methods 参数,它是一个或多个参数:要匹配的 HTTP 方法
(2)例:如果请求方式是 GET 或 POST,则该路由匹配
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
9、The Path Route Predicate Factory
(1)需要两个参数:一个 Spring PathMatcher 模式的列表、一个可选的标志 matchTrailingSlash(默认为 true)
(2)例:如果请求路径是,例如:/red/1 或 /red/1/ 或 /red/blue 或 /blue/green,该路由匹配
(3)如果 matchTrailingSlash 被设置为 false,那么请求路径 /red/1/ 将不会被匹配
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
10、The Query route predicate factory
(1)需要两个参数:一个必需的 param、一个可选的 regexp(Java 正则表达式)
(2)例:如果请求中包含一个 red 的查询参数,其值与 gree.regexp 相匹配,那么前面的路由就会匹配,所以 green 和 greet 会匹配
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree.
11、The RemoteAddr route predicate factory
(1)接受一个 sources 列表(最小尺寸为 1),它是 CIDR-notation(IPv4 或 IPv6)字符串,如:192.168.0.1/16(其中 192.168.0.1 是一个 IP 地址,16 是一个子网掩码)
(2)例:如果请求的远程地址是,例如:192.168.1.10,则该路由匹配
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
12、The Weight route predicate factory
(1)需要两个参数:group 和 weight(int)
(2)权重是按组计算的
(3)例:该路由将转发 ~80% 的流量到 weighthigh.org,~20% 的流量到 weightlow.org
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
13、The XForwarded Remote Addr route predicate factory
(1)接受一个 sources 列表(最小尺寸为 1),这些来源是 CIDR-notation(IPv4 或 IPv6)字符串,如:192.168.0.1/16(其中 192.168.0.1 是一个 IP 地址,16 是子网掩码)
(2)这个路由断言允许根据 X-Forwarded-For HTTP 头对请求进行过滤
(3)这可以与反向代理一起使用,如:负载均衡器或网络应用程序防火墙,只有当请求来自这些反向代理所使用的受信任的 IP 地址列表时,才应该被允许
(4)例:如果 X-Forwarded-For 头包含,例如:192.168.1.10,则该路由匹配
spring:
cloud:
gateway:
routes:
- id: xforwarded_remoteaddr_route
uri: https://example.org
predicates:
- XForwardedRemoteAddr=192.168.1.1/24
GatewayFilter Factories
1、路由过滤器
(1)允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应
(2)路由过滤器的范围是一个特定的路由
(3)Spring Cloud Gateway 包括许多内置的 GatewayFilter Factory,产生路由过滤器
2、生命周期
(1)pre:请求被执行前调用
(2)post:请求被执行后调用
3、种类
(1)GatewayFilter
(2)GlobalFilter
4、自定义全局过滤器(开发常用)
(1)当一个请求与路由匹配时,过滤网络处理器将 GlobalFilter 的所有实例和 GatewayFilter 的所有路由特定实例添加到一个过滤链中
(2)这个组合的过滤链由 org.springframework.core.Ordered 接口进行排序,可以通过实现 getOrder() 方法来设置这个接口,数字越小,优先级又高
(3)由于 Spring Cloud Gateway 区分过滤器逻辑执行的“pre”和“post”阶段,优先级最高的过滤器在“pre”阶段是第一个,在“host”阶段是最后一个
@Bean
public GlobalFilter customFilter() {
return new CustomGlobalFilter();
}
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
//ServerWebExchange:HTTP请求-响应交互的契约。提供对HTTP请求和响应的访问,也暴露了额外的服务器端处理相关的属性和功能,如:请求属性
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("custom global filter");
//将ServerWebExchange通过过滤链传递到下一个过滤器
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1;
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战