完整 Sentinel 示例与解释
1. 项目结构
sentinel-demo/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ ├── config/ # Sentinel 规则配置
│ │ │ │ ├── FlowRuleConfig.java
│ │ │ │ └── DegradeRuleConfig.java
│ │ │ ├── controller/ # 控制器
│ │ │ │ └── DemoController.java
│ │ │ └── Application.java # 启动类
│ │ └── resources/
│ │ └── application.yml
2. 完整代码示例
2.1 启动类 (Application.java)
java
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
2.2 流量控制规则配置 (FlowRuleConfig.java)
java
@Configuration
public class FlowRuleConfig implements CommandLineRunner {
@Override
public void run(String... args) {
List<FlowRule> rules = new ArrayList<>();
// 为DemoController#testFlow定义QPS限流规则
FlowRule rule1 = new FlowRule();
rule1.setResource("DemoController#testFlow");
rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule1.setCount(2); // QPS阈值=2
rules.add(rule1);
// 为DemoController#testParamFlow定义参数限流规则
FlowRule rule2 = new FlowRule();
rule2.setResource("DemoController#testParamFlow");
rule2.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule2.setCount(1);
rule2.setParamIdx(0); // 对第一个参数限流
rules.add(rule2);
FlowRuleManager.loadRules(rules);
}
}
2.3 熔断规则配置 (DegradeRuleConfig.java)
java
@Configuration
public class DegradeRuleConfig implements CommandLineRunner {
@Override
public void run(String... args) {
List<DegradeRule> rules = new ArrayList<>();
// 为DemoController#testDegrade定义熔断规则
DegradeRule rule = new DegradeRule();
rule.setResource("DemoController#testDegrade");
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
rule.setCount(5); // 异常数阈值=5
rule.setTimeWindow(10); // 熔断时间窗口=10秒
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}
}
2.4 控制器 (DemoController.java)
java
@RestController
@RequestMapping("/demo")
public class DemoController {
private static final Random random = new Random();
// ========== 流量控制示例 ==========
/**
* 基础流量控制
*/
@GetMapping("/flow")
@SentinelResource(value = "DemoController#testFlow",
blockHandler = "handleFlowBlock")
public String testFlow() {
return "Flow test passed";
}
/**
* 参数限流示例
*/
@GetMapping("/paramFlow")
@SentinelResource(value = "DemoController#testParamFlow",
blockHandler = "handleParamFlowBlock")
public String testParamFlow(@RequestParam("userId") Long userId) {
return "Param flow test passed for user " + userId;
}
// ========== 熔断降级示例 ==========
/**
* 熔断降级测试
*/
@GetMapping("/degrade")
@SentinelResource(value = "DemoController#testDegrade",
blockHandler = "handleDegradeBlock",
fallback = "handleDegradeFallback")
public String testDegrade() {
// 模拟60%的异常率
if (random.nextInt(10) < 6) {
throw new RuntimeException("Random error occurred");
}
return "Degrade test passed";
}
// ========== 异常处理方法 ==========
// 流量控制Block处理
public String handleFlowBlock(BlockException ex) {
return "Flow control triggered: " + ex.getClass().getSimpleName();
}
// 参数限流Block处理
public String handleParamFlowBlock(Long userId, BlockException ex) {
return "User " + userId + " is blocked by param flow rule";
}
// 熔断Block处理
public String handleDegradeBlock(BlockException ex) {
return "Circuit breaker opened: " + ex.getClass().getSimpleName();
}
// 熔断Fallback处理
public String handleDegradeFallback(Throwable t) {
return "Fallback for: " + t.getMessage();
}
}
3. 详细解释
3.1 资源定义
资源通过 @SentinelResource
注解定义:
java
@SentinelResource(
value = "DemoController#testFlow", // 资源名称
blockHandler = "handleFlowBlock" // BlockException处理方法
)
3.2 规则类型与配置
流量控制规则 (FlowRule)
java
FlowRule rule = new FlowRule();
rule.setResource("DemoController#testFlow"); // 资源名
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 限流类型(QPS/线程数)
rule.setCount(2); // 阈值
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 控制策略
熔断降级规则 (DegradeRule)
java
DegradeRule rule = new DegradeRule();
rule.setResource("DemoController#testDegrade");
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT); // 熔断策略
rule.setCount(5); // 阈值(异常数/异常比例/RT)
rule.setTimeWindow(10); // 熔断时长(秒)
3.3 异常处理机制
BlockHandler
- 处理 Sentinel 规则触发的 BlockException
- 方法签名要求:
- 返回类型与原方法相同
- 参数列表需要包含原方法参数+BlockException
- 必须位于同一个类中
示例:
java
public String handleFlowBlock(BlockException ex) {
// 处理逻辑
}
Fallback
- 处理业务逻辑抛出的非BlockException
- 方法签名要求:
- 返回类型与原方法相同
- 参数列表需要包含原方法参数+Throwable
- 可选,不强制要求在同一类中
示例:
java
public String handleDegradeFallback(Throwable t) {
// 处理逻辑
}
4. 测试场景
4.1 流量控制测试
- 快速刷新
/demo/flow
接口 - 当QPS超过2时,会看到
handleFlowBlock
返回的消息
4.2 参数限流测试
- 用不同userId频繁请求
/demo/paramFlow?userId=xxx
- 对同一userId的QPS超过1时会被限流
4.3 熔断测试
- 连续请求
/demo/degrade
接口 - 当异常数达到5次后触发熔断
- 熔断期间请求会直接进入
handleDegradeBlock
- 10秒后会自动恢复
5. 最佳实践建议
-
资源命名规范
- 使用
类名#方法名
格式 - 保持全局唯一性
- 使用
-
规则配置
- 生产环境建议通过控制台动态配置
- 开发环境可以使用代码初始化
-
异常处理
- 区分业务异常和流控异常
- 提供友好的降级响应
-
监控整合
- 集成Sentinel控制台实时监控
- 配置告警规则
-
性能考虑
- 避免在BlockHandler/Fallback中执行耗时操作
- 保持处理逻辑简单高效
这个完整示例展示了Sentinel的核心功能,包括资源定义、规则配置和异常处理机制,可以作为实际项目中的参考实现。