微服务API网关Spring Cloud Gateway核心概念与实战详解
一、微服务架构中为什么需要API网关?
在微服务架构中,一个系统通常会被拆分为多个独立的微服务。如果客户端直接调用每个微服务的地址,会面临以下问题:
-
客户端复杂性高:需要维护多个微服务的地址和配置,代码冗余且难以维护。
-
认证鉴权复杂:每个微服务可能有不同的认证方式,客户端需要适配多种认证逻辑。
-
跨域与协议问题:存在跨域请求、防火墙限制、浏览器协议兼容性等问题。
-
系统难以重构:微服务随着项目迭代可能需要重新划分,直接调用会导致调用链重构困难。
API网关应运而生,它作为系统的统一入口,为微服务提供路由转发、认证鉴权、流量控制、监控日志等公共能力,实现业务与非业务逻辑的解耦。
二、Spring Cloud Gateway 是什么?
Spring Cloud Gateway 是 Spring Cloud 官方推出的第二代网关框架,旨在取代 Netflix Zuul。它具有以下特点:
-
响应式编程:基于 WebFlux + Netty + Reactor 实现,不支持传统的 Servlet 容器。
-
高性能:官方基准测试显示其性能显著优于 Zuul1 和 Zuul2。
-
灵活的路由与过滤机制:支持动态路由、断言匹配、过滤器链等核心功能。
性能对比(部分数据)
| 网关类型 | 平均延迟 | 每秒请求数/线程 |
|---|---|---|
| Spring Cloud Gateway | 6.61ms | 3.24k |
| Zuul1 | 12.56ms | 2.09k |
| Zuul2 | 2.09ms | 11.77k |
三、Spring Cloud Gateway 核心概念
3.1 路由(Route)
路由是网关中最基本的单元,包含:
-
ID:唯一标识
-
URI:目标服务地址
-
Predicates:断言条件
-
Filters:过滤器链
3.2 断言(Predicates)
基于 Java 8 的 Predicate<ServerWebExchange>,用于匹配 HTTP 请求的各个部分(如路径、请求头、参数等)。匹配成功则路由生效。
3.3 过滤器(Filter)
分为两类:
-
GatewayFilter:作用于特定路由
-
GlobalFilter:全局生效,作用于所有路由
四、Spring Cloud Gateway 工作原理
text
客户端请求 → 网关路由匹配 → 执行Pre过滤器链 → 转发至目标服务 → 执行Post过滤器链 → 返回响应
过滤器分为 pre 和 post 两种:
-
pre过滤器:在转发前执行(如鉴权、添加请求头)
-
post过滤器:在收到响应后执行(如日志记录、修改响应)
五、Spring Cloud Gateway 实战详解
5.1 快速接入
1)引入依赖
xml
<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>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
注意:Gateway 与
spring-webmvc冲突,需排除后者。
2)配置文件示例
yaml
spring:
application:
name: mall-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
routes:
- id: order_route
uri: lb://mall-order
predicates:
- Path=/order/**
- id: user_route
uri: lb://mall-user
predicates:
- Path=/user/**
3)测试访问
text
http://localhost:8888/order/findOrderByUserId/1
5.2 路由断言工厂(Predicate Factories)
5.2.1 路径匹配
yaml
predicates: - Path=/order/**
5.2.2 Header 匹配
yaml
predicates: - Header=X-Request-Id, \d+
请求头
X-Request-Id的值必须为数字。
5.3 过滤器工厂(GatewayFilter Factories)
5.3.1 添加请求头
yaml
filters: - AddRequestHeader=X-Request-color, red
5.3.2 添加请求参数
yaml
filters: - AddRequestParameter=color, blue
5.3.3 自定义过滤器工厂
java
@Component
public class CheckAuthGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return (exchange, chain) -> {
log.info("调用自定义过滤器:{} = {}", config.getName(), config.getValue());
return chain.filter(exchange);
};
}
}
配置使用:
yaml
filters: - CheckAuth=fox,男
5.4 全局过滤器(Global Filters)
5.4.1 负载均衡过滤器
ReactiveLoadBalancerClientFilter 负责将 lb://service 转换为实际的服务地址。
5.4.2 自定义全局过滤器(实现鉴权)
java
@Component
public class CheckAuthFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getHeaders().getFirst("token");
if (token == null) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
// TODO: 校验token
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 2;
}
}
5.5 跨域配置(CORS)
YAML 配置方式
yaml
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowed-origins: "*"
allowed-methods: "*"
Java 配置方式
java
@Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.addAllowedMethod("*");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
5.6 基于 Redis + Lua 的限流
1)引入依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
2)配置限流过滤器
yaml
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1 # 令牌桶每秒填充速率
redis-rate-limiter.burstCapacity: 2 # 令牌桶总容量
key-resolver: "#{@keyResolver}" # 限流键解析器
3)定义 KeyResolver
java
@Bean
KeyResolver keyResolver() {
// URL 限流
return exchange -> Mono.just(exchange.getRequest().getURI().getPath());
// 参数限流
// return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
5.7 整合 Sentinel 实现网关限流
1)引入依赖
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2)配置 Sentinel Dashboard
yaml
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080
3)Sentinel 网关流控原理
Sentinel 将网关流控规则转换为热点参数规则,通过 GatewayFlowSlot 进行规则检查,支持:
-
路由维度限流:基于 routeId
-
API 分组维度限流:用户自定义分组
注:Spring Boot 3 + Spring Cloud Gateway 与 Sentinel 的兼容性待官方更新。
六、总结与建议
Spring Cloud Gateway 作为 Spring Cloud 生态中的第二代网关,具有响应式、高性能、易扩展等优点,适合作为微服务架构的统一入口。
最佳实践建议:
-
路由配置集中管理:结合配置中心(如 Nacos)实现动态路由。
-
过滤器链合理设计:区分业务过滤器与通用过滤器,保持职责单一。
-
限流与熔断结合使用:搭配 Sentinel 或 Resilience4j 实现系统保护。
-
监控与日志完备:集成 Micrometer + Prometheus + Grafana 实现全方位监控。
七、参考资料
更多推荐
所有评论(0)