Spring Cloud Gateway架构与路由模型设计
Spring Cloud Gateway是Spring官方推出的微服务API网关,基于Spring WebFlux和Project Reactor构建,提供非阻塞式的请求转发能力。在微服务架构中,网关承担统一入口的角色,所有外部请求经过网关进行路由转发、鉴权拦截、限流熔断和日志审计。相比传统的Zuul 1.x基于Servlet的阻塞模型,Spring Cloud Gateway的Reactor模型在高并发场景下吞吐量提升显著。
Gateway的核心模型由Route(路由)、Predicate(断言)和Filter(过滤器)三部分组成。Route是一条完整路由规则,包含目标URI、断言列表和过滤器列表。Predicate匹配请求条件(Path、Header、Method、Host等),Filter在请求前后执行增强逻辑(鉴权、日志、限流、重写)。
依赖配置与基础启动类:
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
// 启动类
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
路由配置与动态路由实现
Gateway路由规则可以通过YAML配置文件或Java DSL定义。YAML方式适合静态路由,Java DSL适合需要动态更新的场景。
# application.yml - 静态路由配置
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
- Method=GET,POST
filters:
- StripPrefix=2
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 100
redis-rate-limiter.burstCapacity: 200
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
- Header=X-Version, v2
filters:
- StripPrefix=2
- AddResponseHeader=X-Gateway, cloud-gateway
lb://前缀表示使用负载均衡,Gateway通过Nacos或Eureka注册中心解析服务名并选择实例。StripPrefix=2表示去掉URL前两级路径前缀,例如/api/users/profile转发为/profile。
动态路由通过RouteLocator Bean实现,适合需要运行时更新的场景:
@Configuration
public class DynamicRouteConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("user-service", r -> r
.path("/api/users/**")
.filters(f -> f
.stripPrefix(2)
.filter((exchange, chain) -> {
ServerHttpRequest req = exchange.getRequest();
String token = req.getHeaders().getFirst("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
})
)
.uri("lb://user-service"))
.build();
}
}
限流过滤器与Redis令牌桶实现
RequestRateLimiter是Gateway内置的限流过滤器,基于Redis令牌桶算法实现。replenishRate是令牌填充速率(每秒令牌数),burstCapacity是桶容量(突发请求上限)。每个请求消耗一个令牌,令牌不足时返回429状态码。
spring:
cloud:
gateway:
routes:
- id: rate-limited-service
uri: lb://payment-service
predicates:
- Path=/api/payment/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 50
redis-rate-limiter.burstCapacity: 100
key-resolver: "#{@userKeyResolver}"
@Component
public class UserKeyResolver implements KeyResolver {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
String userId = exchange.getRequest().getHeaders().getFirst("X-User-Id");
return Mono.just(userId != null ? userId : "anonymous");
}
}
key-resolver定义限流维度:基于用户ID、客户端IP或API路径进行差异化限流。上述配置按用户ID限流,每个用户每秒50个请求,突发上限100。
熔断降级与Resilience4j集成
Gateway 3.0后推荐使用Resilience4j替代Hystrix实现熔断降级。CircuitBreaker过滤器在下游服务异常时触发熔断,将请求路由到降级逻辑。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
</dependency>
spring:
cloud:
gateway:
routes:
- id: circuit-breaker-route
uri: lb://order-service
predicates:
- Path=/api/orders/**
filters:
- name: CircuitBreaker
args:
name: orderServiceCB
fallbackUri: forward:/fallback/orders
# Resilience4j配置
resilience4j:
circuitbreaker:
configs:
default:
failureRateThreshold: 50
slowCallRateThreshold: 60
slowCallDurationThreshold: 2s
minimumNumberOfCalls: 10
waitDurationInOpenState: 30s
permittedNumberOfCallsInHalfOpenState: 5
slidingWindowSize: 20
slidingWindowType: COUNT_BASED
@RestController
public class FallbackController {
@GetMapping("/fallback/orders")
public Mono<Map<String, Object>> fallback() {
return Mono.just(Map.of(
"code", 503,
"message", "订单服务暂时不可用,请稍后重试"
));
}
}
熔断器有三个状态:CLOSED(正常放行)、OPEN(熔断拒绝)、HALF_OPEN(半开探测)。当失败率超过failureRateThreshold(50%)时进入OPEN状态,等待waitDurationInOpenState后进入HALF_OPEN,放行5个探测请求,成功则恢复CLOSED,失败则回到OPEN。
全局过滤器与请求链路追踪
全局过滤器(GlobalFilter)对所有路由生效,适合实现鉴权、日志、链路追踪等横切逻辑。通过@Order注解控制过滤器执行顺序。
@Component
@Order(-100)
public class AuthGlobalFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest req = exchange.getRequest();
String path = req.getURI().getPath();
// 白名单路径跳过鉴权
if (path.matches("/api/auth/(login|register)")) {
return chain.filter(exchange);
}
String token = req.getHeaders().getFirst("Authorization");
if (token == null) {
return unauthorized(exchange, "Missing Authorization header");
}
try {
Claims claims = Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(token.replace("Bearer ", ""))
.getBody();
ServerHttpRequest mutated = req.mutate()
.header("X-User-Id", claims.getSubject())
.header("X-User-Role", claims.get("role", String.class))
.build();
return chain.filter(exchange.mutate().request(mutated).build());
} catch (Exception e) {
return unauthorized(exchange, "Invalid token");
}
}
private Mono<Void> unauthorized(ServerWebExchange exchange, String msg) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
exchange.getResponse().getHeaders()
.setContentType(MediaType.APPLICATION_JSON);
String body = "{\"code\":401,\"message\":\"" + msg + "\"}";
DataBuffer buffer = exchange.getResponse().bufferFactory()
.wrap(body.getBytes(StandardCharsets.UTF_8));
return exchange.getResponse().writeWith(Mono.just(buffer));
}
}
在服务治理层面,Spring Cloud Gateway配合Nacos注册中心可以实现服务发现与配置中心一体化管理。Gateway自身也注册为Nacos服务实例,支持多实例集群部署。通过Nginx或SLB在Gateway前面做负载均衡,实现高可用网关集群。结合Sleuth+Zipkin或SkyWalking,可以在Gateway层注入TraceID,实现请求从网关到下游微服务的完整链路追踪。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/springcloudgateway-wei-fu-wu-wang-guan-lu-you-yu-xian-liu/