Sentinel快速开始

Sentinel官网

Sentinel的使用分为两个部分:

  • 核心库:通过代码的手段对资源进行流控降级的处理。
  • 控制台:通过可视化控制台的方式对资源进行流控。

1. 核心库的方式:

  1. 引入依赖
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>1.8.6</version>
</dependency>
  1. 定义接口
@RestController
@Slf4j
public class HelloController {

    private static final String RESOURCE_NAME = "hello";
    
    // 进行 sentinel 流控
    @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 ex){
            // 资源访问阻止,被限流或被降级
            // 进行相应的处理操作
            log.info("block");
            return "被流控了!";
        }catch (Exception ex){
            // 如需要配置降级规则,需要通过这种方式记录业务异常
            Tracer.traceEntry(ex,entry);
        }finally {
            if(entry!=null){
                entry.exit();
            }
        }
        return null;
    }
    
    /**
     * 定义 流控规则
     */
    @PostConstruct
    private /*static*/ void initFlowRules(){
        log.info("流控规则的初始化.........");
        // 流控规则
        List<FlowRule> rules=new ArrayList<>();

        // 流控设置 1
        FlowRule rule=new FlowRule();
        // 设置受保护的资源
        rule.setResource(RESOURCE_NAME);
        // 设置流控规则 QPS
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 设置受保护的资源阈值
        // Set limit QPS to 20
        rule.setCount(1);
        rules.add(rule);

        // 流控设置 2
        FlowRule rule1=new FlowRule();
        // 设置受保护的资源
        rule1.setResource(USER_RESOURCE_NAME);
        // 设置流控规则 QPS
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 设置受保护的资源阈值
        // Set limit QPS to 20
        rule1.setCount(1);
        rules.add(rule1);

        FlowRuleManager.loadRules(rules);
    }
	
	/**
	 * 定义 降级规则
	 */
    @PostConstruct
    public void initDegradeRule(){
        log.info("熔断降级的初始化........");
        /* 降级规则 异常*/
        List<DegradeRule> degradeRules=new ArrayList<>();
        DegradeRule degradeRule=new DegradeRule();
        degradeRule.setResource(DEGRADE_RESOURCE_NAME);
        // 设置规则: 异常数
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
        degradeRule.setCount(2);
        // 触发熔断的最小请求数
        degradeRule.setMinRequestAmount(2);
        // 统计时长: 单位:ms
        degradeRule.setStatIntervalMs(5000);
        // 熔断持续时长
        // 一旦触发了熔断,再次请求对应的接口就会直接调用 降级方法
        // timeWindow时间结束,再次请求对应的接口,如果第一次请求就发生异常,直接熔断。
        degradeRule.setTimeWindow(10);

        degradeRules.add(degradeRule);
        DegradeRuleManager.loadRules(degradeRules);
    }
}

@SentinelResource 注解的使用

  • 引入依赖
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-annotation-aspectj</artifactId>
</dependency>

@SentinelResource 注解

  • value:资源名称,不能为空。
  • entryType:流量类型。EntryType.IN:入口流量,EntryType.OUT(默认):出口流量
  • blockHandler/blockHandlerClass:blockHandler 对应处理 BlockException 的函数名称,可选项。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
  • fallback/fallbackClass:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:
    • 返回值类型必须与原函数返回值类型一致;
    • 方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
    • fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析
  • exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

注意:特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。若未配置 blockHandler、fallback 和 defaultFallback,则被限流降级时会将 BlockException 直接抛出。

基于@SentinelResource 注解对资源的访问进行控制

定义 @Bean SentinelResourceAspect

@SpringBootApplication
public class _01DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(_01DemoApplication.class,args);
    }

    @Bean
    public SentinelResourceAspect sentinelResourceAspect(){
        return new SentinelResourceAspect();
    }
}

对接口进行流量控制

@RestController
@Slf4j
public class HelloController {

    private static final String USER_RESOURCE_NAME = "user";
    private static final String DEGRADE_RESOURCE_NAME = "degrade";

    @RequestMapping("/user")
    @SentinelResource(value = USER_RESOURCE_NAME,blockHandler = "blockHandlerForGerUser")
    public User getUser(String id){
        return new User("wuyu");
    }

    public User blockHandlerForGerUser(String id , BlockException ex){
        ex.printStackTrace();
        return new User("流控!!!");
    }

    @RequestMapping("/degrade")
    @SentinelResource(value = DEGRADE_RESOURCE_NAME,entryType = EntryType.IN,blockHandler = "blockHandlerForDegrade")
    public User degrade(){
        throw new RuntimeException();
    }

    public User blockHandlerForDegrade(BlockException blockException){
        blockException.printStackTrace();
        return new User("熔断了");
    }
    /**
     * 定义 流控规则
     */
    @PostConstruct
    private /*static*/ void initFlowRules(){
        log.info("流控规则的初始化.........");
        // 流控规则
        List<FlowRule> rules=new ArrayList<>();

        // 流控规则 1
        FlowRule rule=new FlowRule();
        // 设置受保护的资源
        rule.setResource(RESOURCE_NAME);
        // 设置流控规则 QPS
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 设置受保护的资源阈值
        // Set limit QPS to 20
        rule.setCount(1);
        rules.add(rule);

        // 流控规则 2
        FlowRule rule1=new FlowRule();
        // 设置受保护的资源
        rule1.setResource(USER_RESOURCE_NAME);
        // 设置流控规则 QPS
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 设置受保护的资源阈值
        // Set limit QPS to 20
        rule1.setCount(1);
        rules.add(rule1);

        FlowRuleManager.loadRules(rules);
    }
	
	/**
	 * 定义 熔断规则
	 */
    @PostConstruct
    public void initDegradeRule(){
        log.info("熔断降级的初始化........");
        /* 降级规则 异常*/
        List<DegradeRule> degradeRules=new ArrayList<>();
        DegradeRule degradeRule=new DegradeRule();
        degradeRule.setResource(DEGRADE_RESOURCE_NAME);
        // 设置规则: 异常数
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
        degradeRule.setCount(2);
        // 触发熔断的最小请求数
        degradeRule.setMinRequestAmount(2);
        // 统计时长: 单位:ms
        degradeRule.setStatIntervalMs(5000);
        // 熔断持续时长
        // 一旦触发了熔断,再次请求对应的接口就会直接调用 降级方法
        // timeWindow时间结束,再次请求对应的接口,如果第一次请求就发生异常,直接熔断。
        degradeRule.setTimeWindow(10);

        degradeRules.add(degradeRule);
        DegradeRuleManager.loadRules(degradeRules);
    }
}

2. 控制台的方式(基于spring-cloud-alibaba):

  1. 准备sentinel控制台:
    下载sentinel的jar包
    为了方便sentinel的启动可以通过.bat文件去启动jar包:

server.port: 设置控制台的端口
sentinel.dashboard.auth.username:设置登陆的用户名
sentinel.dashboard.auth.password:设置密码

创建一个.bat文件,加入下面脚本,注意修改自己的配置(写在一行,不要换行):

java -Dserver.port=1111 -Dsentinel.dashboard.auth.username=wuyu -Dsentinel.dashboard.auth.password=123456 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar pause

  1. 引入依赖
 <dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
 </dependency>
  1. 配置yml文件
server:
  port: 8011
spring:
  application:
    name: order-service
  cloud:
    sentinel:
      transport:
        dashboard: 127.0.0.1:1111
  1. 对流控异常进行统一处理(这里的Result,和Response是封装的工具类)
@Component
@Slf4j
public class MyBlockExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
        log.info("BlockExceptionHandler BlockException================"+e.getRule());
        Result result=null;
        if(e instanceof FlowException){
            result=Result.fail("被流控了");
        }else if(e instanceof ParamFlowException){
            result=Result.fail("参数流控了");
        }else if(e instanceof DegradeException){
            result=Result.fail("服务降级了");
        }else if(e instanceof AuthorityException){
            result=Result.fail("授权规则不通过");
        }else if(e instanceof SystemBlockException){
            result=Result.fail("触发系统保护规则");
        }
        Response.write(httpServletResponse,result);
    }
}

接口信息

@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController {

    @RequestMapping("/add")
//    @SentinelResource(value = "add",blockHandler = "blockHandlerForAdd")
    public String add(){
        log.info(Thread.currentThread()+"--正在下单....");
        return "下单成功";
    }

    @RequestMapping("/get")
    public String get(){
        log.info(Thread.currentThread()+"--正在查询");
        return "查询成功";
    }
}

通过控制台进行配置流控规则,就可以直接对资源的访问进行限制,如果被流控了,会触发BlockException异常,我们实现的BlockExceptionHandler接口,会对这类异常进行统一处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值