一句话总结
Gateway 是微服务的统一入口,基于 WebFlux(响应式编程),非阻塞 I/O,性能优于 Zuul。核心三要素:Route(路由)= Predicate(断言,匹配规则)+ Filter(过滤器,处理逻辑)+ URI(目标地址)。执行流程:请求 → Gateway Handler Mapping(匹配路由)→ Web Handler(执行过滤器链)→ 转发到目标服务。过滤器分两种:GatewayFilter(路由级)和 GlobalFilter(全局)。
初级理解
网关的作用
# 网关核心功能
# 1. 路由转发:将请求转发到对应的微服务
# 2. 负载均衡:配合 LoadBalancer 分发请求
# 3. 统一鉴权:在网关层校验 Token,无需每个服务都做
# 4. 限流熔断:保护后端服务
# 5. 日志监控:统一记录请求日志
# 6. 跨域处理:统一配置 CORS
# 7. 协议转换:HTTP → gRPC 等
基本路由配置
# application.yml 路由配置
spring:
cloud:
gateway:
routes:
- id: user-service # 路由 ID(唯一)
uri: lb://user-service # 目标服务(lb = 负载均衡)
predicates:
- Path=/api/user/** # 匹配 /api/user/** 的请求
filters:
- StripPrefix=1 # 去掉第一段路径 /api
# /api/user/1 → /user/1 转发到 user-service
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
中级深入
Predicate 断言工厂
| 断言 | 说明 | 示例 |
|---|---|---|
| Path | 路径匹配 | - Path=/api/user/** |
| Method | 请求方法 | - Method=GET,POST |
| Header | 请求头匹配 | - Header=X-Request-Id, \d+ |
| Query | 查询参数 | - Query=name, zhangsan |
| Host | 主机名匹配 | - Host=**.example.com |
| After/Before/Between | 时间匹配 | - After=2025-01-01T00:00:00+08:00 |
| Weight | 权重路由(灰度) | - Weight=group1, 80 |
Gateway 执行流程
# Gateway 请求处理流程
# 1. 请求到达 Gateway
# 2. Gateway Handler Mapping 匹配路由
# - 遍历所有路由的 Predicate
# - 找到第一个匹配的路由
# 3. Web Handler 执行过滤器链
# - 前置过滤器(pre):鉴权、限流、日志
# - 转发请求到目标服务
# - 后置过滤器(post):修改响应、添加 Header
# 4. 返回响应给客户端
# 过滤器顺序
# order 值越小越先执行
# 默认过滤器 → 路由过滤器 → 全局过滤器
高级拓展
Gateway vs Zuul
| 对比维度 | Gateway | Zuul 1.x |
|---|---|---|
| 底层 | WebFlux(响应式) | Servlet(阻塞) |
| IO 模型 | 非阻塞 NIO | 阻塞 BIO |
| 性能 | 高(1.6x Zuul) | 较低 |
| 长连接 | 支持 WebSocket | 不支持 |
| 维护状态 | Spring 官方维护 | 已停止维护 |
自定义 GlobalFilter
# 自定义全局鉴权过滤器
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
// 跳过登录接口
if (request.getURI().getPath().contains("/login")) {
return chain.filter(exchange);
}
// 校验 Token
String token = request.getHeaders().getFirst("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -100; // 优先级高
}
}
实战场景
场景:Gateway 限流
# 基于 Redis 的令牌桶限流
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter:
replenishRate: 10 # 每秒生成令牌数
burstCapacity: 20 # 令牌桶容量
key-resolver: "#{@ipKeyResolver}"
# 限流 Key 解析器(按 IP 限流)
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()
);
}
面试模拟
面试官:Gateway 和 Zuul 有什么区别?
你:Gateway 基于 WebFlux 响应式编程,非阻塞 NIO,性能更好(约 1.6 倍),支持 WebSocket 长连接。Zuul 1.x 基于 Servlet 阻塞 BIO,已停止维护。生产环境推荐 Gateway。
面试官:Gateway 如何实现限流?
你:通过 RequestRateLimiter 过滤器 + Redis 令牌桶算法。配置 replenishRate(令牌生成速率)和 burstCapacity(桶容量),通过 KeyResolver 指定限流维度(IP、用户、接口)。