在微服务架构盛行的今天,服务间的调用关系日益复杂,如何保障系统在高并发场景下的稳定性成为每个开发者必须面对的挑战。阿里巴巴开源的 Sentinel 正是为解决这一问题而生的流量治理组件,它能够有效防止服务雪崩、保障系统稳定性。本文将带你快速实现 Sentinel 在 Spring Boot 项目中的集成,让你在 5 分钟内掌握核心用法。
在开始集成前,请确保你的开发环境满足以下要求:
提示:可以通过
java -version和mvn -v命令验证环境版本
使用 Spring Initializr 快速创建项目:
或者直接使用 curl 命令创建:
bash复制curl https://start.spring.io/starter.zip -d dependencies=web \
-d type=maven-project -d language=java -d bootVersion=2.6.4 \
-d groupId=com.example -d artifactId=sentinel-demo -o sentinel-demo.zip
在 pom.xml 中添加 Spring Cloud Alibaba Sentinel 依赖:
xml复制<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.0.5.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Sentinel Starter -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 可选:Actuator 用于监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
在 application.yml 中添加 Sentinel 配置:
yaml复制server:
port: 8080
spring:
application:
name: sentinel-demo
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel Dashboard 地址
port: 8719 # 客户端监控端口
eager: true # 立即初始化
filter:
enabled: false # 关闭默认的 URL 限流
management:
endpoints:
web:
exposure:
include: "*"
编写一个简单的 REST 控制器:
java复制@RestController
public class DemoController {
@GetMapping("/hello")
@SentinelResource(value = "hello", blockHandler = "handleBlock")
public String hello(@RequestParam(required = false) String name) {
if ("error".equals(name)) {
throw new RuntimeException("模拟业务异常");
}
return "Hello, " + (name != null ? name : "World");
}
public String handleBlock(String name, BlockException ex) {
return "请求被限流,请稍后重试";
}
}
bash复制wget https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar
bash复制java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 \
-Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar
Sentinel 支持多种流量控制策略:
| 策略类型 | 说明 | 适用场景 |
|---|---|---|
| 直接限流 | 对资源直接限制 | 简单场景 |
| 关联限流 | 关联资源触发限流 | 优先级控制 |
| 链路限流 | 基于调用链路限流 | 入口流量控制 |
代码示例:配置关联限流
java复制@PostConstruct
public void initFlowRules() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("hello");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(1);
rule.setStrategy(RuleConstant.STRATEGY_RELATE);
rule.setRefResource("relatedResource");
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
| 策略类型 | 触发条件 | 特点 |
|---|---|---|
| 慢调用比例 | RT > 阈值且比例超过设定 | 适合接口性能波动 |
| 异常比例 | 异常比例超过阈值 | 适合业务异常场景 |
| 异常数 | 异常数超过阈值 | 适合低流量场景 |
java复制@PostConstruct
public void initDegradeRules() {
List<DegradeRule> rules = new ArrayList<>();
DegradeRule rule = new DegradeRule();
rule.setResource("hello");
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
rule.setCount(0.5); // 异常比例阈值50%
rule.setTimeWindow(10); // 熔断时间10秒
rule.setMinRequestAmount(5); // 最小请求数
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}
java复制@PostConstruct
public void initSystemRules() {
List<SystemRule> rules = new ArrayList<>();
SystemRule rule = new SystemRule();
rule.setHighestSystemLoad(4.0); // 最大系统负载
rule.setAvgRt(200); // 平均响应时间
rule.setMaxThread(50); // 最大线程数
rules.add(rule);
SystemRuleManager.loadRules(rules);
}
xml复制<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
yaml复制spring:
cloud:
sentinel:
datasource:
ds1:
nacos:
server-addr: localhost:8848
dataId: sentinel-demo-flow-rules
groupId: DEFAULT_GROUP
rule-type: flow
bash复制java -Dserver.port=8720 -Dproject.name=sentinel-token-server \
-jar sentinel-cluster-server-default.jar
yaml复制spring:
cloud:
sentinel:
transport:
client-ip: ${spring.cloud.client.ip-address}
cluster:
server:
host: localhost
port: 8720
xml复制<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-extension</artifactId>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
<version>0.12.0</version>
</dependency>
java复制@Bean
public SentinelPrometheusExporter sentinelExporter() {
return new SentinelPrometheusExporter();
}
检查项:
日志分析:
bash复制grep "Loading rules" application.log
grep "FlowRuleManager" application.log
yaml复制spring:
cloud:
sentinel:
metric:
fileSize: 52428800 # 增大指标文件大小
fileCount: 6 # 增加文件数量
log:
dir: /logs/sentinel # 指定日志目录
bash复制-Dcsp.sentinel.metric.file.singleSize=50 -Dcsp.sentinel.metric.file.totalCount=10
bash复制# 节点1
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=node1:8080,node2:8080
# 节点2
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=node1:8080,node2:8080
yaml复制spring:
cloud:
sentinel:
transport:
dashboard: node1:8080,node2:8080
java复制public class CustomSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
@Override
public void entry(Context context, ResourceWrapper resourceWrapper,
DefaultNode node, int count, boolean prioritized, Object... args) {
// 前置处理
System.out.println("Before flow control: " + resourceWrapper.getName());
// 触发下一个Slot
fireEntry(context, resourceWrapper, node, count, prioritized, args);
// 后置处理
System.out.println("After flow control: " + resourceWrapper.getName());
}
}
java复制@PostConstruct
public void initSlotChain() {
SlotChainBuilder builder = new DefaultSlotChainBuilder() {
@Override
public ProcessorSlotChain build() {
ProcessorSlotChain chain = super.build();
chain.addLast(new CustomSlot());
return chain;
}
};
SlotChainProvider.setSlotChainBuilder(builder);
}
java复制@GetMapping("/order/{id}")
@SentinelResource(value = "orderDetail",
blockHandler = "handleOrderBlock",
fallback = "handleOrderFallback")
public String getOrderDetail(@PathVariable String id,
@RequestParam String userId) {
// 业务逻辑
return "Order: " + id + " for user: " + userId;
}
// 热点参数规则
@PostConstruct
public void initParamFlowRules() {
ParamFlowRule rule = new ParamFlowRule("orderDetail")
.setParamIdx(1) // 对第二个参数(userId)限流
.setCount(5); // 阈值
ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
}
xml复制<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
java复制@PostConstruct
public void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
GatewayFlowRule rule = new GatewayFlowRule("order_service")
.setResourceMode(RuleConstant.GATEWAY_RESOURCE_MODE_ROUTE_ID)
.setCount(10)
.setIntervalSec(1);
rules.add(rule);
GatewayRuleManager.loadRules(rules);
}
| 组件 | 版本 | 配置 |
|---|---|---|
| Sentinel | 1.8.6 | 默认配置 |
| Spring Boot | 2.6.4 | 2C4G |
| JMeter | 5.4.1 | 1000并发 |
| 场景 | QPS | 平均RT | 错误率 |
|---|---|---|---|
| 无Sentinel | 12500 | 12ms | 0% |
| 基础限流 | 11800 | 15ms | 0.2% |
| 熔断降级 | 11600 | 18ms | 0.5% |
| 集群限流 | 10500 | 22ms | 1.2% |
bash复制# 推荐生产环境配置
-Xms2g -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 \
-XX:ParallelGCThreads=4 -XX:ConcGCThreads=2 \
-XX:+HeapDumpOnOutOfMemoryError
yaml复制spring:
cloud:
sentinel:
metric:
fileSize: 100000000 # 100MB
fileCount: 10
stat:
maxRt: 5000 # 最大响应时间统计
flow:
coldFactor: 3 # 冷启动因子
java复制// 商品维度限流示例
@GetMapping("/seckill/{itemId}")
@SentinelResource(value = "seckill_" + "#itemId",
blockHandler = "handleSeckillBlock")
public String seckill(@PathVariable String itemId) {
// 秒杀逻辑
return "Seckill success for item: " + itemId;
}
mermaid复制graph TD
A[网关] --> B[订单服务]
B --> C[库存服务]
B --> D[支付服务]
D --> E[银行接口]
保护策略:
xml复制<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-apollo</artifactId>
</dependency>
yaml复制spring:
cloud:
sentinel:
datasource:
ds1:
apollo:
namespaceName: application
flowRulesKey: sentinel.flow.rules
rule-type: flow
| Sentinel 版本 | Spring Cloud 版本 | Spring Boot 版本 |
|---|---|---|
| 1.8.6 | 2021.0.x | 2.6.x |
| 1.7.2 | 2020.0.x | 2.4.x |
| 1.6.3 | Hoxton | 2.3.x |
| 特性 | Sentinel | Hystrix | Resilience4j |
|---|---|---|---|
| 限流 | ✔️ | ✖️ | ✔️ |
| 熔断 | ✔️ | ✔️ | ✔️ |
| 系统保护 | ✔️ | ✖️ | ✖️ |
| 热点防护 | ✔️ | ✖️ | ✖️ |
| 集群流控 | ✔️ | ✖️ | ✖️ |
在实际项目中,我们发现以下配置组合效果最佳:
对于高并发场景,建议采用集群限流方案,并通过定期压力测试验证系统极限。我们团队在电商大促中通过这套方案成功将系统可用性从99.5%提升到99.99%。