Spring Cloud Gateway在微服务架构中的定位
Spring Cloud Gateway是Spring官方推出的微服务网关组件,基于Spring WebFlux和Reactor实现非阻塞式请求转发。在微服务架构中,网关层承担统一路由、限流熔断、认证鉴权、日志监控等横切职责。相比Netflix Zuul,Spring Cloud Gateway基于Netty异步非阻塞模型,在高并发场景下吞吐性能显著优于基于Servlet的Zuul 1.x。
Spring Cloud Gateway的核心概念:Route(路由)由ID、目标URI、Predicate(断言)和Filter(过滤器)组成;Predicate用于匹配HTTP请求的路径、Header、参数等条件;Filter在请求转发前后对请求和响应进行修改处理。Gateway通过Spring Cloud LoadBalancer集成服务发现,实现基于服务名的动态路由。
Gateway基础路由配置
使用Spring Boot 3.x和Spring Cloud Gateway搭建网关服务:
<!-- pom.xml -->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
YAML配置路由规则:
# application.yml
server:
port: 8080
spring:
cloud:
gateway:
# 路由配置
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=2
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
- Method=GET,POST
filters:
- StripPrefix=2
- id: product-service
uri: lb://product-service
predicates:
- Path=/api/products/**
- Header=X-API-Version, v[1-9]
filters:
- StripPrefix=2
- AddResponseHeader=X-Gateway, scg
# 全局过滤器
default-filters:
- AddRequestHeader=X-Gateway-Request, true
- AddResponseHeader=X-Gateway-Response, true
# 服务发现配置
discovery:
locator:
enabled: true
lower-case-service-id: true
# Redis用于限流
data:
redis:
host: 192.168.1.100
port: 6379
password: yourpassword
自定义全局过滤器实现认证鉴权
通过实现GlobalFilter和Ordered接口创建全局过滤器,在请求转发前进行JWT令牌验证:
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
private static final List<String> WHITE_LIST = List.of(
"/api/auth/login",
"/api/auth/register",
"/api/auth/refresh"
);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
// 白名单路径直接放行
if (WHITE_LIST.stream().anyMatch(path::startsWith)) {
return chain.filter(exchange);
}
// 提取Authorization头
String authHeader = request.getHeaders().getFirst("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
return unauthorizedResponse(exchange, "Missing or invalid token");
}
String token = authHeader.substring(7);
try {
// 验证JWT令牌
Claims claims = Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor(secretKey.getBytes()))
.build()
.parseClaimsJws(token)
.getBody();
// 将用户信息注入请求头,传递给下游服务
ServerHttpRequest mutatedRequest = request.mutate()
.header("X-User-Id", claims.getSubject())
.header("X-User-Role", claims.get("role", String.class))
.build();
return chain.filter(exchange.mutate().request(mutatedRequest).build());
} catch (ExpiredJwtException e) {
return unauthorizedResponse(exchange, "Token expired");
} catch (JwtException e) {
return unauthorizedResponse(exchange, "Invalid token");
}
}
private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String message) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
String body = String.format("{"code":401,"message":"%s"}", message);
DataBuffer buffer = response.bufferFactory().wrap(body.getBytes());
return response.writeWith(Mono.just(buffer));
}
@Override
public int getOrder() {
return -100; // 最高优先级
}
}
RequestRateLimiter限流配置与自定义限流策略
Spring Cloud Gateway内置RequestRateLimiter过滤器,基于Redis令牌桶算法实现限流。通过自定义KeyResolver实现不同维度的限流策略:
@Configuration
public class RateLimiterConfig {
// 按用户ID限流
@Bean
public KeyResolver userKeyResolver() {
return exchange -> {
String userId = exchange.getRequest().getHeaders().getFirst("X-User-Id");
return Mono.just(userId != null ? userId : "anonymous");
};
}
// 按IP地址限流
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> {
String ip = exchange.getRequest().getRemoteAddress() != null
? exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()
: "unknown";
return Mono.just(ip);
};
}
// 按API路径限流
@Bean
public KeyResolver apiKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getURI().getPath()
);
}
// 按用户+API组合限流
@Bean
public KeyResolver userApiKeyResolver() {
return exchange -> {
String userId = exchange.getRequest().getHeaders().getFirst("X-User-Id");
String apiPath = exchange.getRequest().getURI().getPath();
return Mono.just(userId + ":" + apiPath);
};
}
// 自定义RedisRateLimiter配置
@Bean
public RedisRateLimiter customRateLimiter(RedisConnectionFactory factory) {
// replenishRate: 令牌填充速率(每秒10个)
// burstCapacity: 令牌桶容量(最大20个)
return new RedisRateLimiter(10, 20);
}
}
在路由配置中指定限流策略:
spring:
cloud:
gateway:
routes:
- id: user-service-rate-limited
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=2
- name: RequestRateLimiter
args:
key-resolver: "#{@userApiKeyResolver}"
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1
集成Resilience4j实现熔断降级
Spring Cloud Gateway集成Resilience4j实现熔断和重试机制,在下游服务不可用时快速失败并返回降级响应:
# application.yml
resilience4j:
circuitbreaker:
configs:
default:
sliding-window-size: 100
sliding-window-type: COUNT_BASED
minimum-number-of-calls: 20
failure-rate-threshold: 50
wait-duration-in-open-state: 10s
permitted-number-of-calls-in-half-open-state: 5
automatic-transition-from-open-to-half-open-enabled: true
instances:
user-service-cb:
base-config: default
order-service-cb:
base-config: default
timelimiter:
configs:
default:
timeout-duration: 3s
instances:
user-service-tl:
base-config: default
配置熔断过滤器路由:
spring:
cloud:
gateway:
routes:
- id: user-service-circuit-breaker
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=2
- name: CircuitBreaker
args:
name: user-service-cb
fallbackUri: forward:/fallback/users
实现降级响应接口:
@RestController
public class FallbackController {
@GetMapping("/fallback/users")
public Mono<Map<String, Object>> userFallback() {
return Mono.just(Map.of(
"code", 503,
"message", "用户服务暂时不可用,请稍后重试",
"data", Collections.emptyList()
));
}
@GetMapping("/fallback/orders")
public Mono<Map<String, Object>> orderFallback() {
return Mono.just(Map.of(
"code", 503,
"message", "订单服务暂时不可用,请稍后重试",
"data", Collections.emptyList()
));
}
}
Gateway监控与健康检查
通过Actuator暴露Gateway的运行时指标和路由信息:
# application.yml
management:
endpoints:
web:
exposure:
include: gateway,health,metrics,prometheus
endpoint:
gateway:
enabled: true
health:
show-details: always
# 查看所有路由配置
curl http://localhost:8080/actuator/gateway/routes
# 查看特定路由
curl http://localhost:8080/actuator/gateway/routes/user-service
# 查看全局过滤器
curl http://localhost:8080/actuator/gateway/globalfilters
# 查看路由过滤器工厂
curl http://localhost:8080/actuator/gateway/routefilters
# 动态刷新路由(添加路由)
curl -X POST http://localhost:8080/actuator/gateway/refresh
# 健康检查
curl http://localhost:8080/actuator/health
Spring Cloud Gateway作为微服务网关,通过Predicate断言匹配请求,Filter过滤器链处理请求和响应,配合Redis限流和Resilience4j熔断机制,构建了完整的API网关防护体系。在实际部署中,Gateway的响应式非阻塞模型在高并发请求转发场景下表现优异,Actuator端点提供了运行时路由管理和监控能力,支持动态刷新路由配置而无需重启服务。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/springcloudgateway-wei-fu-wu-wang-guan-lu-you-guo-lyu-yu/