网关 Gateway?

2025年 阅读约 15 分钟 面试指南 · Spring Cloud

深入解析Spring Cloud Gateway:路由断言工厂、过滤器链(GatewayFilter/GlobalFilter)、限流实现、跨域配置、与Zuul对比、WebFlux响应式编程,附面试模拟问答。

一句话总结

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

对比维度GatewayZuul 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、用户、接口)。