前言
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 支持和更复杂的路由条件。
1. 安全配置
如果你需要将 Spring Security 集成到 Spring Cloud Gateway 中,以增强 API 网关的安全性,你可以添加如下依赖并配置相应的安全规则:
org.springframework.boot spring-boot-starter-security
然后,你可以配置基本的 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(); } }
2. 限流策略
限流可以帮助你控制对后端服务的请求频率,防止过载。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
3. WebSocket 支持
Spring Cloud Gateway 支持 WebSocket 代理,需要适当的路由配置:
spring: cloud: gateway: routes: - id: websocket_route uri: ws://example-websocket.org predicates: - Path=/echo
4. 动态路由
在一些场景下,你可能需要动态地添加或删除路由。这可以通过编程方式实现,比如使用 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)); }
5. 熔断器配置
Spring Cloud Gateway 集成了 Resilience4j 来提供熔断器支持,可以配置熔断规则来保护后端服务:
spring: cloud: gateway: routes: - id: route1 uri: http://example.org filters: - name: CircuitBreaker args: name: backendService fallbackUri: forward:/fallback
6. 跟踪和日志记录
为了更好地监控和诊断网关流量,可以集成 Spring Cloud Sleuth 和 Zipkin 进行调用链跟踪。这可以帮助你详细了解请求如何通过你的网关和服务。首先需要添加 Sleuth 和 Zipkin 的依赖:
org.springframework.cloud spring-cloud-starter-sleuth org.springframework.cloud spring-cloud-sleuth-zipkin
配置 Zipkin 的服务地址:
spring: zipkin: baseUrl: http://localhost:9411 sleuth: sampler: probability: 1.0 # 采样率
7. 参数化路由匹配
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
8. 环境特定配置
在不同的环境(开发、测试、生产)中,你可能需要不同的配置。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/**
9. 响应重写
在某些情况下,你可能需要修改从后端服务返回的响应。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
10. 自定义过滤器
如果预置的过滤器不能满足你的需求,你可以实现自己的过滤器。你可以继承 AbstractGatewayFilterFactory 类来创建自定义的过滤器逻辑:
public class MyCustomFilter extends AbstractGatewayFilterFactory{ 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 的高级配置,这些配置可以进一步增强你的网关的功能性和灵活性。以下是一些额外的配置选项和高级用法,它们可以帮助你更好地适应复杂的业务需求:
11. Hystrix 集成
虽然 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
12. 路由验证
在一些应用场景中,需要对请求进行额外的验证,比如检查请求中的 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 Monofilter(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; // 假设总是有效 } }
13. API 版本管理
你可以通过配置多个路由来支持不同版本的 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/**
14. 更多动态路由配置
Spring Cloud Gateway 允许通过数据库或其他服务动态加载和更改路由配置。这可以通过自定义 RouteDefinitionLocator 实现:
@Bean public RouteDefinitionLocator databaseRouteLocator() { return new DatabaseRouteDefinitionLocator(); } public class DatabaseRouteDefinitionLocator implements RouteDefinitionLocator { @Override public FluxgetRouteDefinitions() { // 从数据库加载路由定义 return Flux.fromIterable(fetchRoutesFromDatabase()); } private List fetchRoutesFromDatabase() { // 数据库操作,返回路由定义列表 return new ArrayList<>(); } }
15. 定制错误处理
你可以通过定义自己的 ErrorWebExceptionHandler 来定制网关在遇到错误时的行为:
@Bean @Order(-1) // 确保它比默认的错误处理器优先级高 public ErrorWebExceptionHandler myExceptionHandler() { return new JsonErrorWebExceptionHandler(); } public class JsonErrorWebExceptionHandler implements ErrorWebExceptionHandler { @Override public Monohandle(ServerWebExchange exchange, Throwable ex) { exchange.getResponse().setStatusCode(HttpStatus.BAD_GATEWAY); // 设置响应体等 return exchange.getResponse().writeWith(Mono.just(...)); } }
还没有评论,来说两句吧...