Spring Gateway 是基于 Spring Framework 的 API 网关,它为微服务架构提供了路由、监控、弹性以及安全性等功能。Spring Gateway 使用非阻塞 API 和高性能的反应式编程模型来提供服务。
本文的选项在多个最近的 Spring Cloud Gateway 版本中都是有效的,比如 Spring Cloud 2020.0.x 至 2021.0.x 版本系列。与 Spring Boot 2.3.x 至 2.6.x 版本兼容。
以下是一个完整的 Spring Gateway 配置示例,包含了常见的路由配置、过滤器使用、全局过滤器配置以及一些其他常用的设置。这些配置将在 application.yml
文件中进行设置:
spring:
cloud:
gateway:
# 路由配置列表
routes:
# 第一条路由规则
- id: route1
uri: http://example.org
predicates:
- Path=/api/service1/** # 路径匹配规则
filters:
- AddRequestHeader=X-Request-Foo, Bar # 添加请求头
# 第二条路由规则
- id: route2
uri: http://example.com
predicates:
- Path=/api/service2/**
- Method=GET,POST # 只允许 GET 和 POST 方法
filters:
- RewritePath=/api/service2/(?>.*), /$\{segment} # URL 重写
# 全局过滤器配置
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin # 去重HTTP响应头
# 用于控制 HTTP 请求的负载均衡器配置
loadbalancer:
use404: true # 当无可用服务时返回404
# HTTP请求重试配置
retry:
enabled: true
retries: 3 # 重试次数
statuses: BAD_GATEWAY,GATEWAY_TIMEOUT # 触发重试的HTTP状态码
methods: GET,POST # 允许重试的HTTP方法
backoff:
firstBackoff: 50ms # 首次重试的延迟
maxBackoff: 500ms # 最大重试延迟
factor: 2 # 延迟因子
basedOnPreviousValue: false # 延迟是否基于上一次的延迟时间
# 跨域配置
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "*" # 允许所有域
allowedMethods: "*" # 允许所有方法
allowedHeaders: "*" # 允许所有头
allowCredentials: true # 允许证书
# Spring 应用名称
spring:
application:
name: gateway-service
# 服务端口
server:
port: 8080
# 日志配置
logging:
level:
org.springframework.cloud.gateway: DEBUG # 设置Spring Gateway的日志级别为DEBUG
在这个示例中,配置了两条路由规则,每条规则都设置了特定的路径匹配和过滤器。还配置了全局的过滤器,用于去重响应头。另外还包含了负载均衡器配置、重试机制以及全局跨域资源共享(CORS)配置。
Spring Cloud Gateway 提供了丰富的配置选项来支持各种高级功能,包括但不限于过滤器自定义、安全性增强、限流、WebSocket 支持和更复杂的路由条件。
如果你需要将 Spring Security 集成到 Spring Cloud Gateway 中,以增强 API 网关的安全性,你可以添加如下依赖并配置相应的安全规则:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
然后,你可以配置基本的 HTTP 安全规则,如下所示:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
}
}
限流可以帮助你控制对后端服务的请求频率,防止过载。Spring Cloud Gateway 可以通过集成 Redis 来实现请求的限流:
spring:
cloud:
gateway:
routes:
- id: route1
uri: http://example.org
predicates:
- Path=/api/service1/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
Spring Cloud Gateway 支持 WebSocket 代理,需要适当的路由配置:
spring:
cloud:
gateway:
routes:
- id: websocket_route
uri: ws://example-websocket.org
predicates:
- Path=/echo
在一些场景下,你可能需要动态地添加或删除路由。这可以通过编程方式实现,比如使用 RouteDefinitionWriter
和 ApplicationEventPublisher
:
@Autowired
private RouteDefinitionWriter routeWriter;
@Autowired
private ApplicationEventPublisher publisher;
public void addRoute(RouteDefinition routeDefinition) {
routeWriter.save(Mono.just(routeDefinition)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
}
Spring Cloud Gateway 集成了 Resilience4j 来提供熔断器支持,可以配置熔断规则来保护后端服务:
spring:
cloud:
gateway:
routes:
- id: route1
uri: http://example.org
filters:
- name: CircuitBreaker
args:
name: backendService
fallbackUri: forward:/fallback
为了更好地监控和诊断网关流量,可以集成 Spring Cloud Sleuth 和 Zipkin 进行调用链跟踪。这可以帮助你详细了解请求如何通过你的网关和服务。首先需要添加 Sleuth 和 Zipkin 的依赖:
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-sleuthartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-sleuth-zipkinartifactId>
dependency>
配置 Zipkin 的服务地址:
spring:
zipkin:
baseUrl: http://localhost:9411
sleuth:
sampler:
probability: 1.0 # 采样率
Spring Cloud Gateway 允许你根据请求参数、头信息等进行路由匹配。例如,你可以根据请求头中的版本号将流量路由到不同的后端服务:
spring:
cloud:
gateway:
routes:
- id: route1
uri: http://example.org/v1
predicates:
- Path=/api/service
- Header=X-API-Version, v1
- id: route2
uri: http://example.org/v2
predicates:
- Path=/api/service
- Header=X-API-Version, v2
在不同的环境(开发、测试、生产)中,你可能需要不同的配置。Spring Cloud Gateway 允许你使用 Spring 的 profile 功能来定义环境特定的配置。例如,你可以为开发环境和生产环境定义不同的路由和过滤器配置:
---
spring:
profiles: dev
cloud:
gateway:
routes:
- id: dev_route
uri: http://dev.example.org
predicates:
- Path=/api/dev/**
---
spring:
profiles: prod
cloud:
gateway:
routes:
- id: prod_route
uri: http://prod.example.org
predicates:
- Path=/api/prod/**
在某些情况下,你可能需要修改从后端服务返回的响应。Spring Cloud Gateway 提供了过滤器来重写响应头和响应体:
spring:
cloud:
gateway:
routes:
- id: rewrite_response
uri: http://example.org
filters:
- ModifyResponseBody=/path, ${{response.body}} Modified
- ModifyResponseHeader=X-Response-Header, New-Header-Value
如果预置的过滤器不能满足你的需求,你可以实现自己的过滤器。你可以继承 AbstractGatewayFilterFactory
类来创建自定义的过滤器逻辑:
public class MyCustomFilter extends AbstractGatewayFilterFactory<MyCustomFilter.Config> {
public static class Config {
// Put the configuration properties for your filter here
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
// custom pre-processing
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
// custom post-processing
}));
};
}
}
继续探索 Spring Cloud Gateway 的高级配置,这些配置可以进一步增强你的网关的功能性和灵活性。以下是一些额外的配置选项和高级用法,它们可以帮助你更好地适应复杂的业务需求:
虽然 Resilience4j 是现代的断路器选择,但如果你的项目还在使用 Hystrix,Spring Cloud Gateway 也支持与 Hystrix 的集成。你可以为特定路由添加 Hystrix 保护:
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: http://example.org
filters:
- name: Hystrix
args:
name: myCommand
fallbackUri: forward:/fallback
在一些应用场景中,需要对请求进行额外的验证,比如检查请求中的 JWT 令牌。Spring Cloud Gateway 允许通过全局过滤器或路由特定过滤器来实现这一点:
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("token_route", r -> r.path("/token/**")
.filters(f -> f.filter(new AuthFilter()))
.uri("http://example.org"))
.build();
}
public class AuthFilter implements GatewayFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 实现验证逻辑
boolean isValid = checkAuthToken(exchange.getRequest());
if (!isValid) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
private boolean checkAuthToken(ServerHttpRequest request) {
// 验证逻辑
return true; // 假设总是有效
}
}
你可以通过配置多个路由来支持不同版本的 API,以方便客户端调用最合适的服务版本:
spring:
cloud:
gateway:
routes:
- id: api_v1
uri: http://example.org/v1
predicates:
- Path=/api/v1/**
- id: api_v2
uri: http://example.org/v2
predicates:
- Path=/api/v2/**
Spring Cloud Gateway 允许通过数据库或其他服务动态加载和更改路由配置。这可以通过自定义 RouteDefinitionLocator
实现:
@Bean
public RouteDefinitionLocator databaseRouteLocator() {
return new DatabaseRouteDefinitionLocator();
}
public class DatabaseRouteDefinitionLocator implements RouteDefinitionLocator {
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
// 从数据库加载路由定义
return Flux.fromIterable(fetchRoutesFromDatabase());
}
private List<RouteDefinition> fetchRoutesFromDatabase() {
// 数据库操作,返回路由定义列表
return new ArrayList<>();
}
}
你可以通过定义自己的 ErrorWebExceptionHandler
来定制网关在遇到错误时的行为:
@Bean
@Order(-1) // 确保它比默认的错误处理器优先级高
public ErrorWebExceptionHandler myExceptionHandler() {
return new JsonErrorWebExceptionHandler();
}
public class JsonErrorWebExceptionHandler implements ErrorWebExceptionHandler {
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
exchange.getResponse().setStatusCode(HttpStatus.BAD_GATEWAY);
// 设置响应体等
return exchange.getResponse().writeWith(Mono.just(...));
}
}