Spring Cloud Gateway 网关技术文档
1. 引言
在微服务架构中,API网关是系统的入口点,负责请求路由、负载均衡、安全认证、限流熔断等核心功能。Spring Cloud Gateway是Spring Cloud生态系统中的新一代API网关组件,它基于Spring Boot 2.x和Spring WebFlux构建,提供了高性能、响应式的网关服务。
Spring Cloud Gateway具有以下主要特点:
- 响应式编程模型:基于WebFlux构建,支持高并发、低延迟的响应式编程
- 动态路由:支持动态配置和更新路由规则
- 强大的过滤器链:提供丰富的内置过滤器和自定义过滤器支持
- 限流和熔断:集成Redis实现限流,支持与Hystrix、Resilience4j等熔断组件集成
- 安全认证:与Spring Security无缝集成,支持OAuth2、JWT等认证方式
- 监控和可观测性:提供详细的监控指标和日志支持
- 与Spring Cloud生态集成:与Eureka、Consul、Nacos等服务注册中心无缝集成
本文将详细介绍Spring Cloud Gateway的核心概念、架构设计、安装配置、路由规则、过滤器、限流熔断等功能,并提供实际的Java代码示例,帮助读者快速上手Spring Cloud Gateway开发。
2. 核心概念
2.1 Gateway
Gateway是Spring Cloud Gateway的核心组件,负责接收所有客户端请求,并根据配置的路由规则将请求转发到相应的后端服务。
2.2 Route
Route是Spring Cloud Gateway的基本构建块,代表一个路由规则。每个Route包含以下属性:
- ID:路由的唯一标识符
- URI:目标服务的URI
- Predicates:路由断言集合,用于匹配请求
- Filters:过滤器集合,用于修改请求和响应
2.3 Predicate
Predicate是路由断言,用于判断请求是否匹配某个路由规则。Spring Cloud Gateway提供了丰富的内置断言,如路径断言、方法断言、头断言等。
2.4 Filter
Filter是过滤器,用于在请求被路由到后端服务之前或之后修改请求和响应。Spring Cloud Gateway提供了两种类型的过滤器:
- GatewayFilter:局部过滤器,仅应用于特定的路由
- GlobalFilter:全局过滤器,应用于所有路由
2.5 Gateway Handler Mapping
Gateway Handler Mapping负责根据路由断言匹配请求,并将匹配的请求转发到相应的Gateway Handler。
2.6 Gateway Web Handler
Gateway Web Handler负责执行过滤器链,并将请求转发到后端服务。
2.7 Filter Chain
FilterChain是过滤器链,包含多个过滤器,用于在请求处理过程中执行一系列操作。
3. 架构设计
3.1 整体架构
Spring Cloud Gateway的整体架构由以下几个核心组件组成:
- 客户端请求:来自客户端的HTTP请求
- Gateway Handler Mapping:根据路由断言匹配请求
- Gateway Web Handler:执行过滤器链
- FilterChain:包含多个GatewayFilter和GlobalFilter
- 后端服务:目标微服务
3.2 工作流程
Spring Cloud Gateway的工作流程如下:
- 客户端发送HTTP请求到Spring Cloud Gateway
- Gateway Handler Mapping根据请求的属性(如路径、方法、头信息等)匹配相应的路由
- 如果匹配到路由,将请求转发到Gateway Web Handler
- Gateway Web Handler执行过滤器链
- 前置过滤器:在请求被转发到后端服务之前执行
- 路由转发:将请求转发到后端服务
- 后置过滤器:在收到后端服务响应之后执行
- 将响应返回给客户端
3.3 响应式编程模型
Spring Cloud Gateway基于Spring WebFlux构建,采用响应式编程模型。响应式编程模型具有以下优势:
- 高并发:基于Reactor框架,支持非阻塞I/O,能够处理大量并发请求
- 低延迟:减少线程上下文切换和资源消耗,提高系统响应速度
- 更好的资源利用率:使用少量线程即可处理大量请求,提高服务器资源利用率
- 更好的弹性:支持背压机制,能够处理流量峰值
4. 安装与配置
4.1 创建Spring Cloud Gateway项目
4.1.1 使用Spring Initializr
- 访问Spring Initializr:https://start.spring.io/
- 选择Spring Boot版本(建议2.4.0+)
- 添加以下依赖:
- Spring Cloud Gateway
- Spring Cloud Starter Netflix Eureka Client(可选,用于服务发现)
- Spring Boot Starter Actuator(可选,用于监控)
- Spring Boot Starter Security(可选,用于安全认证)
- 生成项目并下载
4.1.2 使用Maven
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>3.1.3</version>
</dependency>
<!-- 服务发现依赖(可选) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>3.1.3</version>
</dependency>
<!-- 监控依赖(可选) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.6.8</version>
</dependency>
<!-- 安全认证依赖(可选) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.6.8</version>
</dependency>
4.2 基本配置
4.2.1 配置文件
Spring Cloud Gateway支持两种配置方式:properties和yaml。以下是一个基本的yaml配置示例:
yaml
spring:
application:
name: gateway-service
cloud:
gateway:
routes:
- id: user-service-route
uri: http://localhost:8081
predicates:
- Path=/api/users/**
filters:
- RewritePath=/api/users/(?<segment>.*), /users/$
4.2.2 服务发现配置
如果使用服务发现(如Eureka),可以配置为从服务注册中心获取后端服务地址:
yaml
spring:
application:
name: gateway-service
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
routes:
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- RewritePath=/api/users/(?<segment>.*), /users/$
# 服务发现配置
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
4.2.3 主类
java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient // 启用服务发现(可选)
public class GatewayServiceApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServiceApplication.class, args);
}
}
5. 路由配置
5.1 路由定义
路由是Spring Cloud Gateway的核心配置,用于定义请求如何被转发到后端服务。每个路由包含ID、URI、断言和过滤器。
5.1.1 基于配置文件的路由
yaml
spring:
cloud:
gateway:
routes:
# 路由1
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- RewritePath=/api/users/(?<segment>.*), /users/$
# 路由2
- id: order-service-route
uri: lb://order-service
predicates:
- Path=/api/orders/**
filters:
- RewritePath=/api/orders/(?<segment>.*), /orders/$
5.1.2 基于Java代码的路由
java
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class GatewayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
// 路由1
.route("user-service-route", r -> r
.path("/api/users/**")
.filters(f -> f
.rewritePath("/api/users/(?<segment>.*)", "/users/$")
)
.uri("lb://user-service")
)
// 路由2
.route("order-service-route", r -> r
.path("/api/orders/**")
.filters(f -> f
.rewritePath("/api/orders/(?<segment>.*)", "/orders/$")
)
.uri("lb://order-service")
)
.build();
}
}
5.2 路由URI
路由URI支持以下几种协议:
- http/https:转发到HTTP/HTTPS服务
- lb:负载均衡,转发到服务注册中心中的服务
- ws/wss:转发到WebSocket服务
yaml
# HTTP服务
uri: http://localhost:8081
# 负载均衡
uri: lb://user-service
# WebSocket服务
uri: ws://localhost:8082
5.3 动态路由
Spring Cloud Gateway支持动态路由,可以通过配置中心(如Spring Cloud Config)或API动态更新路由规则。
5.3.1 使用配置中心
- 添加配置中心依赖:
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>3.1.3</version>
</dependency>
- 配置配置中心:
yaml
spring:
cloud:
config:
uri: http://localhost:8888
name: gateway-service
profile: dev
- 在配置中心中定义路由规则,Gateway会自动刷新路由配置。
5.3.2 使用API动态路由
Spring Cloud Gateway提供了RouteDefinitionRepository接口,可以实现自定义的路由仓库,支持动态添加、删除和更新路由。
java
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class InMemoryRouteDefinitionRepository implements RouteDefinitionRepository {
private final Map<String, RouteDefinition> routes = new ConcurrentHashMap<>();
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
return Flux.fromIterable(routes.values());
}
@Override
public Mono<Void> save(Mono<RouteDefinition> route) {
return route.flatMap(routeDefinition -> {
routes.put(routeDefinition.getId(), routeDefinition);
return Mono.empty();
});
}
@Override
public Mono<Void> delete(Mono<String> routeId) {
return routeId.flatMap(id -> {
if (routes.containsKey(id)) {
routes.remove(id);
}
return Mono.empty();
});
}
}
6. 路由断言
路由断言用于判断请求是否匹配某个路由规则。Spring Cloud Gateway提供了丰富的内置断言,也支持自定义断言。
6.1 内置断言
6.1.1 路径断言(Path)
路径断言用于匹配请求路径:
yaml
predicates:
- Path=/api/users/**
java
.route("user-service-route", r -> r
.path("/api/users/**")
.uri("lb://user-service")
)
6.1.2 方法断言(Method)
方法断言用于匹配HTTP请求方法:
yaml
predicates:
- Method=GET,POST
java
.route("user-service-route", r -> r
.method("GET", "POST")
.uri("lb://user-service")
)
6.1.3 头断言(Header)
头断言用于匹配请求头:
yaml
predicates:
- Header=X-Request-Id, \d+
java
.route("user-service-route", r -> r
.header("X-Request-Id", "\\d+")
.uri("lb://user-service")
)
6.1.4 参数断言(Query)
参数断言用于匹配请求参数:
yaml
predicates:
- Query=name
- Query=age, \d+
java
.route("user-service-route", r -> r
.query("name")
.query("age", "\\d+")
.uri("lb://user-service")
)
6.1.5 主机断言(Host)
主机断言用于匹配请求主机:
yaml
predicates:
- Host=**.example.com
java
.route("user-service-route", r -> r
.host("**.example.com")
.uri("lb://user-service")
)
6.1.6 Cookie断言(Cookie)
Cookie断言用于匹配请求Cookie:
yaml
predicates:
- Cookie=sessionId, \w+
java
.route("user-service-route", r -> r
.cookie("sessionId", "\\w+")
.uri("lb://user-service")
)
6.1.7 权重断言(Weight)
权重断言用于实现负载均衡:
yaml
routes:
- id: user-service-v1
uri: lb://user-service-v1
predicates:
- Path=/api/users/**
- Weight=group1, 80
- id: user-service-v2
uri: lb://user-service-v2
predicates:
- Path=/api/users/**
- Weight=group1, 20
java
.route("user-service-v1", r -> r
.path("/api/users/**")
.weight("group1", 80)
.uri("lb://user-service-v1")
)
.route("user-service-v2", r -> r
.path("/api/users/**")
.weight("group1", 20)
.uri("lb://user-service-v2")
)
6.1.8 时间断言(After/Before/Between)
时间断言用于匹配请求时间:
yaml
predicates:
- After=2023-01-01T00:00:00+08:00[Asia/Shanghai]
- Before=2024-01-01T00:00:00+08:00[Asia/Shanghai]
- Between=2023-01-01T00:00:00+08:00[Asia/Shanghai], 2024-01-01T00:00:00+08:00[Asia/Shanghai]
java
import java.time.ZonedDateTime;
.route("user-service-route", r -> r
.after(ZonedDateTime.parse("2023-01-01T00:00:00+08:00[Asia/Shanghai]"))
.uri("lb://user-service")
)
6.1.9 远程地址断言(RemoteAddr)
远程地址断言用于匹配客户端IP地址:
yaml
predicates:
- RemoteAddr=192.168.1.0/24
java
.route("user-service-route", r -> r
.remoteAddr("192.168.1.0/24")
.uri("lb://user-service")
)
6.2 自定义断言
可以通过实现RoutePredicateFactory接口来自定义断言:
java
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
@Component
public class CustomRoutePredicateFactory extends AbstractRoutePredicateFactory<CustomRoutePredicateFactory.Config> {
public CustomRoutePredicateFactory() {
super(Config.class);
}
@Validated
public static class Config {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
@Override
public List<String> shortcutFieldOrder() {
return Collections.singletonList("value");
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {
// 自定义断言逻辑
String requestValue = exchange.getRequest().getQueryParams().getFirst("custom");
return config.getValue().equals(requestValue);
};
}
}
使用自定义断言:
yaml
predicates:
- Custom=test
java
.route("user-service-route", r -> r
.predicate(new CustomRoutePredicateFactory().apply(config -> {
config.setValue("test");
return config;
}))
.uri("lb://user-service")
)
7. 过滤器
过滤器用于在请求被路由到后端服务之前或之后修改请求和响应。Spring Cloud Gateway提供了两种类型的过滤器:
- GatewayFilter:局部过滤器,仅应用于特定的路由
- GlobalFilter:全局过滤器,应用于所有路由
7.1 内置GatewayFilter
7.1.1 重写路径过滤器(RewritePath)
重写路径过滤器用于重写请求路径:
yaml
filters:
- RewritePath=/api/users/(?<segment>.*), /users/$
java
.route("user-service-route", r -> r
.path("/api/users/**")
.filters(f -> f
.rewritePath("/api/users/(?<segment>.*)", "/users/$")
)
.uri("lb://user-service")
)
7.1.2 添加请求头过滤器(AddRequestHeader)
添加请求头过滤器用于添加请求头:
yaml
filters:
- AddRequestHeader=X-Request-Id, 123456
java
.route("user-service-route", r -> r
.path("/api/users/**")
.filters(f -> f
.addRequestHeader("X-Request-Id", "123456")
)
.uri("lb://user-service")
)
7.1.3 添加响应头过滤器(AddResponseHeader)
添加响应头过滤器用于添加响应头:
yaml
filters:
- AddResponseHeader=X-Response-Id, 123456
java
.route("user-service-route", r -> r
.path("/api/users/**")
.filters(f -> f
.addResponseHeader("X-Response-Id", "123456")
)
.uri("lb://user-service")
)
7.1.4 移除请求头过滤器(RemoveRequestHeader)
移除请求头过滤器用于移除请求头:
yaml
filters:
- RemoveRequestHeader=X-Request-Id
java
.route("user-service-route", r -> r
.path("/api/users/**")
.filters(f -> f
.removeRequestHeader("X-Request-Id")
)
.uri("lb://user-service")
)
7.1.5 移除响应头过滤器(RemoveResponseHeader)
移除响应头过滤器用于移除响应头:
yaml
filters:
- RemoveResponseHeader=X-Response-Id
java
.route("user-service-route", r -> r
.path("/api/users/**")
.filters(f -> f
.removeResponseHeader("X-Response-Id")
)
.uri("lb://user-service")
)
7.1.6 请求参数过滤器(AddRequestParameter)
请求参数过滤器用于添加请求参数:
yaml
filters:
- AddRequestParameter=version, v1
java
.route("user-service-route", r -> r
.path("/api/users/**")
.filters(f -> f
.addRequestParameter("version", "v1")
)
.uri("lb://user-service")
)
7.1.7 前缀过滤器(PrefixPath)
前缀过滤器用于在请求路径前添加前缀:
yaml
filters:
- PrefixPath=/api
java
.route("user-service-route", r -> r
.path("/users/**")
.filters(f -> f
.prefixPath("/api")
)
.uri("lb://user-service")
)
7.1.8 移除前缀过滤器(StripPrefix)
移除前缀过滤器用于移除请求路径的前缀:
yaml
filters:
- StripPrefix=1
java
.route("user-service-route", r -> r
.path("/api/users/**")
.filters(f -> f
.stripPrefix(1)
)
.uri("lb://user-service")
)
7.1.9 重试过滤器(Retry)
重试过滤器用于在请求失败时重试:
yaml
filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY
methods: GET
backoff:
firstBackoff: 100ms
maxBackoff: 1s
factor: 2
basedOnPreviousValue: false
java
.route("user-service-route", r -> r
.path("/api/users/**")
.filters(f -> f
.retry(retryConfig -> {
retryConfig.setRetries(3);
retryConfig.setStatuses(HttpStatus.BAD_GATEWAY);
retryConfig.setMethods(HttpMethod.GET);
retryConfig.setBackoff(100, 1000, 2, false);
})
)
.uri("lb://user-service")
)
7.1.10 限流过滤器(RequestRateLimiter)
限流过滤器用于限制请求速率:
yaml
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1
java
.route("user-service-route", r -> r
.path("/api/users/**")
.filters(f -> f
.requestRateLimiter(config -> {
config.setRateLimiter(redisRateLimiter());
config.setReplenishRate(10);
config.setBurstCapacity(20);
config.setRequestedTokens(1);
})
)
.uri("lb://user-service")
)
7.2 自定义GatewayFilter
可以通过实现GatewayFilterFactory接口来自定义GatewayFilter:
java
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@Component
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomGatewayFilterFactory.Config> {
private final AtomicInteger counter = new AtomicInteger(0);
public CustomGatewayFilterFactory() {
super(Config.class);
}
public static class Config {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
@Override
public List<String> shortcutFieldOrder() {
return Collections.singletonList("message");
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
// 前置处理
System.out.println("CustomGatewayFilter: " + config.getMessage());
exchange.getAttributes().put("requestCount", counter.incrementAndGet());
// 调用下一个过滤器
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
// 后置处理
Integer requestCount = exchange.getAttributes().get("requestCount");
System.out.println("Request count: " + requestCount);
}));
};
}
}
使用自定义GatewayFilter:
yaml
filters:
- Custom=Hello World
java
.route("user-service-route", r -> r
.path("/api/users/**")
.filters(f -> f
.filter(new CustomGatewayFilterFactory().apply(config -> {
config.setMessage("Hello World");
return config;
}))
)
.uri("lb://user-service")
)
7.3 全局过滤器
全局过滤器应用于所有路由,可以通过实现GlobalFilter接口来创建全局过滤器:
java
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 前置处理
System.out.println("CustomGlobalFilter前置处理");
// 调用下一个过滤器
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
// 后置处理
System.out.println("CustomGlobalFilter后置处理");
}));
}
@Override
public int getOrder() {
// 过滤器顺序,数值越小优先级越高
return 0;
}
}
8. 限流功能
Spring Cloud Gateway支持限流功能,可以通过集成Redis实现令牌桶算法的限流。
8.1 添加依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
<version>2.6.8</version>
</dependency>
8.2 配置Redis
yaml
spring:
redis:
host: localhost
port: 6379
password:
database: 0
8.3 配置限流
8.3.1 基于请求路径的限流
yaml
routes:
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10 # 每秒允许的请求数
redis-rate-limiter.burstCapacity: 20 # 令牌桶的容量
redis-rate-limiter.requestedTokens: 1 # 每个请求需要的令牌数
8.3.2 基于用户的限流
java
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;
@Configuration
public class RateLimiterConfig {
@Bean
public KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
}
yaml
routes:
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1
key-resolver: "#{@userKeyResolver}"
8.3.3 基于IP地址的限流
java
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}
yaml
routes:
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1
key-resolver: "#{@ipKeyResolver}"
8.4 自定义限流算法
可以通过实现RateLimiter接口来自定义限流算法:
java
import org.springframework.cloud.gateway.filter.ratelimit.AbstractRateLimiter;
import org.springframework.cloud.gateway.filter.ratelimit.RateLimiter;import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import reactor.core.publisher.Mono;
@Component
public class CustomRateLimiter extends AbstractRateLimiter<CustomRateLimiter.Config> implements RateLimiter<CustomRateLimiter.Config> {
private final Map<String, AtomicInteger> counters = new ConcurrentHashMap<>();
public CustomRateLimiter() {
super(Config.class, "custom-rate-limiter");
}
public static class Config {
private int limit;
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
}
@Override
public Mono<Response> isAllowed(String routeId, String key) {
return Mono.fromSupplier(() -> {
// 自定义限流逻辑
AtomicInteger counter = counters.computeIfAbsent(key, k -> new AtomicInteger(0));
int count = counter.incrementAndGet();
// 每秒重置计数器
if (count == 1) {
new Thread(() -> {
try {
Thread.sleep(1000);
counters.remove(key);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
boolean allowed = count <= getConfig().getLimit();
return new Response(allowed, Map.of("remaining", Math.max(0, getConfig().getLimit() - count)));
});
}
}
使用自定义限流算法:
yaml
routes:
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@customRateLimiter}"
custom-rate-limiter.limit: 10
9. 熔断功能
Spring Cloud Gateway支持熔断功能,可以与Hystrix、Resilience4j等熔断组件集成。
9.1 与Resilience4j集成
9.1.1 添加依赖
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
<version>2.1.3</version>
</dependency>
9.1.2 配置熔断
yaml
spring:
cloud:
gateway:
routes:
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- name: CircuitBreaker
args:
name: userServiceCircuitBreaker
fallbackUri: forward:/fallback/users
resilience4j:
circuitbreaker:
instances:
userServiceCircuitBreaker:
registerHealthIndicator: true
slidingWindowSize: 10
minimumNumberOfCalls: 5
permittedNumberOfCallsInHalfOpenState: 3
automaticTransitionFromOpenToHalfOpenEnabled: true
waitDurationInOpenState: 5s
failureRateThreshold: 50
eventConsumerBufferSize: 10
9.1.3 实现降级处理
java
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FallbackController {
@RequestMapping("/fallback/users")
public String fallbackUsers() {
return "User service is unavailable, please try again later.";
}
}
9.2 与Hystrix集成
9.2.1 添加依赖
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
9.2.2 配置熔断
yaml
spring:
cloud:
gateway:
routes:
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- Hystrix=fallbackCommand
# Hystrix配置
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000
fallbackCommand:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000
9.2.3 实现降级处理
java
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.HystrixCommands;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import static org.springframework.web.reactive.function.server.RequestPredicates.path;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
@Configuration
@EnableHystrix
public class HystrixConfig {
@Bean
public RouterFunction<ServerResponse> fallbackRoute() {
return route(path("/fallback/users"), request ->
ServerResponse.ok().body(Mono.just("User service is unavailable, please try again later."), String.class));
}
}
10. 安全性
Spring Cloud Gateway可以与Spring Security无缝集成,实现安全认证和授权。
10.1 添加依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.6.8</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
<version>5.6.3</version>
</dependency>
10.2 配置Spring Security
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange(exchanges -> exchanges
// 允许访问健康检查和指标端点
.pathMatchers("/actuator/health", "/actuator/info").permitAll()
// 其他请求需要认证
.anyExchange().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2
// 使用JWT认证
.jwt(jwt -> jwt
.jwtDecoder(jwtDecoder())
)
);
return http.build();
}
@Bean
public JwtDecoder jwtDecoder() {
// 配置JWT解码器
return NimbusJwtDecoder.withJwkSetUri("http://localhost:8080/.well-known/jwks.json").build();
}
}
10.3 配置CORS
yaml
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "*"
allowedMethods: "*"
allowedHeaders: "*"
allowCredentials: true
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsWebFilter() {
CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.setAllowedOrigins(Arrays.asList("*"));
corsConfig.setAllowedMethods(Arrays.asList("*"));
corsConfig.setAllowedHeaders(Arrays.asList("*"));
corsConfig.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig);
return new CorsWebFilter(source);
}
}
11. 监控和可观测性
Spring Cloud Gateway提供了丰富的监控指标和日志支持,可以通过Spring Boot Actuator监控网关的运行状态。
11.1 启用Actuator
yaml
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
metrics:
tags:
application: ${spring.application.name}
11.2 监控指标
Spring Cloud Gateway提供了以下监控指标:
- gateway.requests:请求计数和持续时间
- gateway.routes:路由计数
- gateway.filter:过滤器执行计数和持续时间
可以通过以下端点访问监控指标:
- /actuator/health:健康检查
- /actuator/metrics:所有指标
- /actuator/metrics/gateway.requests:请求指标
- /actuator/metrics/gateway.routes:路由指标
- /actuator/metrics/gateway.filter:过滤器指标
- /actuator/prometheus:Prometheus格式的指标
11.3 日志配置
yaml
logging:
level:
org.springframework.cloud.gateway: DEBUG
org.springframework.web.reactive: DEBUG
reactor.netty: DEBUG
11.4 分布式追踪
Spring Cloud Gateway可以与Sleuth和Zipkin集成,实现分布式追踪:
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
<version>3.1.3</version>
</dependency>
yaml
spring:
zipkin:
base-url: http://localhost:9411/
enabled: true
sleuth:
sampler:
probability: 1.0
12. 最佳实践
12.1 路由设计
- 使用清晰的路由ID:路由ID应该具有描述性,便于识别和调试
- 合理划分路由:根据业务模块划分路由,避免路由过于复杂
- 使用服务发现:优先使用服务发现(如Eureka、Consul),避免硬编码服务地址
- 使用负载均衡:使用负载均衡(如Ribbon),提高系统的可用性和性能
12.2 过滤器使用
- 合理使用过滤器:只添加必要的过滤器,避免过滤器链过长影响性能
- 使用全局过滤器:对于所有路由都需要的功能,使用全局过滤器
- 使用局部过滤器:对于特定路由需要的功能,使用局部过滤器
- 自定义过滤器:根据业务需求自定义过滤器,实现特定功能
12.3 性能优化
- 启用连接池:启用HTTP连接池,减少TCP连接建立的开销
- 启用压缩:启用请求和响应压缩,减少网络传输量
- 使用缓存:对于频繁访问的静态资源,使用缓存减少后端服务压力
- 优化路由匹配:使用精确的路由匹配,避免模糊匹配影响性能
- 使用异步处理:使用异步处理,提高系统的并发处理能力
12.4 安全性
- 启用SSL/TLS:加密网络通信,保护数据安全
- 使用认证和授权:对所有请求进行认证和授权,防止未授权访问
- 启用CORS:配置合理的CORS策略,防止跨域攻击
- 使用JWT:使用JWT进行身份认证,避免会话管理的复杂性
- 定期更新依赖:定期更新依赖,修复安全漏洞
12.5 监控和可观测性
- 启用Actuator:启用Actuator,监控系统的运行状态
- 配置日志:配置合理的日志级别,便于调试和问题定位
- 使用分布式追踪:使用分布式追踪(如Sleuth和Zipkin),追踪请求的完整路径
- 使用APM工具:使用APM工具(如SkyWalking、Pinpoint),实现系统的全链路监控
13. 总结
Spring Cloud Gateway是Spring Cloud生态系统中的新一代API网关组件,它基于Spring Boot 2.x和Spring WebFlux构建,提供了高性能、响应式的网关服务。
Spring Cloud Gateway具有以下主要特点:
- 响应式编程模型:基于WebFlux构建,支持高并发、低延迟的响应式编程
- 动态路由:支持动态配置和更新路由规则
- 强大的过滤器链:提供丰富的内置过滤器和自定义过滤器支持
- 限流和熔断:集成Redis实现限流,支持与Hystrix、Resilience4j等熔断组件集成
- 安全认证:与Spring Security无缝集成,支持OAuth2、JWT等认证方式
- 监控和可观测性:提供详细的监控指标和日志支持
- 与Spring Cloud生态集成:与Eureka、Consul、Nacos等服务注册中心无缝集成
通过本文的学习,读者可以了解Spring Cloud Gateway的核心概念、架构设计、安装配置、路由规则、过滤器、限流熔断等功能,并能够使用Spring Cloud Gateway构建高性能、可靠的API网关服务。
在实际项目中,Spring Cloud Gateway可以帮助开发者实现系统的统一入口管理、请求路由、负载均衡、安全认证、限流熔断等功能,提高系统的可用性、安全性和性能。随着微服务架构的广泛应用,Spring Cloud Gateway将成为构建现代微服务系统的重要组件。