Spring Cloud Gateway 微服务网关实战指南
Spring Cloud Gateway 是基于 Spring Framework 5、Spring Boot 2 和 Project Reactor 构建的响应式 API 网关,专为云原生微服务架构设计。它取代了传统的 Servlet 基网关(如 Zuul),以非阻塞 I/O 和函数式路由模型提供更高吞吐与更低延迟。
一、网关的核心价值与定位
在分布式系统中,网关承担着统一入口、流量调度与安全管控的关键角色:
- 统一接入层:所有客户端请求必须经由网关,屏蔽后端服务拓扑细节;
- 动态路由分发:根据路径、Header、参数等条件将请求精准转发至对应微服务实例;
- 访问控制中枢:集中实现身份鉴权、权限校验、黑白名单等安全策略;
- 弹性流量治理:内置限流、熔断、重试机制,保护下游服务免于雪崩。
相较于 Zuul 的同步阻塞模型,Gateway 基于 WebFlux 的响应式编程范式,天然支持高并发连接与低资源占用,更适合现代容器化部署场景。
二、快速构建基础网关服务
以下演示一个集成 Nacos 服务发现的最小可行网关配置流程:
1. 初始化项目并引入依赖
<dependencies>
<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>
</dependencies>
2. 启动类声明
@SpringBootApplication
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
3. YAML 路由配置(application.yml)
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
routes:
- id: user-api
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=2
说明:lb://user-service 表示通过负载均衡调用注册在 Nacos 中的 user-service 实例;StripPrefix=2 将匹配路径中的前两级前缀(如 /api/users/123 → /123)移除后再转发。
4. 验证效果
启动网关及 user-service 后,访问 http://localhost:8080/api/users/1 即可透明代理至目标服务,完成首次路由验证。
三、灵活的路由断言(Route Predicate)
断言用于定义"何时触发该路由规则",由一系列工厂类解析配置字符串并生成响应式判断逻辑。常用内置断言包括:
| 断言类型 | 用途描述 | 配置示例 |
|---|---|---|
Path |
按请求路径模式匹配 | - Path=/v1/orders/{id} |
Method |
限定 HTTP 方法 | - Method=GET,PUT |
Header |
检查请求头是否存在或符合正则 | - Header=X-API-Version, v\d+ |
Cookie |
验证 Cookie 键值对 | - Cookie=sessionid, [a-fA-F\d]{32} |
四、可编程的过滤器链(Filter Chain)
过滤器分为三类,执行顺序按优先级从高到低为:default-filters → 路由级 filters → GlobalFilter。
1. 内置网关过滤器(GatewayFilter)
例如为所有匹配路由添加认证头:
filters:
- AddRequestHeader=X-Auth-Source, gateway
2. 全局过滤器(GlobalFilter)
适用于需跨路由复用的通用逻辑,如 JWT 解析、灰度路由、日志埋点等。自定义示例如下:
@Component
@Order(-1)
public class JwtAuthenticationFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = extractToken(exchange.getRequest());
if (token == null || !JwtUtil.validate(token)) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
private String extractToken(ServerHttpRequest request) {
return request.getHeaders().getFirst("Authorization");
}
}
五、统一处理跨域请求(CORS)
为避免前端应用因同源策略被拦截,可在网关层统一启用 CORS 支持:
spring:
cloud:
gateway:
globalcors:
add-to-simple-url-handler-mapping: true
cors-configurations:
'[/**]':
allowed-origins: "http://localhost:3000"
allowed-methods: GET,POST,PUT,DELETE,OPTIONS
allowed-headers: "*"
allow-credentials: true
max-age: 3600
该配置将自动响应预检(OPTIONS)请求,并允许指定源携带凭证发起跨域调用。