流控是在服务提供方,降级是在消费方
第一步:创建maven项目,添加依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>sentinel_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--sentinel核心库-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
<!--如果要使用@SentinelResource-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.8.0</version>
</dependency>
</dependencies>
</project>
第二步:创建启动类
package com.example.sentinel;
import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class SentinelDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelDemoApplication.class,args);
}
// 注解支持的配置Bean
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
}
第三步:创建配置文件application.yml
server:
port: 8020
第四步:创建控制类
package com.example.sentinel.controller;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.example.sentinel.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
@RestController
@Slf4j
public class HelloController {
private static final String DEGRADE_RESOURCE_NAME = "degrade";
@RequestMapping("/degrade")
@SentinelResource(value = DEGRADE_RESOURCE_NAME,entryType = EntryType.IN,
blockHandler = "blockHandlerForFb")
public User degrade(String id) throws InterruptedException {
// 异常数
throw new RuntimeException("异常");
}
public User blockHandlerForFb(String id, BlockException ex) {
return new User("熔断降级");
}
@PostConstruct // 初始化
public void initDegradeRule(){
/*降级规则 异常*/
List<DegradeRule> degradeRules = new ArrayList<>();
DegradeRule degradeRule = new DegradeRule();
degradeRule.setResource(DEGRADE_RESOURCE_NAME);
// 设置规则策略: 异常数
degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
// 触发熔断异常数 : 2
degradeRule.setCount(2);
// 触发熔断最小请求数:2,就是说我必须要请求两次,在这两次里面有两次异常,我就会进行熔断
degradeRule.setMinRequestAmount(2);
// 统计时长:在多长时间段内请求的两次,触发了两次异常,触发熔断 单位:ms 1分钟
degradeRule.setStatIntervalMs(60*1000); // 时间太短不好测
// 一分钟内: 执行了2次 出现了2次异常 就会触发熔断
// 熔断持续时长 : 单位 秒
// 一旦触发了熔断, 再次请求对应的接口就会直接调用 降级方法。
// 10秒过了后——半开状态: 恢复接口请求调用, 如果第一次请求就异常, 再次熔断,不会根据设置的条件进行判定
degradeRule.setTimeWindow(10);
degradeRules.add(degradeRule);
DegradeRuleManager.loadRules(degradeRules);
}
}
第五步:启动测试
访问:http://localhost:8020/degrade,在1分钟内访问三次都是whitelabel Error Page界面 访问第一次:访问第二次:
访问第三次:
访问第四次:
等待10秒后,访问第五次:
访问第六次: