spring cloud gateway(网关)简介
Spring Cloud Gateway 是一个基于 Spring WebFlux 构建的强大且广泛使用的 API 网关。它负责处理所有进入的请求,并将它们路由到相应的后端服务。
Gateway 的主要作用:
- 统一的入口点 (Single Entry Point):
- 它为所有的客户端请求提供了一个唯一的入口地址。客户端不需要知道后端各个微服务的具体地址,只需要与 Gateway 交互。
- 这样可以简化客户端的开发和维护,降低了客户端与后端服务之间的耦合度。
- 请求路由 (Request Routing):
URL 重写是 API 网关一个非常常见且强大的功能。
- 根据预先配置的路由规则,将客户端的请求转发到相应的后端微服务实例。
- 路由规则可以基于请求的路径、HTTP 方法、请求头、查询参数等多种条件进行灵活配置。
- 安全控制 (Security):
- 可以在 Gateway 层集中处理身份验证和授权,例如校验 JWT、Session 等。
- 避免了在每个微服务中都进行重复的安全控制,提高了安全性和可维护性。
- 监控和可观察性 (Monitoring and Observability):
- 方便在 Gateway 层进行统一的请求日志记录、性能监控和链路追踪。
- 可以更容易地了解整个系统的运行状况和性能瓶颈。
- 请求和响应修改 (Request and Response Modification):
- 允许在请求转发到后端服务之前或之后对请求头、请求体、响应头、响应体等进行修改。
- 例如,可以添加统一的请求头、压缩响应数据等。
- 流量控制 (Traffic Control):
- 可以实现限流、熔断、降级等流量管理策略,保护后端服务免受过载的影响,提高系统的稳定性。
- 负载均衡 (Load Balancing):
- 可以集成负载均衡器(如 Spring Cloud LoadBalancer、Ribbon 等),将请求分发到后端服务的多个实例,提高系统的可用性和吞吐量.
整体架构
spring cloud gateway的几个重要概念:
- 路由 (Routes): 网关的基本构建模块。一个路由定义了一个断言 (predicate) 和一组过滤器 (filters)。当一个请求匹配了断言,它就会在经过定义的过滤器处理后被路由到指定的 URI。
- 断言 (Predicates): 这些是 Java 8 的 Function 接口的实现,它们基于各种请求属性评估结果为 true 或 false。常见的断言包括匹配路径、请求头、查询参数和 HTTP 方法。
- 过滤器 (Filters): 这些是 GatewayFilter 接口的实例,允许你修改传入的 HTTP 请求和传出的 HTTP 响应。过滤器可以执行各种任务,例如添加请求头、日志记录、速率限制、请求重写和熔断。
- 网关处理器映射 (Gateway Handler Mapping): 这个组件负责将传入的 Web 请求映射到已配置的路由。
- 网关 Web 处理器 (Gateway Web Handler): 这个处理器接收到匹配路由的请求,并应用过滤器链,然后将请求转发到目标 URI。
下图来自spring cloud官网,展示网关是如何工作的
Gateway Handler Mapping (GHM):
- 负责接收 WebFlux 处理的 HTTP 请求。
- 将请求的属性(例如路径、HTTP 方法、Headers 等)与配置的路由定义进行匹配。
- 当找到匹配的路由时,GHM 会将请求交给 Gateway Web Handler 处理。
- 可以将 GHM 视为请求的“分发器”。
Gateway Web Handler (GWH):
- 接收 GHM 匹配到的路由信息和原始的 HTTP 请求。
- 负责执行与该路由关联的 Filter Chain (过滤器链)。
- Filter Chain 是一个有序的 GatewayFilter 实例列表,它们按照配置的顺序被执行。
Gateway Filter Chain (过滤器链):
- 由一系列的 GatewayFilter 组成,每个 Filter 都负责执行特定的逻辑。
- Filter 可以拦截请求和响应,并对其进行修改。
- Filter 的类型包括:
- Pre-Filters (前置过滤器): 在请求被路由到后端服务之前执行,例如添加请求头、记录日志、进行身份验证等。
- Post-Filters (后置过滤器): 在收到后端服务的响应之后执行,例如修改响应头、记录响应日志等。
- Spring Cloud Gateway 内置了许多常用的 Filter,同时也允许开发者自定义 Filter。
Route Definition Locator:
- 负责加载和管理 Gateway 的路由配置信息。
- 路由配置可以来源于多种方式,例如:
- 配置文件 (application.yml 或 application.properties)
- Java 代码
- 服务发现机制 (DiscoveryClient)
- 自定义的 Route Definition Locator
Route Predicate Factories:
- 用于创建 Route Predicate 实例。
- 每个 Predicate Factory 对应一种断言规则,例如 Path、Method、Header、Query 等。
- 在路由配置中使用的谓词表达式会被解析成对应的 Route Predicate 实例,用于匹配请求。
Gateway Filter Factories:
- 用于创建 GatewayFilter 实例。
- 每个 Filter Factory 对应一种 Gateway Filter 的实现,例如 AddRequestHeader、RewritePath、RateLimiter 等。
- 在路由配置中使用的 Filter 定义会被解析成对应的 GatewayFilter 实例。
WebClient (基于 Netty 的非阻塞 HTTP 客户端):
- 用于将经过 Filter Chain 处理后的请求转发到后端的微服务实例。
- Spring WebFlux 的核心组件,支持异步和非阻塞的 I/O 操作,保证 Gateway 的高性能。
客户端发起请求到 Spring Cloud Gateway。Gateway Handler Mapping (GHM) 接收到请求。
GHM 根据配置的 Route Definitions 和 Route Predicates 匹配到对应的路由。如果找到匹配的路由,Gateway Web Handler (GWH) 获取该路由相关的 Filter Chain。
Filter Chain 中的 Pre-Filters 按照配置顺序依次执行,可以修改请求头、参数等。
请求被转发到 WebClient。WebClient 将请求发送到 后端微服务 (目标 URI,可能是硬编码的地址或通过服务发现获取的地址)。后端微服务 处理请求并返回响应。WebClient 接收到后端服务的响应。
Filter Chain 中的 Post-Filters 按照配置顺序反向执行,可以修改响应头、响应体等。Gateway 将最终的响应返回给客户端。
快速集成
引入依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>
spring-cloud-starter-gateway是基础依赖,注册中心使用哪个依赖哪个。lb://serviceid方式配置要添加依赖spring-cloud-starter-loadbalancer。
application.yaml配置文件配置
spring:cloud:gateway:routes:- id: user-service # 路由的唯一标识符uri: http://localhost:8081 # 后端服务的 URIpredicates:- Path=/users/** # 当请求路径匹配 /users/** 时,路由到 user-servicefilters:- AddRequestHeader=X-Request-ID, ${random.uuid()} # 添加一个请求头- id: product-serviceuri: http://localhost:8082predicates:- Path=/products/**- Method=GET,POST # 只匹配 GET 和 POST 请求filters:- AddRequestHeader=X-Source, gateway # 添加另一个请求头- RewritePath=/products/(?<segment>.*), /$\\{segment} # URL 重写,移除 /products 前缀
spring.cloud.gateway.routes: 定义路由列表。id是每个路由的唯一标识符,用于管理和监控。url是请求将被转发到的后端服务的 URI。可以是 HTTP 地址,也可以是使用服务发现的服务名称 (例如 lb://user-service,需要集成服务发现组件如 Nacos、Eureka、Consul)。
predicates: 定义路由匹配的条件。只有当请求满足所有 Predicate 时,该路由才会被选中。常用的 Predicate 包括 Path、Method、Header、Query 等。
filters: 定义应用于匹配路由的过滤器列表。过滤器用于在请求被转发到后端服务之前或之后对请求和响应进行修改。常用的 Filter 包括 AddRequestHeader、RewritePath、StripPrefix、RateLimiter 等。