快速入门-Spring Cloud Gateway
Gateway(网关) 是一种服务组件,通常用作微服务架构中的入口点,负责请求的统一管理、路由转发、协议转换、安全认证、负载均衡等。Gateway 是客户端与后端服务之间的桥梁,简化了客户端的复杂性,同时增强了系统的安全性和灵活性。
在现代分布式系统架构中,微服务逐渐取代了传统的单体架构,成为主流的软件开发模式。微服务的优势包括模块化开发、高可用性、可扩展性等,但它也引入了以下复杂性和问题:服务数量增加,通信复杂化,不同服务的协议兼容性,缺乏统一的安全管理,性能和流量管理困难,监控和日志的分散。为了解决上述问题, Gateway 被引入作为一种集中式的流量管理工具。解决了微服务架构中的复杂性问题,包括通信管理、协议转换、安全性、性能优化等。它既是客户端与后端服务之间的桥梁,也是微服务治理的重要工具。在现代分布式架构中,Gateway 已成为不可或缺的组件。
Spring Cloud Gateway 是对 Netflix Zuul 的替代方案,专为微服务架构设计,基于 Spring Framework 和 Spring Boot,具有更高的性能和灵活性。
特点包括:
- 高性能:基于非阻塞式 I/O(Netty)实现,性能优于传统的阻塞式网关(如 Zuul 1.x)。
- 动态路由:支持根据路径、请求头、参数等条件动态路由请求。
- 过滤器链:提供丰富的过滤器功能,可以对请求和响应进行修改,例如添加身份验证、限流等。
- 集成 Spring 生态:无缝集成 Spring Security、Spring Cloud Config、Spring Actuator 等模块。
快速实践
可以参考:springdoc.cn/spring-clou…
# 环境准备
1. JDK8以上版本
2. 安装 Maven
3. 下载并安装 Spring Boot 工程模板(可以通过 Spring Initializr)
4. 构建一个SpringBoot项目
# 项目 pom 文件中引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
application 配置文件
spring:
####################################### spring 微服务模块配置 ###################################
cloud:
# 网关配置
gateway:
# 设置与服务注册发现组件结合,这样可以采用服务名的路由策略
discovery:
locator:
enabled:true
lower-case-service-id:true
routes:
-id:dotj-cloud-gateway
# 匹配微服务的名称, 或者微服务的地址
uri:lb://dotj-cloud-gateway
# uri: http://127.0.0.1:9090
# 断言, 路径相互匹配的进行路由
predicates:
-Path=/gateway/**
# 过滤掉前缀
filters:
-StripPrefix=1
## 说明
# id:随便写保持和其他服务不同就是了
# uri:说明要跳转的uri地址
# StripPrefix:指定要从源地址截取的个数,以“/“为分隔符。以地址栏输入“http://localhost:9090/gateway/say/** ”为例,域名部分不计,那就是从gateway/say/** 计算,StripPrefix=1,表示从前截取两个”/”,那么结构就是:/say/**,你的服务必须对应这个uri,否则会出现404。
Java代码
@RestController
@RequestMapping("/route")
public class RouteController {
@Autowired
private RouteDefinitionLocator routeDefinitionLocator;
/**
* test
*/
@Operation(description = "test")
@GetMapping("/test")
public Mono<Result<?>> test() {
String uuid = UUID.randomUUID().toString();
return Mono.just(Result.success("test: " + uuid + "; test: " + test));
}
/**
* 获取网关所有的路由信息
*
* @return
*/
@Operation(description = "路由信息")
@GetMapping("/list")
public Flux<RouteDefinition> getRouteDefinitions() {
return routeDefinitionLocator.getRouteDefinitions();
}
}
Gateway 的重要概念
# Route(路由)
路由是 Spring Cloud Gateway 的核心模块,用于定义请求转发规则。每个路由规则会根据指定的条件(Predicates)匹配请求,并将其转发到指定的目标服务。
组成部分:
1.ID:路由的唯一标识。
2.URI:目标服务地址(可以是 HTTP 服务、WebSocket 服务等)。
3.Predicates:条件匹配器,用于决定请求是否匹配当前路由规则。
4.Filters:过滤器链,用于对请求和响应进行修改或拦截。
# Predicate(断言)
Predicate 是用于定义路由规则的条件判断模块。Gateway 会根据请求的属性(如路径、请求头、参数等)进行匹配,判断请求是否符合条件。
常用 Predicates:
1.Path:按路径匹配
- Path=/api/**
2.Method:按请求方法匹配
- Method=GET
3.Header:按请求头匹配
- Header=X-Request-ID,123
4.Query:按查询参数匹配
- Query=type,user
5.After/Before/Between:按时间范围匹配。
- After=2025-01-01T00:00:00+08:00
6.自定义 Predicate:
开发者可以通过实现 RoutePredicateFactory 接口来自定义路由断言。
# Filter(过滤器)
Filter 是用于对请求和响应进行处理的模块。过滤器可以用来实现身份验证、日志记录、限流、重写请求头等功能。
分为两种:
1.全局过滤器(GlobalFilters):作用于所有路由。
2.局部过滤器(RouteFilters):作用于特定路由。
常用内置过滤器:
1.AddRequestHeader:添加请求头
- AddRequestHeader=X-Request-ID,12345
2.AddResponseHeader:添加响应头
- AddResponseHeader=X-Response-Time,500ms
3.RewritePath:重写请求路径
- RewritePath=/old/(?<segment>.*), /new/${segment}
自定义 Filter
通过实现 GatewayFilter 接口,可以创建自定义过滤器。
# Gateway Handler(处理器)
Gateway Handler 是 Gateway 中的核心调度器,负责
1.将请求分发给合适的路由。
2.触发相关的过滤器链。
3.转发请求到目标服务并返回结果。
Gateway Handler 依赖于 Routing Predicate 和 Filter Chain 的运行结果,确保所有匹配的逻辑和操作都被执行。
# Filter Chain(过滤器链)
Filter Chain 是过滤器的集合,按顺序执行所有过滤器。请求处理包含两个阶段:
1.Pre Filters:在请求到达后端服务之前执行。
2.Post Filters:在后端服务响应返回给客户端之前执行。
过滤器链的执行逻辑类似于拦截器的链式调用。
自定义过滤器
@Component
publicclass CustomFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 预处理逻辑
System.out.println("Pre-Filter logic here");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
// 后处理逻辑
System.out.println("Post-Filter logic here");
}));
}
@Override
public int getOrder() {
return -1; // 优先级,越小越高
}
}
自定义过滤器规则
@Component
publicclass TestGatewayFilterFactory extends AbstractGatewayFilterFactory<TestGatewayFilterFactory.Config> {
privatestaticfinal Logger logger = LoggerFactory.getLogger(TestGatewayFilterFactory.class);
// 在类的构造器中一定要调用下父类的构造器把Config类型传过去,否则会报ClassCastException
public TestGatewayFilterFactory() {
super(Config.class);
}
@Override
public String name() {
return"TestGatewayFilterFactory";
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
return chain.filter(exchange).then(
Mono.fromRunnable(() -> {})
);
};
}
publicstaticclass Config {
privateboolean withParams;
public boolean isWithParams() {
return withParams;
}
public void setWithParams(boolean withParams) {
this.withParams = withParams;
}
}
}
配置文件事例
spring:
cloud:
gateway:
# 路由数组:指当请求满足什么样的断言时,转发到哪个服务上
routes:
# 路由标识,要求唯一,名称任意
-id:gateway-provider_1
# 请求最终被转发到的目标地址
uri:http://localhost:9024
# 设置断言
predicates:
# Path Route Predicate Factory 断言,满足 /gateway/provider/** 路径的请求都会被路由到 http://localhost:9024 这个uri中
-Path=/gateway/provider/**
# Weight Route Predicate Factory 断言,同一分组按照权重进行分配流量,这里分配了80%
# 第一个group1是分组名,第二个参数是权重
-Weight=group1,8
# 配置过滤器(局部)
filters:
# StripPrefix:去除原始请求路径中的前1级路径,即/gateway
-StripPrefix=1
-id:gateway-provider_2
uri:http://localhost:9025
# 设置断言
predicates:
-Path=/gateway/provider/**
# Weight Route Predicate Factory,同一分组按照权重进行分配流量,这里分配了20%
-Weight=group1,2
# 配置过滤器(局部)
filters:
# StripPrefix:去除原始请求路径中的前1级路径,即/gateway
-StripPrefix=1
总结
Spring Cloud Gateway 是基于 Spring WebFlux 构建的高效 API 网关,作为微服务架构的统一流量入口,提供动态路由、过滤器、负载均衡、限流和熔断等功能,与 Spring 生态无缝集成,适合高并发和灵活扩展的场景。它简化了客户端与服务的交互流程,统一了认证、安全和流量控制,提升了系统的稳定性与可维护性,是现代微服务架构的重要组件。
致谢
更多内容欢迎关注 [ 小巫编程室 ] 公众号,喜欢文章的话,也希望能给小编点个赞或者转发,你们的喜欢与支持是小编最大的鼓励,小巫编程室感谢您的关注与支持。好好学习,天天向上(good good study day day up)。
参考资料
[1] 官网: spring.io/projects/sp…
[2] 源码: github.com/spring-clou…