SpringCloudAlibabaSentinel限流

wen java案例 2

Spring Cloud Alibaba Sentinel 限流详解

核心概念

Sentinel 是阿里巴巴开源的流量控制组件,主要提供:

SpringCloudAlibabaSentinel限流

  • 流量控制:控制请求速率
  • 熔断降级:防止系统雪崩
  • 系统负载保护:保护系统稳定

快速集成

1 Maven 依赖

<!-- Sentinel 核心依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- Sentinel Dashboard 监控(可选) -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
</dependency>

2 配置文件

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080  # Sentinel Dashboard 地址
      eager: true  # 开启饥饿加载
      filter:
        enabled: true  # 启用过滤器

限流规则配置

1 基本限流规则

@RestController
public class DemoController {
    // 方法级别的限流
    @GetMapping("/demo/limit")
    @SentinelResource(value = "demo_limit", 
                      blockHandler = "blockHandlerMethod",
                      fallback = "fallbackMethod")
    public String limitMethod() {
        return "正常访问";
    }
    // 限流后的处理方法
    public String blockHandlerMethod(BlockException ex) {
        return "请求过于频繁,请稍后重试";
    }
    // 降级处理方法
    public String fallbackMethod(Throwable throwable) {
        return "服务异常,请稍后重试";
    }
}

2 编程式配置限流规则

@Component
public class SentinelRuleConfig {
    @PostConstruct
    public void initFlowRules() {
        // 1. 定义限流规则
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("demo_limit");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 按QPS限流
        rule.setCount(10); // 每秒最多10个请求
        rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 直接拒绝
        // 2. 注册规则
        FlowRuleManager.loadRules(Collections.singletonList(rule));
    }
}

限流模式详解

1 基于QPS限流

// 每秒请求数限制
FlowRule qpsRule = new FlowRule();
qpsRule.setResource("qps_limit");
qpsRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
qpsRule.setCount(100);

2 基于线程数限流

// 并发线程数限制
FlowRule threadRule = new FlowRule();
threadRule.setResource("thread_limit");
threadRule.setGrade(RuleConstant.FLOW_GRADE_THREAD);
threadRule.setCount(20);

3 冷启动限流(预热)

// 系统预热,逐步增加QPS
FlowRule warmUpRule = new FlowRule();
warmUpRule.setResource("warmup_limit");
warmUpRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
warmUpRule.setCount(100);
warmUpRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
warmUpRule.setWarmUpPeriodSec(10); // 预热时间10秒

4 匀速排队限流

// 严格控制请求通过间隔时间
FlowRule queueRule = new FlowRule();
queueRule.setResource("queue_limit");
queueRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
queueRule.setCount(100);
queueRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
queueRule.setMaxQueueingTimeMs(500); // 最大排队时间500ms

高级特性

1 热点参数限流

@GetMapping("/hot/param")
@SentinelResource(value = "hot_param_limit")
public String hotParamLimit(@RequestParam("id") Integer id) {
    return "热点参数限流测试";
}
// 配置热点规则
@PostConstruct
public void initHotParamRules() {
    // 创建热点规则
    ParamFlowRule rule = new ParamFlowRule("hot_param_limit")
        .setParamIdx(0) // 第0个参数
        .setCount(5) // 阈值
        .setDurationInSec(1); // 统计时间窗口
    // 特定参数值单独配置
    ParamFlowItem item = new ParamFlowItem()
        .setObject(String.valueOf(1)) // 参数值
        .setClassType(int.class.getName())
        .setCount(10); // 特殊阈值
    rule.setParamFlowItemList(Collections.singletonList(item));
    // 加载规则
    ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
}

2 系统规则限流

// 系统负载保护规则
SystemRule systemRule = new SystemRule();
systemRule.setHighestSystemLoad(10.0); // 系统负载阈值
systemRule.setAvgRt(100); // 平均响应时间
systemRule.setMaxThread(1000); // 最大线程数
systemRule.setQps(100); // QPS阈值
SystemRuleManager.loadRules(Collections.singletonList(systemRule));

熔断降级配置

1 降级规则

// 熔断降级规则
DegradeRule degradeRule = new DegradeRule();
degradeRule.setResource("degrade_demo");
degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_RT); // 响应时间降级
degradeRule.setCount(500); // 响应时间阈值500ms
degradeRule.setTimeWindow(10); // 熔断时长10秒
// 异常比例降级
DegradeRule exceptionRatioRule = new DegradeRule();
exceptionRatioRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
exceptionRatioRule.setCount(0.5); // 异常比例50%
exceptionRatioRule.setMinRequestAmount(5); // 最小请求数
// 异常数降级
DegradeRule exceptionCountRule = new DegradeRule();
exceptionCountRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
exceptionCountRule.setCount(100); // 异常数100
DegradeRuleManager.loadRules(Arrays.asList(degradeRule));

自定义限流处理器

@Component
public class CustomBlockExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest request, 
                      HttpServletResponse response, 
                      BlockException e) throws Exception {
        // 自定义限流响应
        response.setStatus(429);
        response.setContentType("application/json;charset=utf-8");
        Map<String, Object> result = new HashMap<>();
        result.put("code", 429);
        result.put("message", "请求过于频繁,请稍后重试");
        result.put("resource", e.getRule().getResource());
        response.getWriter().write(JSON.toJSONString(result));
    }
}

Sentinel Dashboard 配置

1 下载与启动

# 下载Sentinel Dashboard
wget https://github.com/alibaba/Sentinel/releases/download/1.8.2/sentinel-dashboard-1.8.2.jar
# 启动Dashboard
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 \
     -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.2.jar

2 客户端连接配置

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080  # Dashboard地址
        port: 8719  # 客户端端口
      datasource:
        ds1:
          nacos:
            serverAddr: localhost:8848
            dataId: ${spring.application.name}-sentinel
            groupId: DEFAULT_GROUP
            ruleType: flow

最佳实践

1 限流粒度选择

// 1. 资源级限流 - 对特定方法或接口限流
@SentinelResource(value = "user_service_query")
// 2. 上下文级限流 - 对调用来源限流
ContextUtil.enter("user-service", "app-A");
// 3. 链路级限流 - 对调用链路限流
// 需要在配置中开启链路收敛

2 限流与熔断组合使用

@SentinelResource(
    value = "complex_service",
    blockHandler = "blockHandler",      // 限流处理
    fallback = "fallbackHandler",       // 异常降级
    exceptionsToIgnore = {IllegalArgumentException.class} // 忽略某些异常
)
public String complexMethod() {
    // 业务逻辑
}

监控与报警

@Component
public class SentinelMonitor {
    @EventListener
    public void handleBlockEvent(SentinelBlockEvent event) {
        // 限流事件监控
        log.warn("限流触发: resource={}, rule={}, count={}", 
                 event.getResourceName(), 
                 event.getRule(), 
                 event.getCount());
        // 发送告警
        sendAlert(event);
    }
    private void sendAlert(SentinelBlockEvent event) {
        // 集成告警系统(如钉钉、邮件等)
    }
}

注意事项

  1. 规则持久化:使用Nacos等配置中心持久化规则
  2. 性能影响:合理设置滑动窗口大小
  3. 异常处理:正确处理BlockException和Fallback
  4. 预热策略:新服务上线时使用冷启动模式
  5. 监控告警:设置合适的监控指标和告警阈值

通过合理使用Sentinel的限流功能,可以有效保护微服务系统的稳定性,防止雪崩效应,提高系统的可用性和可靠性。

抱歉,评论功能暂时关闭!