1、引入依赖
链接: 点击查看依赖关系
父pom
<spring.cloud.version>Hoxton.SR12</spring.cloud.version>
<spring.cloud.alibaba.version>2.2.10-RC1</spring.cloud.alibaba.version>
Sentinel应用直接引用starter
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2、配置规则
限流着重于防止整体系统的入口流量过大,通过量化控制进入系统的请求速度。
降级是在系统负载过高或部分服务不可用时,采取的一种策略,它允许系统牺牲部分非核心功能或降低服务质量,以保证核心功能的正常运行。
// 限流配置规则
@PostConstruct
public static void initFlowRules() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("ordering"); //设置资源名称
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);//QPS 每秒的访问量
// Set limit QPS to 20.
rule.setCount(2);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
// 降级规则
//@PostConstruct
public void initFlowRules2() {
List<DegradeRule> rules = new ArrayList<>();
DegradeRule rule = new DegradeRule();
rule.setResource("ordering2"); //设置资源名称
rule.setGrade(DEGRADE_GRADE_EXCEPTION_RATIO);
// Set limit QPS to 20.
rule.setCount(0.5);
rule.setMinRequestAmount(10);
rule.setTimeWindow(10); // 10s 熔断时长10s
rule.setStatIntervalMs(10*1000); 10s 统计时长,统计的窗口(单位为 ms)
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}
3、为接口设置熔断与降级方法
blockHandler与fallback命名规则
- blockHandler方法应该接收与原始方法相同类型的参数,并且额外添加一个 BlockException 类型的参数,用于传递被 Sentinel 阻塞的具体原因。
命名规则是:
- 原方法名 + “_blockHandler”,比如在示例中,对应的 blockHandler 方法应该是 ordering_blockHandler(Integer id, BlockException ex)。
- 必须为static方法
- fallback方法应该接收与原始方法相同类型的参数
命名规则是:
- 原方法名 + “_fallback”,此方法应该接收与原始方法相同的参数列表,并返回与原始方法相同的返回类型。
- 必须为static方法
在示例中,对应的 fallback 方法应该是 ordering_fallback(Integer id)也可以ordering_fallback(Integer id, Throwable ex)
上述的 _blockHandler 和 _fallback 后面是可以带上任意的参数类型,但至少需要包含原始方法的所有参数类型,以及在 blockHandler 方法中加入 BlockException 参数。
验证限流
@RestController
@RequestMapping("/api/order")
@Slf4j
public class OrderController {
private static AtomicInteger count = new AtomicInteger(0);
@GetMapping
@SentinelResource(
value = "HelloWorld",
blockHandlerClass=OrderController.class,
blockHandler = "ordering_blockHandler")
public String ordering(Integer id) {
int i = count.incrementAndGet();
log.debug(id + "进来了 - > "+i);
return "下单成功";
}
public static String ordering_blockHandler(Integer id,BlockException ex){
int i = count.incrementAndGet();
log.debug("熔断了 -> "+i );
return "系统繁忙,请稍后重试";
}
@PostConstruct //初始化执行
private void initFlowRules(){
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("HelloWorld");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// Set limit QPS to 20.
rule.setCount(2);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}
验证降级
@RestController
@RequestMapping("/api/order2")
@Slf4j
public class Order2Controller {
@GetMapping
@SentinelResource(
value = "ordering2",
fallbackClass= Order2Controller.class,
fallback = "ordering_fallback")
public String ordering(Integer id) {
log.debug("进来了");
if (id == 4) {
throw new IllegalArgumentException("参数异常");
}
return "下单成功";
}
//? 什么时候触发? ordering_fallback 有什么要求吗?
public static String ordering_fallback(Integer id, Throwable ex) {
log.debug("降级");
return "降级了";
}
@PostConstruct //初始化执行 降级规则
private void initDegradeRule(){
List<DegradeRule> rules = new ArrayList<>();
DegradeRule rule = new DegradeRule("ordering2")
.setGrade(CircuitBreakerStrategy.ERROR_COUNT.getType())
// Max allowed response time 错误数量
.setCount(2)
// Retry timeout (in second) 熔断10s
.setTimeWindow(20)
.setMinRequestAmount(10) //最小请求数
.setStatIntervalMs(10*1000);//10s 统计时长,统计的窗口(单位为 ms)
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}
}
高级配置
- 流量控制规则 (FlowRule)
- 熔断降级规则 (DegradeRule)