Spring Cloud Gateway 与 Sentinel 限流熔断实战

构建高可用微服务网关层,掌握 Spring Cloud Gateway 路由断言、过滤器链与 Sentinel 流量控制、熔断降级的企业级实践

微服务网关是流量的统一入口,承担路由转发、负载均衡、认证鉴权、限流熔断等核心职责。Spring Cloud Gateway 作为 Spring 官方推荐的网关实现,配合阿里巴巴 Sentinel 的流量治理能力,可构建企业级的服务保护体系。

一、Spring Cloud Gateway 核心架构

1.1 请求处理流程

Client Request
     │
     ▼
┌──────────────────────────────────────┐
│  Predicate(路由断言)                 │  ← 匹配路径、Header、时间等
│  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─   │
│  Pre Filter(前置过滤器)              │  ← 认证、日志、灰度
│  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─   │
│  │ Proxy Request to Backend          │
│  ▼                                   │
│  Post Filter(后置过滤器)             │  ← 响应处理、埋点
└──────────────────────────────────────┘

1.2 路由与断言配置

spring:
  cloud:
    gateway:
      routes:
        # 订单服务路由
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/order/**
            - Method=GET,POST
            - Header=X-Api-Version, v[12]   # Header 正则匹配
          filters:
            - StripPrefix=2                  # 去掉 /api/order 前缀
            - AddRequestHeader=X-Request-From, Gateway
            - RequestRateLimiter=...         # 限流
            - CircuitBreaker=...             # 熔断

        # 支付服务路由(带重试)
        - id: payment-service
          uri: lb://payment-service
          predicates:
            - Path=/api/pay/**
          filters:
            - StripPrefix=2
            - Retry=3                        # 失败重试 3 次
            - SetStatus=200                  # 统一返回 200

1.3 自定义过滤器

@Component
public class AuthGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthGatewayFilterFactory.Config> {
    
    @Autowired
    private JwtTokenProvider tokenProvider;
    
    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            String token = request.getHeaders().getFirst("Authorization");
            
            if (!tokenProvider.validate(token)) {
                ServerHttpResponse response = exchange.getResponse();
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
            
            // 透传用户信息到下游服务
            ServerHttpRequest mutated = request.mutate()
                .header("X-User-Id", tokenProvider.getUserId(token))
                .header("X-User-Role", tokenProvider.getRole(token))
                .build();
            
            return chain.filter(exchange.mutate().request(mutated).build());
        };
    }
    
    public static class Config {
        // 配置参数
    }
}

二、Sentinel 流量控制

2.1 核心概念

概念说明
资源被保护的方法、接口或代码块
规则流量控制、熔断降级、系统保护、热点参数
Slot Chain处理链:NodeSelector → ClusterBuilder → Log → Statistic → System → Authority → Flow → Degrade

2.2 流控规则

@RestController
@RequestMapping("/api")
public class OrderController {
    
    @GetMapping("/{id}")
    @SentinelResource(
        value = "getOrderById",
        blockHandler = "getOrderBlockHandler",
        fallback = "getOrderFallback"
    )
    public Order getOrder(@PathVariable Long id) {
        return orderService.findById(id);
    }
    
    // 限流/降级时的响应
    public Order getOrderBlockHandler(Long id, BlockException ex) {
        log.warn("订单查询被限流: {}", id);
        throw new RateLimitException("系统繁忙,请稍后重试");
    }
    
    // 业务异常时的降级
    public Order getOrderFallback(Long id, Throwable ex) {
        log.error("订单查询异常: {}", id, ex);
        return Order.empty(id);  // 返回降级数据
    }
}

2.3 规则动态配置

@Configuration
public class SentinelConfig {
    
    @PostConstruct
    public void initRules() {
        List<FlowRule> rules = new ArrayList<>();
        
        // QPS 限流:每秒最多 1000 次
        FlowRule qpsRule = new FlowRule("getOrderById")
            .setGrade(RuleConstant.FLOW_GRADE_QPS)
            .setCount(1000)
            .setStrategy(RuleConstant.STRATEGY_DIRECT)
            .setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)
            .setWarmUpPeriodSec(10);  // 预热 10 秒
        
        // 线程数限流:最多 50 并发
        FlowRule threadRule = new FlowRule("createOrder")
            .setGrade(RuleConstant.FLOW_GRADE_THREAD)
            .setCount(50);
        
        rules.add(qpsRule);
        rules.add(threadRule);
        FlowRuleManager.loadRules(rules);
    }
}

2.4 熔断降级规则

@PostConstruct
public void initDegradeRules() {
    List<DegradeRule> rules = new ArrayList<>();
    
    // 慢调用比例熔断
    DegradeRule slowRule = new DegradeRule("getOrderById")
        .setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType())
        .setCount(500)                    // RT 超过 500ms 视为慢调用
        .setTimeWindow(30)                // 熔断时长 30 秒
        .setSlowRatioThreshold(0.5)       // 慢调用比例超过 50%
        .setMinRequestAmount(10)          // 最小请求数 10
        .setStatIntervalMs(1000);         // 统计时长 1 秒
    
    // 异常比例熔断
    DegradeRule errorRule = new DegradeRule("createOrder")
        .setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType())
        .setCount(0.5)                    // 异常比例超过 50%
        .setTimeWindow(60)                // 熔断时长 60 秒
        .setMinRequestAmount(5)
        .setStatIntervalMs(1000);
    
    rules.add(slowRule);
    rules.add(errorRule);
    DegradeRuleManager.loadRules(rules);
}

三、Gateway 集成 Sentinel

3.1 网关流控

spring:
  cloud:
    gateway:
      routes:
        - id: order-route
          uri: lb://order-service
          predicates:
            - Path=/order/**
          filters:
            - name: SentinelGatewayFilter
              args:
                flowConfig:
                  resource-mode: 0          # 0: route ID 模式, 1: 自定义 API 分组
@Configuration
public class GatewaySentinelConfig {
    
    @PostConstruct
    public void init() {
        // 自定义 API 分组
        Set<ApiDefinition> definitions = new HashSet<>();
        ApiDefinition api = new ApiDefinition("order_api")
            .setPredicateItems(new HashSet<>() {{
                add(new ApiPathPredicateItem()
                    .setPattern("/order/**")
                    .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
            }});
        definitions.add(api);
        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
        
        // 网关流控规则
        Set<GatewayFlowRule> rules = new HashSet<>();
        rules.add(new GatewayFlowRule("order_api")
            .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
            .setCount(100)                    // QPS 100
            .setIntervalSec(1)
            .setBurst(20)                     // 突发流量 20
            .setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP));
        GatewayRuleManager.loadRules(rules);
    }
}

3.2 自定义限流响应

@Configuration
public class SentinelConfig {
    
    @PostConstruct
    public void init() {
        BlockExceptionHandler handler = (exchange, ex) -> {
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
            response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
            
            String body = JsonUtils.toJson(Map.of(
                "code", 429,
                "message", "当前访问人数过多,请稍后重试",
                "timestamp", System.currentTimeMillis()
            ));
            
            return response.writeWith(Mono.just(
                response.bufferFactory().wrap(body.getBytes())
            ));
        };
        GatewayCallbackManager.setBlockHandler(handler);
    }
}

四、高级限流策略

4.1 热点参数限流

@GetMapping("/hot")
@SentinelResource(
    value = "hotParam",
    blockHandler = "hotBlock"
)
public String hotParam(
    @RequestParam("userId") @SentinelParam(idx = 0) String userId,
    @RequestParam("skuId") @SentinelParam(idx = 1) String skuId
) {
    return process(userId, skuId);
}

@PostConstruct
public void initParamRules() {
    ParamFlowRule rule = new ParamFlowRule("hotParam")
        .setParamIdx(0)                       // 对第 0 个参数限流
        .setCount(100);                       // 默认 QPS 100
    
    // 特定用户 ID 单独设置阈值
    rule.setParamFlowItemList(List.of(
        new ParamFlowItem().setObject("VIP_USER_001").setCount(1000),
        new ParamFlowItem().setObject("BLACK_USER_001").setCount(0)  // 黑名单
    ));
    
    ParamFlowRuleManager.loadRules(List.of(rule));
}

4.2 系统自适应保护

@PostConstruct
public void initSystemRules() {
    List<SystemRule> rules = new ArrayList<>();
    
    rules.add(new SystemRule()
        .setHighestSystemLoad(10.0)           // 系统负载阈值
        .setAvgRt(500)                        // 平均 RT 阈值(ms)
        .setMaxThread(500)                    // 最大线程数
        .setQps(5000)                         // 全局 QPS
        .setHighestCpuUsage(0.7));            // CPU 使用率阈值
    
    SystemRuleManager.loadRules(rules);
}

五、监控与管理

5.1 Sentinel 控制台

# 启动 Sentinel Dashboard
java -Dserver.port=8080 \
     -Dcsp.sentinel.dashboard.server=localhost:8080 \
     -Dproject.name=sentinel-dashboard \
     -jar sentinel-dashboard.jar

5.2 指标上报

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719                    # 应用与控制台通信端口
      metric:
        charset: UTF-8
        fileSingleSize: 52428800      # 单个日志文件 50MB
        fileTotalCount: 6             # 保留 6 个文件
      datasource:
        flow:                         # 规则持久化到 Nacos
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}-flow-rules
            ruleType: flow

六、最佳实践

6.1 网关限流设计

流量入口层级:
    ┌─────────────────┐
    │   CDN / WAF     │  ← 第一层:防 DDoS、CC 攻击
    └────────┬────────┘
             ▼
    ┌─────────────────┐
    │  Gateway Sentinel │  ← 第二层:API 级限流、鉴权
    │  - 路由级 QPS     │
    │  - API 分组       │
    └────────┬────────┘
             ▼
    ┌─────────────────┐
    │  Service Sentinel │  ← 第三层:方法级限流、熔断
    │  - 热点参数       │
    │  - 慢调用熔断     │
    └─────────────────┘

6.2 熔断策略参数推荐

场景策略阈值熔断时长恢复策略
核心接口慢调用比例RT > 500ms30s半开试探
非核心接口异常比例错误率 > 50%60s半开试探
第三方调用异常数5 次/分钟120s半开试探

七、总结

组件职责关键能力
Spring Cloud Gateway统一入口路由、转发、过滤、负载均衡
Sentinel流量治理限流、熔断、热点、系统保护
整合优势全链路防护网关层 + 服务层双重保护

网关层 Sentinal 适合粗粒度限流(API 级别),服务层 Sentinel 适合细粒度控制(方法级别)。两者结合,构建完整的微服务流量防护体系。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「java-enterprise」更多文章

  1. 限流算法深度解析:令牌桶、漏桶与滑动窗口计数
  2. Java 代码质量:SonarQube、Checkstyle 与 SpotBugs 工程化实践
  3. Spring IoC 容器与依赖注入原理深度剖析