第一步:启动sentinel控制台
下载控制台 jar 包并在本地启动:可以参见https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0#2-%E5%90%AF%E5%8A%A8%E6%8E%A7%E5%88%B6%E5%8F%B0
下载控制台jar路径:https://github.com/alibaba/Sentinel/releases
#启动控制台命令
java ‐jar sentinel‐dashboard‐1.8.0.jar
访问:http://localhost:8080,默认用户名密码: sentinel/sentinel
用户可以通过如下参数进行配置:
-Dsentinel.dashboard.auth.username=sentinel 用于指定控制台的登录用户名为 sentinel;
-Dsentinel.dashboard.auth.password=123456 用于指定控制台的登录密码为 123456;如果省略这两个参数,默认用户和密码均为
sentinel;
-Dserver.servlet.session.timeout=7200 用于指定 Spring Boot 服务端 session 的过期时间,如 7200 表示 7200 秒;60m 表示 60 分钟,
默认为 30 分钟;
java Dserver.port=8858 Dsentinel.dashboard.auth.username=xushu Dsentinel.dashboard.auth.password=123456 jar sentineldashboard1.8.0.jar
为了方便快捷启动可以在桌面创建.bat文件
java ‐Dserver.port=8858 ‐Dsentinel.dashboard.auth.username=xushu ‐Dsentinel.dashboard.auth.password=123456 ‐jar D:\server\sentinel‐dashboard‐1.8.0.jar
pause
第二步:创建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>
<!--整合控制台-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</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();
}
}
第四步:创建User
package com.example.sentinel.pojo;
import lombok.Data;
@Data
public class User {
private final String username;
}
第五步:创建配置文件application.yml
server:
port: 8020
第六步:创建控制类
package com.example.sentinel.controller;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
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.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
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 RESOURCE_NAME = "hello";
private static final String USER_RESOURCE_NAME = "user";
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("异常");
/* 慢调用比例
TimeUnit.SECONDS.sleep(1);
return new User("正常");*/
}
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);
}
@RequestMapping(value = "/hello")
public String hello() {
Entry entry = null;
try {
// 1.sentinel针对资源进行限制的
entry = SphU.entry(RESOURCE_NAME);
// 被保护的业务逻辑
String str = "hello world";
log.info("====="+str+"=====");
return str;
} catch (BlockException e1) {
// 资源访问阻止,被限流或被降级
//进行相应的处理操作
log.info("block!");
return "被流控了!";
} catch (Exception ex) {
// 若需要配置降级规则,需要通过这种方式记录业务异常
Tracer.traceEntry(ex, entry);
} finally {
if (entry != null) {
entry.exit();
}
}
return null;
}
/**
* 定义规则
*
* spring 的初始化方法
*/
@PostConstruct //相当于init-method
private static void initFlowRules(){
// 流控规则
List<FlowRule> rules = new ArrayList<>();
// 流控
FlowRule rule = new FlowRule();
// 为哪个资源进行流控
rule.setResource(RESOURCE_NAME);
// 设置流控规则 QPS表示每秒请求的次数
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 设置受保护的资源阈值
rule.setCount(1);
rules.add(rule);
// 通过@SentinelResource来定义资源并配置降级和流控的处理方法
FlowRule rule2 = new FlowRule();
//设置受保护的资源
rule2.setResource(USER_RESOURCE_NAME);
// 设置流控规则 QPS表示每秒请求的次数
rule2.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 设置受保护的资源阈值
rule2.setCount(1);
rules.add(rule2);
// 加载配置好的规则
FlowRuleManager.loadRules(rules);
}
/**
* @SentinelResource 改善接口中资源定义和被流控降级后的处理方法
* 怎么使用: 1.添加依赖<artifactId>sentinel-annotation-aspectj</artifactId>
* 2.配置bean——SentinelResourceAspect
* value 定义资源
* blockHandler 设置 流控降级后的处理方法(默认该方法必须声明在同一个类)
* 如果不想在同一个类中 blockHandlerClass 但是方法必须是static
* fallback 当接口出现了异常,就可以交给fallback指定的方法进行处理
* 如果不想在同一个类中 fallbackClass 但是方法必须是static
*
* blockHandler 如果和fallback同时指定了,则blockHandler优先级更高
* exceptionsToIgnore 排除哪些异常不处理
* @param id
* @return
*/
@RequestMapping("/user")
@SentinelResource(value = USER_RESOURCE_NAME, fallback = "fallbackHandleForGetUser",
/*exceptionsToIgnore = {ArithmeticException.class},*/
/*blockHandlerClass = User.class,*/ blockHandler = "blockHandlerForGetUser")
public User getUser(String id) {
int a=1/0;
return new User("xushu");
}
public User fallbackHandleForGetUser(String id,Throwable e) {
e.printStackTrace();
return new User("异常处理");
}
/**
* 注意:
* 1. 一定要public
* 2. 返回值一定要和源方法保证一致, 包含源方法的参数。
* 3. 可以在参数最后添加BlockException 可以区分是什么规则的处理方法
* @param id
* @param ex
* @return
*/
public User blockHandlerForGetUser(String id, BlockException ex) {
ex.printStackTrace();
return new User("流控!!");
}
}