Spring Cloud Gateway -- 架构图和安全认证,熔断降级等代码示例

一、整体架构图

客户端 → Nginx (负载均衡) → Spring Cloud Gateway → 微服务集群
                      ↑
               服务注册中心 (Eureka/Nacos)

二、详细架构流程图

客户端
Nginx
Spring Cloud Gateway
服务注册中心
微服务A
微服务B
微服务C

让我们通过一个具体的例子来说明整个请求流程:客户端调用 api/userService/userInfo 获取用户信息。

Spring Cloud Gateway 请求调用用户服务的完整流程示例

让我们通过一个具体的例子来说明整个请求流程:客户端调用 api/userService/userInfo 获取用户信息。

三、Nginx 配置示例

upstream gateway {
    server gateway1.example.com:8080;
    server gateway2.example.com:8080;
    keepalive 64;
}

server {
    listen 80;
    server_name api.example.com;
    
    location / {
        proxy_pass http://gateway;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        # 长连接优化
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        
        # 超时设置
        proxy_connect_timeout 5s;
        proxy_read_timeout 60s;
    }
    
    # 健康检查
    location /health {
        proxy_pass http://gateway/actuator/health;
    }
}

四、Spring Cloud Gateway 最佳实践

1. 基础配置示例

application.yml

spring:
  cloud:
    gateway:
      httpclient:
        pool:
          max-idle-time: 60000
          max-connections: 1000
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 100
                redis-rate-limiter.burstCapacity: 200
            - name: Retry
              args:
                retries: 3
                statuses: BAD_GATEWAY,INTERNAL_SERVER_ERROR
                methods: GET,POST

2. 安全实践

JWT 认证过滤器

@Component
public class JwtAuthFilter implements GlobalFilter {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        
        if (StringUtils.isEmpty(token)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        
        try {
            // 验证token逻辑
            Claims claims = Jwts.parser()
                .setSigningKey("secret")
                .parseClaimsJws(token.replace("Bearer ", ""))
                .getBody();
            
            // 将用户信息添加到header
            exchange.getRequest().mutate()
                .header("X-User-Id", claims.getSubject())
                .build();
            
            return chain.filter(exchange);
        } catch (Exception e) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
    }
}

3. 熔断降级配置

spring:
  cloud:
    gateway:
      routes:
      - id: order-service
        uri: lb://order-service
        predicates:
        - Path=/api/orders/**
        filters:
        - name: Hystrix
          args:
            name: fallbackcmd
            fallbackUri: forward:/fallback/order

Fallback 控制器

@RestController
@RequestMapping("/fallback")
public class FallbackController {
    
    @GetMapping("/order")
    public Mono<ResponseEntity<String>> orderFallback() {
        return Mono.just(ResponseEntity
            .status(HttpStatus.SERVICE_UNAVAILABLE)
            .body("Order Service is unavailable. Please try again later."));
    }
}

4. 监控与指标

management:
  endpoints:
    web:
      exposure:
        include: health,info,gateway,metrics
  endpoint:
    health:
      show-details: always
    gateway:
      enabled: true

五、高级实践代码示例

1. 动态路由配置

@Configuration
public class DynamicRouteConfig {
    
    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;
    
    public void addRoute(RouteDefinition definition) {
        routeDefinitionWriter.save(Mono.just(definition)).subscribe();
    }
    
    public void deleteRoute(String routeId) {
        routeDefinitionWriter.delete(Mono.just(routeId)).subscribe();
    }
}

2. 灰度发布过滤器

@Component
public class GrayReleaseFilter implements GlobalFilter {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String version = exchange.getRequest().getHeaders().getFirst("X-Version");
        
        if ("v2".equals(version)) {
            ServerHttpRequest request = exchange.getRequest().mutate()
                .header("X-Gray", "true")
                .build();
            return chain.filter(exchange.mutate().request(request).build());
        }
        
        return chain.filter(exchange);
    }
}

3. 请求日志过滤器

@Component
@Order(-1)
public class RequestLogFilter implements GlobalFilter {
    
    private static final Logger log = LoggerFactory.getLogger(RequestLogFilter.class);
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        long startTime = System.currentTimeMillis();
        String path = exchange.getRequest().getPath().toString();
        
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            long duration = System.currentTimeMillis() - startTime;
            int status = exchange.getResponse().getStatusCode() != null ? 
                exchange.getResponse().getStatusCode().value() : 500;
            
            log.info("Request {} - Status: {} - Time: {}ms", 
                path, status, duration);
        }));
    }
}

六、部署建议

  1. 高可用部署

    • 至少部署2个Gateway实例
    • 使用Nginx做负载均衡
  2. 性能优化

    spring:
      cloud:
        gateway:
          httpclient:
            pool:
              max-connections: 1000
              acquire-timeout: 5000
              max-idle-time: 60000
    
  3. 健康检查

    • 配置Kubernetes/ECS的健康检查端点:/actuator/health
    • 设置合理的检查间隔
  4. 日志收集

    • 集成ELK或类似日志系统
    • 记录关键请求信息

七、完整请求流程图

客户端NginxSpring Cloud Gateway服务注册中心(Eureka)用户服务发起请求 GET /api/userService/userInfo转发请求到Gateway查询userService的实例列表返回可用实例(如:192.168.1.10:8081)转发请求 GET /userInfo返回用户数据返回响应返回最终结果客户端NginxSpring Cloud Gateway服务注册中心(Eureka)用户服务
1. 客户端发起请求

客户端发送请求到Nginx入口:

GET http://api.yourdomain.com/api/userService/userInfo
Authorization: Bearer xxxxxx
2. Nginx反向代理

Nginx配置将请求转发到Gateway集群:

location /api/ {
    proxy_pass http://gateway_cluster/;
    # 其他代理配置...
}
3. Gateway接收请求并路由

Gateway路由配置 (application.yml):

spring:
  cloud:
    gateway:
      routes:
      - id: user-service-route
        uri: lb://user-service  # lb表示从服务注册中心获取负载均衡地址
        predicates:
        - Path=/api/userService/**
        filters:
        - StripPrefix=2  # 去掉/api/userService前缀
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 100
            redis-rate-limiter.burstCapacity: 200
4. Gateway处理流程
  1. 路由匹配:Gateway发现请求路径 /api/userService/userInfo 匹配 Path=/api/userService/** 断言
  2. 服务发现:通过lb://user-service从Eureka/Nacos获取用户服务的实际地址(如http://192.168.1.10:8081
  3. 过滤器处理
    • StripPrefix=2 过滤器将路径变为 /userInfo
    • 限流过滤器检查请求频率
    • 如果有其他全局过滤器(如JWT验证)也会执行
  4. 转发请求:Gateway将请求转发到用户服务实例:
    GET http://192.168.1.10:8081/userInfo
    
5. 用户服务处理

用户服务接收到请求:

@RestController
@RequestMapping("/userInfo")
public class UserController {
    
    @GetMapping
    public ResponseEntity<UserInfo> getUserInfo(@RequestHeader("X-User-Id") String userId) {
        // 业务逻辑处理
        UserInfo user = userService.getUserById(userId);
        return ResponseEntity.ok(user);
    }
}
6. 响应返回路径

响应沿原路返回:

用户服务 → Gateway → Nginx → 客户端

关键组件代码示例

1. Gateway全局过滤器(添加用户ID)
@Component
public class AuthFilter implements GlobalFilter {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        
        if (StringUtils.isEmpty(token)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        
        // 模拟JWT解析
        String userId = parseUserIdFromToken(token);
        
        // 将用户ID添加到header
        ServerHttpRequest request = exchange.getRequest().mutate()
                .header("X-User-Id", userId)
                .build();
        
        return chain.filter(exchange.mutate().request(request).build());
    }
    
    private String parseUserIdFromToken(String token) {
        // 实际项目中使用JWT库解析
        return "12345"; // 模拟返回用户ID
    }
}
2. 用户服务Controller
@RestController
public class UserController {
    
    @GetMapping("/userInfo")
    public Map<String, Object> getUserInfo(
            @RequestHeader("X-User-Id") String userId,
            HttpServletRequest request) {
        
        // 获取实际请求的IP(从Gateway转发)
        String clientIp = request.getHeader("X-Forwarded-For");
        
        return Map.of(
            "userId", userId,
            "username", "user_" + userId,
            "email", userId + "@example.com",
            "requestFrom", clientIp,
            "servicePort", request.getServerPort()
        );
    }
}
3. 测试请求示例

请求:

curl -X GET "http://api.yourdomain.com/api/userService/userInfo" \
-H "Authorization: Bearer mock_token_123"

响应:

{
  "userId": "12345",
  "username": "user_12345",
  "email": "12345@example.com",
  "requestFrom": "客户端真实IP",
  "servicePort": "8081"
}
  1. 统一入口:所有API请求都通过Gateway进入,简化客户端调用
  2. 服务发现:自动发现服务实例,无需硬编码IP
  3. 负载均衡:多个用户服务实例时自动均衡负载
  4. 横切关注点
    • 认证/授权在Gateway统一处理
    • 限流、熔断等保护措施
    • 日志记录和监控
  5. 路径转换:对外暴露友好API,内部服务可使用不同路径

通过这样的架构,你的微服务系统可以获得更好的可维护性、扩展性和安全性。

七、常见问题解决方案

  1. CORS问题
@Bean
public CorsWebFilter corsFilter() {
    return new CorsWebFilter(source -> {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        config.setMaxAge(3600L);
        return config;
    });
}
  1. 大文件上传
spring:
  webflux:
    max-in-memory-size: 10MB
  1. 请求超时
spring:
  cloud:
    gateway:
      httpclient:
        response-timeout: 10s
        connect-timeout: 2s

通过以上配置和实践,Spring Cloud Gateway 可以成为微服务架构中强大的API网关,提供路由、安全、监控等关键功能。

<think>我们根据用户的问题,结合引用内容,系统化地分析Spring Cloud Gateway的高级功能实现方案。用户的问题涉及多个方面,我们将逐一解答,并尽量结合图表Mermaid图进行说明。 ### 一、请求限流与熔断机制实现方案 #### 1. 限流机制(基于令牌桶算法) Spring Cloud Gateway使用`RequestRateLimiter`过滤器实现限流,默认采用Redis RateLimiter(基于令牌桶算法)。 ```mermaid graph LR A[请求] --> B{令牌桶状态} B -->|令牌充足| C[扣除令牌并转发] B -->|令牌不足| D[返回429错误] ``` **实现原理**: - 通过`RouteLocatorBuilder`添加`RequestRateLimiter`过滤器[^1]。 - 使用`RedisRateLimiter`维护分布式令牌桶状态。 **关键配置**(application.yml): ```yaml spring: cloud: gateway: routes: - id: my_route uri: http://example.org filters: - name: RequestRateLimiter args: key-resolver: "#{@ipKeyResolver}" # 引用限流维度Bean redis-rate-limiter: replenishRate: 20 # 每秒生成20个令牌 burstCapacity: 100 # 令牌桶容量100 ``` **自定义限流维度**(例如按IP限流): ```java @Bean public KeyResolver ipKeyResolver() { return exchange -> Mono.just( exchange.getRequest().getRemoteAddress().getHostName() ); } ``` #### 2. 熔断机制(断路器模式) Spring Cloud Gateway支持熔断器模式,通过`CircuitBreakerFilter`实现。 **熔断器状态转换**(引用[1]): - **Closed**:正常状态,请求直接通过。 - **Open**:熔断状态,所有请求被拒绝。 - **Half-Open**:半熔断状态,允许部分请求通过,如果成功则关闭熔断器,否则回到Open状态[^1]。 **原生熔断器配置**: ```yaml filters: - name: CircuitBreaker args: name: myCircuitBreaker fallbackUri: forward:/fallback ``` **Hystrix兼容方案**(旧版): ```yaml filters: - name: Hystrix args: name: serviceFallback fallbackUri: forward:/fallback ``` ### 二、自定义全局过滤器处理认证 通过实现`GlobalFilter`接口,可以创建全局认证过滤器。 **JWT认证过滤器示例**: ```java @Component @Order(-100) // 设置高优先级(数值越小优先级越高) public class JwtAuthFilter implements GlobalFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 1. 从请求头提取JWT令牌 String token = exchange.getRequest().getHeaders().getFirst("Authorization"); if (token == null || !token.startsWith("Bearer ")) { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } // 2. 验证令牌(假设validateToken是同步阻塞方法,需异步执行) return Mono.fromCallable(() -> validateToken(token)) .subscribeOn(Schedulers.boundedElastic()) // 切换到弹性线程池 .flatMap(valid -> { if (!valid) { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } // 3. 令牌有效,添加用户信息到请求头 ServerHttpRequest mutatedRequest = exchange.getRequest().mutate() .header("X-User", extractUser(token)) .build(); return chain.filter(exchange.mutate().request(mutatedRequest).build()); }); } } ``` **关键点**: - 使用`@Order`控制过滤器执行顺序(认证过滤器通常设置高优先级)。 - 阻塞操作(如JWT验证)必须使用`Schedulers.boundedElastic()`异步执行,避免阻塞响应式线程。 ### 三、与Zuul的优劣势对比 | **维度** | **Spring Cloud Gateway** | **Zuul 1.x** | |------------------|----------------------------------------|----------------------------| | **架构模型** | 非阻塞式(WebFlux + Reactor) | 阻塞式(Servlet API) | | **吞吐能力** | ⭐⭐⭐⭐(实测高$1.5 \times \sim 2 \times$) | ⭐⭐ | | **扩展机制** | 声明式路由+过滤器链 | 需实现`ZuulFilter` | | **限流熔断** | 原生支持+Sentinel集成 | 依赖Hystrix[^1][^2] | | **资源消耗** | 低线程占用(事件驱动) | 高线程开销(每请求一线程) | | **适用场景** | 云原生/高并发网关 | 传统架构迁移 | > **结论**:Gateway在性能、扩展性、云原生适配方面全面领先,Zuul仅适用于遗留系统改造[^1][^2]。 ### 四、结合Sentinel实现熔断降级 Sentinel提供更灵活的熔断降级规则,支持慢调用比例、异常比例等策略。 #### 1. 集成步骤 **添加依赖**(pom.xml): ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> </dependency> ``` **配置熔断规则**(动态规则源): ```java @Bean public DataSource sentinelDataSource() { return new NacosDataSource( "nacos-server:8848", "DEFAULT_GROUP", "gateway-rules", source -> JSON.parseArray(source, GatewayFlowRule.class) ); } ``` **熔断策略类型**: | **策略** | **适用场景** | **参数示例** | |----------------|-----------------------------|---------------------------| | 慢调用比例 | 保护响应缓慢的服务 | `maxRt=2000ms`, `ratio=0.5` | | 异常比例 | 服务稳定性波动场景 | `ratio=0.7` | | 异常数 | 低频但关键的服务 | `count=5` | #### 2. 熔断回调处理 自定义熔断响应: ```java @Bean public BlockRequestHandler blockHandler() { return (exchange, ex) -> ServerResponse.status(429) .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromValue("{\"code\":429,\"msg\":\"触发熔断\"}")); } ``` ### 五、响应式编程中处理阻塞调用 在响应式编程模型中,阻塞操作(如数据库访问)必须异步执行,避免阻塞Reactor线程。 **解决方案**: ```java public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 将阻塞操作调度到弹性线程池 return Mono.fromCallable(() -> blockingDBQuery()) .subscribeOn(Schedulers.boundedElastic()) // 关键:线程隔离 .flatMap(result -> { exchange.getAttributes().put("data", result); return chain.filter(exchange); }); } ``` **最佳实践**: - 使用`Schedulers.boundedElastic()`隔离所有阻塞调用。 - 推荐使用响应式数据库驱动(如R2DBC)替代JDBC。 ### 六、过滤器执行顺序控制 过滤器的执行顺序由`Order`值决定,数值越小优先级越高。 **执行顺序规则**: ```mermaid graph TB A[GlobalFilter] --> B[Order值越小越优先] C[GatewayFilter] --> D[YAML声明顺序] ``` **典型执行序列**: | **阶段** | **过滤器类型** | **Order范围** | **示例** | |------------|---------------------|--------------|------------------------| | 预处理 | 全局认证过滤器 | $-100 \sim 0$ | JWT校验 | | 核心处理 | 路由级过滤器 | $1 \sim 50$ | 限流/重试/路径改写 | | 后处理 | 响应修改过滤器 | $51 \sim 100$ | 添加响应头/日志记录 | ### 七、动态路由更新实现 通过`RouteDefinitionWriter`动态更新路由,并发布`RefreshRoutesEvent`事件。 **代码示例**: ```java @Autowired private RouteDefinitionWriter routeDefinitionWriter; // 添加路由 public void addRoute(RouteDefinition definition) { routeDefinitionWriter.save(Mono.just(definition)).subscribe(); publishEvent(new RefreshRoutesEvent(this)); } // 删除路由 public void deleteRoute(String routeId) { routeDefinitionWriter.delete(Mono.just(routeId)).subscribe(); publishEvent(new RefreshRoutesEvent(this)); } ``` **基于Nacos的配置**: ```yaml spring: cloud: gateway: discovery: locator: enabled: true # 开启服务发现动态路由 ``` ### 八、Sentinel熔断规则热更新 #### 1. 配置中心方案(Nacos) ```java @NacosConfigListener(dataId = "sentinel-rules", groupId = "GATEWAY") public void updateRules(String config) { List<FlowRule> rules = JSON.parseArray(config, FlowRule.class); FlowRuleManager.loadRules(rules); // 动态更新 } ``` #### 2. Sentinel Dashboard推送 ```mermaid sequenceDiagram Dashboard->>Gateway: 推送新规则 Gateway->>Gateway: 更新内存规则 Gateway->>Dashboard: 返回生效结果 ``` ### 九、响应式异常处理机制 #### 1. 全局异常处理器 ```java @Bean @Order(-1) // 最高优先级 public ErrorWebExceptionHandler exceptionHandler() { return (exchange, ex) -> { if (ex instanceof BlockRequestException) { exchange.getResponse().setStatusCode(429); return writeResponse(exchange, "触发送控"); } return Mono.error(ex); }; } ``` #### 2. 过滤器链异常捕获 ```java public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { return chain.filter(exchange) .onErrorResume(ex -> { metrics.recordError(ex); // 记录异常指标 exchange.getResponse().setStatusCode(500); return exchange.getResponse().writeWith( Mono.just(exchange.getResponse().bufferFactory().wrap("服务异常".getBytes())) ); }); } ``` ### 十、基于用户角色的动态路由配置 通过自定义路由谓词工厂实现: ```java public class RoleRoutePredicateFactory extends AbstractRoutePredicateFactory<RoleRoutePredicateFactory.Config> { public RoleRoutePredicateFactory() { super(Config.class); } @Override public Predicate<ServerWebExchange> apply(Config config) { return exchange -> { String role = exchange.getRequest().getHeaders().getFirst("X-Role"); return config.getRoles().contains(role); }; } public static class Config { private Set<String> roles; // getters/setters } } ``` **配置示例**: ```yaml spring: cloud: gateway: routes: - id: admin_route uri: lb://admin-service predicates: - Role=admin # 只允许admin角色访问 ``` ### 十一、Sentinel动态调整熔断阈值 通过Sentinel Dashboard动态调整: 1. 在Dashboard中选择目标网关服务。 2. 修改熔断规则参数(如慢调用比例阈值)。 3. 点击“推送”按钮实时生效。 **代码监听规则变化**: ```java @SentinelDataSource public class DynamicRuleManager { @SentinelProperty("sentinel.rules.circuit-breaker") public void updateCircuitBreakerRule(String ruleJson) { List<CircuitBreakerRule> rules = JSON.parseArray(ruleJson, CircuitBreakerRule.class); GatewayRuleManager.loadRules(rules); } } ``` ### 十二、响应式编程中无阻塞集成OAuth2 使用`WebClient`实现无阻塞OAuth2认证: ```java public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { return WebClient.create("http://auth-service") .post() .uri("/oauth/check_token") .header("Authorization", exchange.getRequest().getHeaders().getFirst("Authorization")) .retrieve() .bodyToMono(AuthResult.class) .flatMap(authResult -> { if (authResult.isValid()) { return chain.filter(exchange); } else { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } }); } ``` **关键点**: - 使用响应式`WebClient`替代阻塞式RestTemplate。 - 全程无阻塞,符合响应式编程规范。 ### 总结 Spring Cloud Gateway的核心优势在于响应式架构、动态能力、扩展性云原生集成。生产环境建议: - 使用`spring-cloud-gateway-actuator`监控路由状态。 - 通过Micrometer暴露指标到Prometheus。 - 结合Grafana实现网关流量可视化。 §§相关问题§§ 1. 如何通过Spring Cloud Gateway实现WebSocket的负载均衡? 2. 网关层如何实现请求Body的签名验证而不阻塞响应式线程? 3. Spring Cloud Gateway如何集成Consul作为服务发现? 4. 如何实现网关的灰度发布功能? 5. 在Gateway中如何配置跨域(CORS)策略?</think>### Spring Cloud Gateway 高级功能实现详解 #### 一、请求限流与熔断机制实现 **1. 限流机制(令牌桶算法)** ```mermaid graph LR A[请求] --> B{令牌桶状态} B -->|令牌充足| C[扣除令牌并转发] B -->|令牌不足| D[返回429错误] ``` - **实现原理**: - 使用`RequestRateLimiter`过滤器 + `RedisRateLimiter` - 令牌桶参数:`replenishRate`(生成速率), `burstCapacity`(桶容量) - **配置示例**: ```yaml filters: - name: RequestRateLimiter args: key-resolver: "#{@userKeyResolver}" redis-rate-limiter: replenishRate: 50 burstCapacity: 200 ``` **2. 熔断机制(断路器模式)** ```mermaid stateDiagram-v2 [*] --> Closed Closed --> Open: 失败阈值触发 Open --> HalfOpen: 等待时间结束 HalfOpen --> Closed: 测试请求成功 HalfOpen --> Open: 测试请求失败 ``` - **熔断状态转换**: - Closed → Open:失败超过阈值 - Open → Half-Open:等待时间结束 - Half-Open → Closed:测试请求成功[^1] - **原生实现**: ```yaml filters: - name: CircuitBreaker args: name: serviceA fallbackUri: forward:/fallback ``` #### 二、自定义全局认证过滤器 ```java @Component @Order(-100) public class JwtAuthFilter implements GlobalFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 1. 提取JWT String token = extractToken(exchange.getRequest()); // 2. 异步验证(非阻塞) return Mono.fromCallable(() -> validateToken(token)) .subscribeOn(Schedulers.boundedElastic()) .flatMap(valid -> { if(!valid) { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } // 3. 添加用户上下文 return chain.filter(addUserContext(exchange, token)); }); } } ``` **关键点**: - `@Order(-100)`确保最先执行 - 使用`Schedulers.boundedElastic()`隔离阻塞操作 - 响应式修改请求头:`exchange.mutate().request()` #### 三、Gateway vs Zuul 对比 | **维度** | **Spring Cloud Gateway** | **Zuul 1.x** | |------------------|--------------------------------|----------------------------| | 架构模型 | 响应式(WebFlux) | 阻塞式(Servlet) | | 吞吐量 | 10k+ QPS | 2k-3k QPS | | 资源消耗 | 固定线程池 | 每请求一线程 | | 限流熔断 | 原生支持+Sentinel集成 | 依赖Hystrix[^2] | | 动态路由 | 内置事件机制 | 需手动刷新 | | WebSocket | 原生支持 | 不支持 | | 监控指标 | Micrometer集成 | 需自定义 | > **结论**:Gateway 在性能、扩展性、云原生支持方面全面领先,适合高并发场景[^1][^2] #### 四、结合 Sentinel 实现熔断降级 **1. 集成步骤**: ```mermaid graph TD A[添加依赖] --> B[配置规则源] B --> C[定义熔断回调] C --> D[监控仪表盘] ``` - **依赖配置**: ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> </dependency> ``` **2. 熔断规则类型**: | **策略** | **参数** | **适用场景** | |----------------|------------------------|---------------------| | 慢调用比例 | maxRt, slowRatio | 响应时间敏感服务 | | 异常比例 | exceptionRatio | 服务稳定性波动 | | 异常数 | exceptionCount | 低频关键服务 | **3. 动态阈值调整**: ```java // 根据响应时间自动调整阈值 @SentinelProperty("rtThreshold") public void updateThreshold(double avgRt) { List<FlowRule> rules = ruleManager.getRules(); rules.forEach(rule -> rule.setMaxQueueingTimeMs((int)(avgRt * 1.5)) ); FlowRuleManager.loadRules(rules); } ``` #### 五、响应式阻塞调用处理 **解决方案**: ```java public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 阻塞操作转移到弹性线程池 return Mono.fromCallable(() -> blockingDatabaseCall()) .subscribeOn(Schedulers.boundedElastic()) .flatMap(result -> { exchange.getAttributes().put("data", result); return chain.filter(exchange); }); } ``` **最佳实践**: 1. 使用`Schedulers.boundedElastic()`隔离所有阻塞调用 2. 禁止在过滤器链中使用`Thread.sleep()` 3. 数据库访问推荐R2DBC等响应式驱动 4. 复杂计算使用`Mono.fromSupplier()` #### 六、过滤器执行顺序控制 **优先级规则**: ```mermaid graph TB A[GlobalFilter] -->|Order值| B[数值越小越优先] C[GatewayFilter] -->|配置位置| D[从上到下执行] ``` **典型顺序**: 1. 认证过滤:Order = -100 2. 限流熔断:Order = -50 3. 路径重写:Order = 0 4. 响应修改:Order = 100 **自定义顺序**: ```java @Bean @Order(-1) // 全局异常处理最高优先级 public ErrorWebExceptionHandler customExceptionHandler() { // ... } ``` #### 七、动态路由更新实现 **事件驱动更新**: ```java @Autowired private RouteDefinitionWriter writer; public void updateRoute(String serviceId, String newPath) { // 1. 创建新路由定义 RouteDefinition definition = new RouteDefinition(); definition.setId(serviceId); definition.setUri("lb://" + serviceId); definition.setPredicates(List.of( new PredicateDefinition("Path=" + newPath)) ); // 2. 保存并刷新 writer.save(Mono.just(definition)).subscribe(); publisher.publishEvent(new RefreshRoutesEvent(this)); } ``` **基于Nacos的配置**: ```yaml spring: cloud: gateway: discovery: locator: enabled: true url-expression: "'lb://' + serviceId + '/api/' + serviceId" ``` #### 八、Sentinel熔断规则热更新 **1. Nacos配置中心方案**: ```java @NacosConfigListener(dataId = "sentinel-rules", groupId = "GATEWAY") public void updateRules(String config) { List<FlowRule> rules = JSON.parseArray(config, FlowRule.class); FlowRuleManager.loadRules(rules); // 秒级生效 } ``` **2. Sentinel Dashboard推送**: ```mermaid sequenceDiagram Dashboard->> Gateway: POST /setRules Gateway->> Gateway: 更新内存规则 Gateway->> Dashboard: 200 OK ``` **3. 文件监听方案**: ```java FileWatchService.register("rules.json", path -> { String json = Files.readString(path); GatewayRuleManager.loadRules(JSON.parseObject(json)); }); ``` #### 九、响应式异常处理 **1. 全局异常处理器**: ```java @Bean @Order(-1) // 最高优先级 public ErrorWebExceptionHandler exceptionHandler() { return (exchange, ex) -> { if (ex instanceof RateLimitException) { exchange.getResponse().setStatusCode(429); return writeResponse(exchange, "请求过快"); } return Mono.error(ex); }; } ``` **2. 过滤器链异常捕获**: ```java public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { return chain.filter(exchange) .onErrorResume(ex -> { metrics.recordError(ex); // 记录指标 return Mono.fromRunnable(() -> exchange.getResponse().setStatusCode(500) ).then(Mono.empty()); }); } ``` #### 十、基于角色的动态路由 ```java public RouteLocator dynamicRoutes(RouteLocatorBuilder builder) { return builder.routes() .route("admin_route", r -> r.path("/admin/**") .filters(f -> f.filter(roleFilter("ADMIN")) .uri("lb://admin-service") ) .route("user_route", r -> r.path("/user/**") .filters(f -> f.filter(roleFilter("USER")) .uri("lb://user-service") ).build(); } private GatewayFilter roleFilter(String role) { return (exchange, chain) -> { String userRole = getRoleFromToken(exchange); if(!role.equals(userRole)) { exchange.getResponse().setStatusCode(403); return exchange.getResponse().setComplete(); } return chain.filter(exchange); }; } ``` #### 十一、OAuth2无阻塞集成 ```java @Bean public SecurityWebFilterChain oauth2Filter(ServerHttpSecurity http) { return http .authorizeExchange(exchanges -> exchanges.pathMatchers("/login").permitAll() .anyExchange().authenticated() ) .oauth2ResourceServer(server -> server.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtConverter())) ) .build(); } // 响应式JWT转换器 private Converter<Jwt, Mono<AbstractAuthenticationToken>> jwtConverter() { return jwt -> Mono.just(new JwtAuthenticationToken(jwt, getAuthorities(jwt))); } ``` ### 总结 Spring Cloud Gateway的核心优势: 1. **响应式架构**:基于WebFlux实现高并发($QPS \geq 10k$) 2. **动态扩展**:支持路由/熔断规则热更新 3. **云原生集成**:无缝对接Sentinel/Nacos等组件 4. **灵活过滤链**:支持全局/路由级过滤器编排 > **生产建议**: > - 使用`spring-cloud-gateway-actuator`监控路由状态 > - 通过Micrometer暴露$QPS$/$RT$/$ErrorRate$指标 > - 结合Grafana实现网关流量可视化 > - 关键操作使用`Schedulers.boundedElastic()`隔离阻塞调用
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值