Spring集成Sentinel限流示例

前言:在高并发系统中,突发流量可能导致服务雪崩。Sentinel作为阿里开源的轻量级限流组件,能有效保障系统稳定性。

本文将介绍如何在Spring Boot中快速集成Sentinel,通过注解方式实现接口限流,并利用控制台实时监控流量。无论你是应对秒杀场景,还是提升服务韧性,Sentinel都是值得掌握的利器。

让我们开始Sentinel的实战之旅!

1.添加Maven依赖

<!-- Sentinel Starter -->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
	<version>2021.0.5.0</version>
</dependency>

2.配置Sentinel

spring:
  application:
    name: sentinel-demo
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080 # Sentinel控制台地址
        port: 8719 # 本地启动的http服务端口,用于与Sentinel控制台通信
      eager: true # 是否立即加载Sentinel控制台
      filter:
        enabled: false # 关闭Sentinel的默认过滤器,我们将使用注解方式
server:
  port: 3389

3.创建Controller

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    // 接口A - QPS限流为2
    @GetMapping("/api/a")
    @SentinelResource(value = "apiA", blockHandler = "handleApiABlock")
    public String apiA() {
        return "This is API A response";
    }

    // 接口A的限流处理方法
    public String handleApiABlock(BlockException ex) {
        return "API A is blocked by Sentinel. Too many requests!";
    }

    // 接口B - QPS限流为5
    @GetMapping("/api/b")
    @SentinelResource(value = "apiB", blockHandler = "handleApiBBlock")
    public String apiB() {
        return "This is API B response";
    }

    // 接口B的限流处理方法
    public String handleApiBBlock(BlockException ex) {
        return "API B is blocked by Sentinel. Too many requests!";
    }
}

4.初始化限流规则

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

@Configuration
public class SentinelConfig {

    @PostConstruct
    public void initRules() {
        List<FlowRule> rules = new ArrayList<>();
        
        // 接口A的限流规则 - QPS=2
        FlowRule ruleA = new FlowRule();
        ruleA.setResource("apiA");
        ruleA.setGrade(RuleConstant.FLOW_GRADE_QPS);
        ruleA.setCount(2); // 每秒最多2次请求
        rules.add(ruleA);
        
        // 接口B的限流规则 - QPS=5
        FlowRule ruleB = new FlowRule();
        ruleB.setResource("apiB");
        ruleB.setGrade(RuleConstant.FLOW_GRADE_QPS);
        ruleB.setCount(5); // 每秒最多5次请求
        rules.add(ruleB);
        
        FlowRuleManager.loadRules(rules);
    }
}

5.测试

  1. 启动应用

  2. 访问 http://localhost:8080/api/a 和 http://localhost:8080/api/b

  3. 快速刷新页面,当超过限流阈值时会看到限流提示信息(如下图)

6.使用Sentinel控制台

  1. 下载Sentinel控制台:https://github.com/alibaba/Sentinel/releases

  2. 启动控制台:java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar

  3. 访问 http://localhost:8080 (默认用户名/密码: sentinel/sentinel)

  4. 在控制台中可以看到实时监控数据,并可以动态修改限流规则

7.注意事项

  1. @SentinelResource 注解的 blockHandler 方法必须与原方法在同一个类中

  2. blockHandler 方法的参数列表必须包含 BlockException 参数

  3. 生产环境中建议将规则配置在Nacos等配置中心,实现规则持久化

  4. 可以通过 @SentinelResource 的 fallback 属性配置降级逻辑

8.源码地址

https://github.com/xiaodonglicn/SentinelAccess