Spring Cloud Gateway:您的微服务保镖兼红娘!
各位看官,大家好!今天咱们不聊风花雪月,不谈人生理想,就来聊聊微服务架构中的一个重要角色:API 网关。 别听到“微服务”就觉得高深莫测,其实它就是把一个庞大的应用拆分成一个个小的、独立的服务。 想象一下,原来一个巨无霸餐厅,现在变成了各种小吃摊,各有特色,各自为战。
但是问题来了,这么多小吃摊,顾客怎么点餐?总不能让顾客直接跟每个小吃摊老板对接吧? 这时候,就需要一个“总服务台”,统一接收顾客的订单,然后分发给对应的小吃摊,这就是 API 网关的职责。
而 Spring Cloud Gateway,就是 Spring 全家桶里提供的这个“总服务台”,它像一个尽职尽责的保镖,保护着您的微服务;又像一个热情洋溢的红娘,牵线搭桥,连接着客户端和微服务。
为什么要用 API 网关?
您可能会问,直接让客户端调用微服务不行吗? 当然可以,但是直接调用会有很多问题:
- 安全问题: 直接暴露微服务,很容易受到攻击,比如恶意请求、DDoS 攻击等。
- 复杂性: 客户端需要知道每个微服务的地址,而且如果微服务地址变更,客户端也要跟着改,维护起来很麻烦。
- 重复代码: 很多通用的逻辑,比如认证、授权、日志记录等,需要在每个微服务里都实现一遍,造成代码冗余。
- 协议转换: 不同的客户端可能使用不同的协议,比如 HTTP、WebSocket 等,微服务需要支持所有协议,增加了复杂度。
- 聚合请求: 客户端可能需要调用多个微服务才能完成一个业务场景,如果让客户端自己去调用,效率很低。
有了 API 网关,这些问题就迎刃而解了:
- 统一入口: 客户端只需要跟 API 网关交互,无需关心微服务的细节。
- 安全防护: API 网关可以进行身份验证、授权、限流等安全措施,保护微服务。
- 路由转发: API 网关可以根据不同的规则,将请求转发到对应的微服务。
- 协议转换: API 网关可以进行协议转换,让微服务专注于业务逻辑。
- 请求聚合: API 网关可以将多个请求聚合成一个请求,减少客户端的请求次数。
- 跨域处理: API 网关可以统一处理跨域问题,简化客户端的开发。
- 监控和日志: API 网关可以记录请求和响应的日志,方便进行监控和分析。
总而言之,API 网关就像一个称职的管家,把微服务打理得井井有条,让客户端用起来舒舒服服。
Spring Cloud Gateway 的核心概念
Spring Cloud Gateway 的核心概念主要有两个:路由 (Route) 和 过滤器 (Filter)。
-
路由 (Route): 路由是 API 网关的基本组成单元,它定义了请求应该如何转发到对应的微服务。 一个路由包含以下几个要素:
- ID: 路由的唯一标识。
- Predicate: 断言,用于匹配请求。只有当请求满足断言条件时,才会执行该路由。
- Filters: 过滤器,用于对请求进行修改或增强。
- URI: 目标 URI,即请求最终要转发到的微服务地址。
- Order: 路由的优先级,数字越小,优先级越高。
-
过滤器 (Filter): 过滤器是 API 网关的核心功能,它用于对请求进行各种处理,比如修改请求头、添加参数、进行认证、限流等。 过滤器可以分为两种:
- GatewayFilter: 作用于单个路由,可以对请求和响应进行处理。
- GlobalFilter: 作用于所有路由,通常用于实现一些通用的功能,比如日志记录、安全认证等。
简而言之,路由就是告诉 API 网关“往哪儿走”,而过滤器就是告诉 API 网关“怎么走”。
如何配置 Spring Cloud Gateway?
配置 Spring Cloud Gateway 主要有两种方式:
- Java 代码配置: 使用 Java 代码来定义路由和过滤器,灵活性高,适合复杂的场景。
- 配置文件配置: 使用 YAML 或 Properties 文件来定义路由和过滤器,简单易懂,适合简单的场景。
接下来,我们分别来看一下这两种方式的配置方法。
1. Java 代码配置
首先,需要在 Spring Boot 项目中引入 Spring Cloud Gateway 的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
然后,创建一个配置类,使用 RouteLocatorBuilder
来定义路由:
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class GatewayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
// 第一个路由:将 /baidu 请求转发到 https://www.baidu.com
.route("baidu_route", r -> r.path("/baidu")
.uri("https://www.baidu.com"))
// 第二个路由:将 /api/user/** 请求转发到 user-service 服务,并移除 /api 前缀
.route("user_service_route", r -> r.path("/api/user/**")
.filters(f -> f.stripPrefix(1))
.uri("lb://user-service")) // lb:// 表示使用 LoadBalancerClient 进行负载均衡
// 第三个路由:将 /api/product/** 请求转发到 product-service 服务,并添加一个请求头
.route("product_service_route", r -> r.path("/api/product/**")
.filters(f -> f.addRequestHeader("X-Request-Source", "Gateway"))
.uri("lb://product-service"))
.build();
}
}
在这个例子中,我们定义了三个路由:
- baidu_route: 将所有以
/baidu
开头的请求转发到https://www.baidu.com
。 - user_service_route: 将所有以
/api/user/**
开头的请求转发到user-service
服务,并使用stripPrefix(1)
过滤器移除/api
前缀。lb://user-service
表示使用 LoadBalancerClient 进行负载均衡,user-service
是服务的名称。 - product_service_route: 将所有以
/api/product/**
开头的请求转发到product-service
服务,并使用addRequestHeader("X-Request-Source", "Gateway")
过滤器添加一个请求头X-Request-Source: Gateway
。
代码解释:
RouteLocatorBuilder
用于构建路由。route(String id, Function<PredicateSpec, AsyncBuilder>)
方法用于定义一个路由,第一个参数是路由的 ID,第二个参数是一个函数,用于定义路由的规则。path(String... patterns)
方法用于定义请求路径的匹配规则,可以使用 Ant 风格的路径匹配。filters(GatewayFilterSpec::filter)
方法用于定义过滤器,可以添加多个过滤器。stripPrefix(int parts)
过滤器用于移除请求路径的前缀,parts
参数指定要移除的前缀的层数。addRequestHeader(String headerName, String headerValue)
过滤器用于添加请求头。uri(String uri)
方法用于指定目标 URI,可以使用 HTTP 地址或者lb://service-name
格式的地址,表示使用 LoadBalancerClient 进行负载均衡。
2. 配置文件配置
除了 Java 代码配置,还可以使用 YAML 或 Properties 文件来配置 Spring Cloud Gateway。 这种方式更加简单直观,适合简单的场景。
YAML 配置文件 (application.yml):
spring:
cloud:
gateway:
routes:
- id: baidu_route
uri: https://www.baidu.com
predicates:
- Path=/baidu
- id: user_service_route
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1
- id: product_service_route
uri: lb://product-service
predicates:
- Path=/api/product/**
filters:
- AddRequestHeader=X-Request-Source, Gateway
Properties 配置文件 (application.properties):
spring.cloud.gateway.routes[0].id=baidu_route
spring.cloud.gateway.routes[0].uri=https://www.baidu.com
spring.cloud.gateway.routes[0].predicates[0]=Path=/baidu
spring.cloud.gateway.routes[1].id=user_service_route
spring.cloud.gateway.routes[1].uri=lb://user-service
spring.cloud.gateway.routes[1].predicates[0]=Path=/api/user/**
spring.cloud.gateway.routes[1].filters[0]=StripPrefix=1
spring.cloud.gateway.routes[2].id=product_service_route
spring.cloud.gateway.routes[2].uri=lb://product-service
spring.cloud.gateway.routes[2].predicates[0]=Path=/api/product/**
spring.cloud.gateway.routes[2].filters[0]=AddRequestHeader=X-Request-Source, Gateway
配置文件中的参数与 Java 代码配置中的参数一一对应,含义相同。
代码解释:
spring.cloud.gateway.routes
:定义路由列表。id
:路由的唯一标识。uri
:目标 URI。predicates
:断言列表,用于匹配请求。filters
:过滤器列表,用于对请求进行修改或增强。
Spring Cloud Gateway 的常用过滤器
Spring Cloud Gateway 提供了丰富的内置过滤器,可以满足各种常见的需求。 下面列举一些常用的过滤器:
过滤器名称 | 功能描述 |
---|---|
AddRequestHeader |
添加请求头。 |
AddRequestParameter |
添加请求参数。 |
AddResponseHeader |
添加响应头。 |
StripPrefix |
移除请求路径的前缀。 |
PrefixPath |
添加请求路径的前缀。 |
RewritePath |
重写请求路径。 |
RedirectTo |
重定向到指定的 URI。 |
Hystrix |
使用 Hystrix 进行熔断降级。 |
Retry |
重试请求。 |
RequestRateLimiter |
限制请求速率,防止恶意请求。 |
TokenRelay |
将 OAuth 2.0 的 Token 传递给下游服务。 |
RemoveRequestHeader |
移除请求头 |
RemoveResponseHeader |
移除响应头 |
SetPath |
设置请求路径 |
ModifyRequestBody |
修改请求体 |
ModifyResponseBody |
修改响应体 |
CircuitBreaker |
使用 Resilence4j 或其他断路器框架进行熔断降级 |
示例:使用 RequestRateLimiter
过滤器进行限流
spring:
cloud:
gateway:
routes:
- id: rate_limit_route
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- RequestRateLimiter=redis-rate-limiter, replenishRate:10, burstCapacity:20 # 每秒允许 10 个请求,最大突发流量为 20 个
在这个例子中,我们使用了 RequestRateLimiter
过滤器来限制请求速率。 redis-rate-limiter
是一个基于 Redis 的限流器,replenishRate
参数指定每秒允许的请求数量,burstCapacity
参数指定最大突发流量。
注意: 使用 RequestRateLimiter
过滤器需要引入 spring-cloud-starter-gateway
和 spring-boot-starter-data-redis
依赖。
除了内置过滤器,还可以自定义过滤器,以满足更复杂的需求。 自定义过滤器需要实现 GatewayFilter
或 GlobalFilter
接口,并将其注册为 Spring Bean。
总结
Spring Cloud Gateway 是一个功能强大的 API 网关,它可以帮助我们构建安全、可靠、高效的微服务架构。 通过灵活的路由和过滤器配置,我们可以实现各种各样的功能,比如安全认证、限流、请求聚合、协议转换等。
希望本文能够帮助您更好地理解和使用 Spring Cloud Gateway,让您的微服务架构更加健壮!
最后,祝各位看官工作顺利,生活愉快! 如果您觉得本文对您有所帮助,请点个赞,鼓励一下作者! 谢谢大家!