跳到主要内容

服务网关

问题

微服务网关的作用是什么?Spring Cloud Gateway 的核心原理和使用方式?

答案

网关的作用

网关是微服务架构的统一入口,客户端不直接调用各个微服务,而是通过网关转发。

核心功能:路由转发负载均衡统一鉴权限流熔断日志监控跨域处理

Spring Cloud Gateway 核心概念

概念说明
Route(路由)网关的基本单元:ID + URI + Predicate + Filter
Predicate(断言)匹配条件(Path、Header、Method 等)
Filter(过滤器)请求/响应的拦截处理

路由配置

application.yml
spring:
cloud:
gateway:
routes:
# 路由1:用户服务
- id: user-service
uri: lb://user-service # lb:// 表示从注册中心负载均衡
predicates:
- Path=/api/users/** # 路径匹配
filters:
- StripPrefix=1 # 去掉前缀 /api

# 路由2:订单服务(多条件)
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
- Method=GET,POST # 只匹配 GET 和 POST
- Header=X-Request-Id, \d+ # Header 正则匹配
filters:
- StripPrefix=1
- AddRequestHeader=X-Gateway, true

# 默认过滤器(对所有路由生效)
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Origin

常用 Predicate

Predicate示例说明
PathPath=/api/**路径匹配
MethodMethod=GET,POSTHTTP 方法
HeaderHeader=X-Token, \w+请求头
QueryQuery=name, \w+查询参数
After/Before/BetweenAfter=2024-01-01T00:00:00+08:00时间窗口
WeightWeight=group1, 80权重路由(灰度发布)

自定义全局过滤器

AuthGlobalFilter.java
@Component
@Order(-1) // 优先级,值越小越先执行
public class AuthGlobalFilter implements GlobalFilter {

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();

// 白名单放行
if (path.startsWith("/api/public")) {
return chain.filter(exchange);
}

// 鉴权逻辑
String token = request.getHeaders().getFirst("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}

// 解析 token,将用户信息传递给下游服务
String userId = parseToken(token);
ServerHttpRequest newRequest = request.mutate()
.header("X-User-Id", userId)
.build();

return chain.filter(exchange.mutate().request(newRequest).build());
}
}

限流配置

基于 Redis 的限流
spring:
cloud:
gateway:
routes:
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10 # 每秒 10 个令牌
redis-rate-limiter.burstCapacity: 20 # 令牌桶容量
key-resolver: "#{@ipKeyResolver}" # 限流维度
限流 Key 解析器
@Bean
public KeyResolver ipKeyResolver() {
// 按 IP 限流
return exchange -> Mono.just(
exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()
);
}

Gateway vs Zuul

对比Spring Cloud GatewayZuul 1.x
模型异步非阻塞(WebFlux + Netty)同步阻塞(Servlet)
性能高(适合高并发)较低
长连接支持 WebSocket不支持
维护Spring 官方维护Netflix 停止维护

常见面试问题

Q1: 网关的核心作用?

答案

网关是微服务的统一入口,核心功能包括:路由转发(根据路径分发到不同服务)、负载均衡(配合注册中心)、统一鉴权(集中处理认证,下游服务不需要重复鉴权)、限流熔断(保护后端服务)、日志监控(统一记录请求日志)、跨域处理

Q2: Spring Cloud Gateway 的执行流程?

答案

  1. 客户端请求到达 Gateway
  2. HandlerMapping 根据 Predicate 匹配路由
  3. 请求进入 Filter 链,依次执行 Pre Filter
  4. 转发到目标微服务
  5. 收到响应后,反向执行 Post Filter
  6. 返回给客户端

Q3: 如何在网关实现灰度发布?

答案

通过 Weight 路由 将流量按比例分配:

routes:
- id: order-v1
uri: lb://order-service-v1
predicates:
- Path=/api/orders/**
- Weight=order, 90 # 90% 流量到 v1
- id: order-v2
uri: lb://order-service-v2
predicates:
- Path=/api/orders/**
- Weight=order, 10 # 10% 流量到 v2

也可以通过自定义 Filter 根据用户 ID、Header 等条件路由到不同版本。

Q4: Gateway 和 Nginx 的区别?

答案

  • Nginx:通用反向代理,配置静态路由,适合 L4/L7 负载均衡、静态资源、SSL 终止
  • Gateway:应用层网关,动态路由(配合注册中心),适合微服务鉴权、限流、灰度等业务逻辑

两者通常组合使用:Nginx 在最外层处理 SSL 和静态资源,Gateway 在内网处理微服务路由和业务逻辑。

相关链接