Spring Boot 整合 Sentinel 实现 QPS 限流
Sentinel 是阿里巴巴开源的分布式系统流量控制组件,它以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来保障微服务的稳定性。本文将详细介绍如何在 Spring Boot 项目中整合 Sentinel 并实现 QPS(每秒查询率) 限流功能。
一、Sentinel限流原理与必要性
在微服务架构中,服务限流是保障系统稳定性的重要手段。当系统面临突发流量时,无限制的请求可能导致:
资源耗尽:CPU、内存、数据库连接等资源被快速消耗
服务雪崩:一个服务的不可用导致级联故障
用户体验下降:响应时间变长甚至服务不可用
Sentinel 通过QPS 限流可以精确控制接口的访问频率,当请求量超过设定阈值时,会自动拦截额外请求,防止系统过载。
二、环境准备与依赖配置
1. 启动Sentinel控制台
首先需要下载并启动 Sentinel 控制台 (Dashboard):
wget https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -jar sentinel-dashboard-1.8.6.jar启动后访问 http://localhost:8080 ,默认账号密码为 sentinel/sentinel。
2. Spring Boot项目添加依赖
在 pom.xml 中添加以下依赖:
<!-- Sentinel核心依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2022.0.0.0</version>
</dependency>
<!-- Spring Boot Web支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Sentinel数据源(可选,用于规则持久化) -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>3. 配置Sentinel连接
在 application.yml 中配置 Sentinel 控制台地址:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel控制台地址
port: 8719 # 本地启动的HTTP Server端口
eager: true # 取消Sentinel控制台懒加载三、QPS限流实现方式
1. 注解方式实现限流
在 Controller 方法上使用@SentinelResource注解是最常用的限流方式:
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 FlowLimitController {
@GetMapping("/test")
@SentinelResource(value = "testResource", blockHandler = "handleBlock")
public String test() {
return "正常访问";
}
// 限流降级方法
public String handleBlock(BlockException ex) {
return "请求过于频繁,请稍后再试";
}
}代码说明:
@SentinelResource注解标记需要限流的方法value属性指定资源名称,需唯一blockHandler属性指定限流后的处理方法
2. URL自动限流
Sentinel 默认会将所有 HTTP 接口自动定义为资源,资源名为 URL 路径:
@RestController
public class AutoFlowController {
@GetMapping("/auto")
public String auto() {
return "自动限流资源";
}
}访问该接口后,在 Sentinel 控制台的 "簇点链路" 中可以看到/auto资源,可直接为其配置流控规则。
3. 编程方式实现限流
除了注解方式,还可以通过代码实现限流:
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
public class Service {
public void doSomething() throws BlockException {
Entry entry = null;
try {
entry = SphU.entry("doSomething");
// 业务逻辑
} catch (BlockException e) {
// 限流逻辑
} finally {
if (entry != null) {
entry.exit();
}
}
}
}这种方式更灵活,适合非 HTTP 接口的限流场景。
四、限流规则配置
1. 通过控制台配置规则
访问 Sentinel 控制台 (http://localhost:8080)
在左侧菜单点击 "簇点链路"
找到要限流的资源 ( 如
/test或testResource)点击 "流控" 按钮
设置限流规则:
资源名:接口路径或注解定义的资源名
阈值类型:QPS 或并发线程数
单机阈值:限流阈值
流控模式:直接、关联或链路
流控效果:快速失败、Warm Up 或排队等待
2. 通过代码配置规则
可以在应用启动时通过代码配置规则:
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.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class SentinelRuleConfig implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("testResource"); // 资源名
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 限流阈值类型(QPS)
rule.setCount(2); // 阈值
rule.setLimitApp("default"); // 默认来源
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}这种方式适合需要动态配置规则的场景。
五、规则持久化配置
默认情况下,Sentinel 的规则存储在内存中,应用重启后规则会丢失。可以通过 Nacos 等配置中心实现规则持久化:
spring:
cloud:
sentinel:
datasource:
ds1:
nacos:
server-addr: localhost:8848
data-id: ${spring.application.name}-flow-rules
group-id: SENTINEL_GROUP
rule-type: flow这样配置后,限流规则会保存在 Nacos 中,应用重启后规则不会丢失。
六、高级限流配置
1. 网关层限流
在 Spring Cloud Gateway 中集成 Sentinel 可以实现网关层限流:
添加网关依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>配置网关限流规则:
@PostConstruct
public void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("user_service_route")
.setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_ROUTE_ID)
.setCount(2)
.setIntervalSec(1));
GatewayRuleManager.loadRules(rules);
}这样可以对整个路由进行限流控制。
2. 熔断降级结合
Sentinel 不仅可以限流,还可以实现熔断降级:
@Service
public class UserService {
@SentinelResource(
value = "getUserById",
blockHandler = "handleBlock", // 限流/降级处理
fallback = "handleFallback" // 异常处理
)
public User getUserById(Long id) {
// 业务逻辑
}
// 限流/降级处理逻辑
public User handleBlock(Long id, BlockException ex) {
return new User(-1L, "blocked_user", "请求过于频繁,请稍后重试!");
}
// 异常处理逻辑
public User handleFallback(Long id, Throwable t) {
return new User(-1L, "fallback_user", "服务暂时不可用:" + t.getMessage());
}
}可以在 Sentinel 控制台配置熔断规则,如基于异常比例触发熔断。
七、测试与验证
1. 使用JMeter测试
创建 JMeter 测试计划,模拟高并发请求:
添加线程组,设置线程数为 100,循环 10 次
添加 HTTP 请求,指向限流接口
查看结果树和聚合报告,观察限流效果
2. 使用curl命令测试
# 连续发送请求测试限流
for i in {1..20}; do curl http://localhost:8080/test; echo; done正常情况会看到部分请求返回 "请求过于频繁,请稍后再试" 的限流提示。
八、总结
通过本文的介绍,我们了解了如何在 Spring Boot 项目中整合 Sentinel 实现 QPS 限流。主要步骤包括:
部署 Sentinel 控制台
添加 Sentinel 依赖
配置 Sentinel 连接
实现限流逻辑(注解 / 编程方式)
配置限流规则(控制台 / 代码方式)
可选的高级配置(持久化、网关限流、熔断降级)
Sentinel 提供了丰富的流量控制功能,可以帮助我们构建更加健壮的微服务系统。在实际项目中,可以根据业务需求选择合适的限流策略和配置方式。
通过合理的限流配置,我们可以有效防止系统过载,保障核心业务的稳定性,提升整体系统的可用性和用户体验。