【Spring Cloud 微服务】2.守护神网关Gateway
目录
1.API网关的作用
2.Spring Cloud Gateway 是什么?
3.核心由来与背景
1. 微服务架构的挑战:
2. API 网关模式的兴起:
3. Zuul 的局限性:
4. Spring Cloud Gateway 的诞生:
4.核心特征:
5.核心概念与工作原理
1. 路由 (Route)
2. 断言 (Predicate)
3. 过滤器 (Filter)
工作原理流程
6.如何与 Spring Cloud 集成
第一步:创建项目并添加依赖
第二步:配置文件 (application.yml)
第三步:编写简单的降级控制器
第四步:主启动类
7.集成案例:一个简单的路由
总结
1.API网关的作用
在微服务中,每个模块都是单独的服务,每个服务之间通过Fegin或着RPC之间进行通信,那我们客户端如何与不同服务进行调用呢?
但是带来以下几个问题
在我们引入APi网关之后
架构优势:
- 简化客户端:客户端只需知道网关的地址,不需要了解所有微服务的细节
- 安全性:可以在网关层面统一实施安全策略
- 可观察性:集中收集日志、指标和追踪信息
- 灵活性:可以在不影响客户端的情况下重构后端服务
2.Spring Cloud Gateway 是什么?
Spring Cloud Gateway 是基于 Spring 5、Spring Boot 2 和 Project Reactor 等技术构建的 API 网关。它的核心是一个建立在 Spring Framework 之上的反向代理,旨在为微服务架构提供一种简单、有效且统一的方式来路由到 API,并提供跨领域的关注点,如:安全、监控/指标和弹性。
3.核心由来与背景
要理解 Spring Cloud Gateway 的由来,需要先了解微服务架构的演进和其前身。
1. 微服务架构的挑战:
在微服务架构中,系统被拆分为数十甚至上百个细粒度的服务。客户端(如 Web 前端、移动 App)如果直接与这些服务通信,会面临诸多问题:
- 客户端复杂性:客户端需要知道所有服务的网络位置(IP/域名)。
- 交叉关切点:每个服务都需要独立实现认证、授权、日志、限流等功能,造成代码重复和维护困难。
- 协议适配:后端微服务可能使用 gRPC、Dubbo 等协议,而外部客户端通常只接受 HTTP/HTTPS。
2. API 网关模式的兴起:
为了解决上述问题,API 网关模式 应运而生。它作为系统的唯一入口,扮演了“门卫”和“路由器”的角色,将所有非业务功能集中处理。Netflix 开源的 Zuul 是这个领域的先驱。
3. Zuul 的局限性:
Spring Cloud 早期整合了 Netflix Zuul 1.x 作为其网关解决方案。
然而,Zuul 1.x 基于 阻塞式 I/O (Servlet API) 模型。在处理大量并发连接或慢速客户端时,容易阻塞工作线程,成为性能瓶颈,无法很好地应对未来的响应式编程趋势。
4. Spring Cloud Gateway 的诞生:
为了提供一款现代化、高性能、响应式且与 Spring 生态无缝集成的官方网关,Spring 团队自己开发了 Spring Cloud Gateway。它的设计目标非常明确:
-
- 性能:基于 Netty 和 Project Reactor,提供非阻塞、异步的响应式编程模型,能够轻松处理高并发场景。
- 与 Spring 生态深度集成:天生支持通过服务发现(如 Eureka、Nacos)动态路由,与 Spring Cloud CircuitBreaker、Spring Cloud Security 等组件完美配合。
- 强大的功能:提供简单而强大的断言(Predicates) 和过滤器(Filters) 机制,可以通过配置或编程方式灵活地定义路由和请求处理逻辑。
- 面向未来:支持 WebSocket、gRPC 等现代通信协议。
简单来说,Spring Cloud Gateway 是 Spring 官方为了取代老旧的 Zuul 1.x,顺应响应式编程潮流而推出的新一代高性能 API 网关
4.核心特征:
- 建立在 Spring Framework 5、Project Reactor 和 Spring Boot 2 之上:这意味着它天生支持异步非阻塞(Reactive) 模型,能够轻松处理高并发请求,资源消耗低,性能强劲。
- 动态路由:能够与任何服务发现组件(如 Eureka, Nacos, Consul)集成,实现到微服务的动态路由。
- 请求限流:集成 Resilience4j 或 Sentinel 实现限流和熔断。
- 路径重写:可以修改转发前后的请求路径。
- 强大的过滤器(Filter):提供了丰富的、功能各异的过滤器,用于在请求转发前(Pre) 和接收响应后(Post) 执行各种逻辑(如修改请求头、添加参数、认证鉴权、记录日志等)。
5.核心概念与工作原理
要理解 Gateway,必须先掌握它的三个核心概念:路由(Route)、断言(Predicate) 和过滤器(Filter)。
1. 路由 (Route)
路由是网关最基础的部分。它由一个 ID、一个目标 URI、一组断言和一组过滤器组成。如果断言为真,则匹配该路由,请求就会被转发到目标 URI。
- id:路由的唯一标识。
- uri:最终要转发到的目标地址。可以是
lb://SERVICE-NAME
(lb 代表从注册中心负载均衡)或一个具体的http://host:port
。 - predicates:断言数组,决定什么时候使用这个路由。
- filters:过滤器数组,用于在发送下游请求之前或之后修改请求和响应。
2. 断言 (Predicate)
这是 Java 8 中的 Predicate
函数式接口。它接收一个 ServerWebExchange
对象,可以访问到请求的所有信息(如路径、方法、头、参数等),并返回布尔值。
- 作用:定义匹配条件。例如:“如果请求路径是
/api/user/**
” 或 “如果请求方法是GET
并且包含一个X-Token
头”。 - 常见断言:
Path
,Method
,Header
,Host
,Query
,Cookie
,After
,Before
等。
3. 过滤器 (Filter)
这是 Gateway 的核心功能组件,基于 Spring Framework 的 GatewayFilter
工厂构建。
- 作用:在请求被转发前(pre) 或收到响应后(post) 执行特定操作。
- 种类:
-
- Gateway Filter:作用于单个路由。
- Global Filter:作用于所有路由,实现
GlobalFilter
接口,常用于全局鉴权、日志等。
- 常见过滤器:
AddRequestHeader
,AddRequestParameter
,AddResponseHeader
,StripPrefix
,PrefixPath
,RewritePath
,Retry
,RequestRateLimiter
,Hystrix
(已不推荐,用 Resilience4j)。
工作原理流程
一个请求到达 Spring Cloud Gateway 后的处理流程,清晰地展示了其基于反应式编程模型的核心组件如何协同工作:路由定位、断言判断及过滤器链处理。
6.如何与 Spring Cloud 集成
集成非常简单,主要通过 spring-cloud-starter-gateway
依赖和配置文件即可完成。
第一步:创建项目并添加依赖
创建一个新的 Spring Boot 项目,在 pom.xml
中添加以下依赖:
<dependencies><!-- Spring Cloud Gateway 核心依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!-- 与服务发现组件集成(以Nacos为例) --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- 如果需要限流等功能,引入Resilience4j --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-circuitbreaker-reactor-resilience4j</artifactId></dependency>
</dependencies><dependencyManagement><dependencies><!-- Spring Cloud 版本管理 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>2021.0.8</version> <!-- 请使用最新稳定版 --><type>pom</type><scope>import</scope></dependency><!-- Spring Cloud Alibaba 版本管理 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2021.0.5.0</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>
第二步:配置文件 (application.yml)
这是最核心的集成部分,展示了如何配置路由、与服务发现集成、配置过滤器等。
server:port: 8080 # 网关端口spring:application:name: api-gatewaycloud:gateway:discovery:locator:enabled: true # 开启根据服务名自动创建路由的功能(可选)lower-case-service-id: true # 服务名小写routes:# 路由1: 用户服务路由- id: user-service-routeuri: lb://user-service # lb:// 表示从注册中心负载均衡发现服务predicates:- Path=/api/user/** # 断言:路径匹配- Method=GET,POST # 断言:请求方法匹配filters:- StripPrefix=1 # 过滤器:去掉路径的第一部分(/api),再转发给user-service- AddRequestHeader=X-Request-color, blue # 过滤器:添加请求头- name: RequestRateLimiter # 过滤器:请求限流args:redis-rate-limiter.replenishRate: 10 # 每秒允许的请求数redis-rate-limiter.burstCapacity: 20 # 每秒最大处理的请求数key-resolver: "#{@userKeyResolver}" # 限流策略(需自己定义Bean)# 路由2: 订单服务路由- id: order-service-routeuri: lb://order-servicepredicates:- Path=/api/order/**- After=2023-01-20T17:42:47.789-07:00[America/Denver] # 在此时间之后生效filters:- StripPrefix=1- name: CircuitBreaker # 断路器过滤器 (Resilience4j)args:name: myCircuitBreakerfallbackUri: forward:/fallback/orderServiceDown # 降级URI# 全局默认过滤器,会对所有路由生效default-filters:- AddResponseHeader=X-Response-Default-Red, Default-Blue# Nacos 服务发现与注册配置nacos:discovery:server-addr: localhost:8848# 配置限流使用的Redis(如果使用了RequestRateLimiter过滤器)redis:host: localhostport: 6379
第三步:编写简单的降级控制器
当触发熔断时,需要一个本地的 fallback
端点来返回托底信息。
@RestController
@RequestMapping("/fallback")
public class FallbackController {@GetMapping("/orderServiceDown")public ResponseEntity<String> orderServiceFallback() {return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body("订单服务暂时不可用,请稍后再试。");}
}
第四步:主启动类
主启动类非常简单,只需添加 @EnableDiscoveryClient
注解即可与 Spring Cloud 集成。
@SpringBootApplication
@EnableDiscoveryClient // 启用服务发现客户端
public class ApiGatewayApplication {public static void main(String[] args) {SpringApplication.run(ApiGatewayApplication.class, args);}
}
7.集成案例:一个简单的路由
假设你有两个服务:
user-service
(注册到 Nacos,实例地址为localhost:8081
)order-service
(注册到 Nacos,实例地址为localhost:8082
)
配置网关路由后:
- 当你访问
http://localhost:8080/api/user/1
(网关地址) - Gateway 的
Path
断言匹配到/api/user/**
StripPrefix=1
过滤器会将路径中的第一部分/api
去掉- 最终,网关会将请求负载均衡地转发到
user-service
的/user/1
这个接口上。 - 对于客户端来说,它只和网关交互,完全不知道后端微服务的具体地址,实现了解耦和统一入口。
总结
Spring Cloud Gateway 通过 路由 + 断言 + 过滤器 的组合,提供了一个强大而灵活的方式来管理微服务API的入口流量。它与 Spring Cloud 生态系统的其他组件(如服务发现、熔断器)无缝集成,通过简单的 YAML 配置即可完成大部分工作,是构建现代微服务架构不可或缺的组件。