美文网首页
sentinel注解配置

sentinel注解配置

作者: 板栗炖牛肉 | 来源:发表于2021-08-10 10:00 被阅读0次

前言

  • 当前在spring boot 是不spring cloud上运行sentinel
  • 环境: spring boot 2.4.9 , sentinel 2021.1
  • 主要配置运行,只讲限流方式,且不讲解控制台操作(不需要使用),不配置nacos持久化
  • 只用注解式
  • 官方

解决方案

  • 引入sentinel
        <!-- sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            <version>2021.1</version>
        </dependency>
  • 还是贴出所有pom
     <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            <version>2021.1</version>
        </dependency>
  • 提一下跑时出现的一个坑,引入了一个以下包,导致跑时出现异常无法启动
       <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>
  • 修改为,hibernate-validator包含validation-api,但是sentinel缺少其他配置所以无法启动
   <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>7.0.1.Final</version>
        </dependency>
  • 还是贴以下外部配置,外部jar包控制台
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:30010
        heartbeat-interval-ms: 1000
      enabled: true

  • 创建一个CustomBlockHandler外部控制异常捕获(只针对控制台操作),new RestBean<>(RestCodeType.BUSY_BUSINESS)这些变更为自己的异常代码
@Configuration
public class CustomBlockHandler implements BlockExceptionHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        String msg = null;
        if (e instanceof FlowException) {
            //限流
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_BUSINESS));
        } else if (e instanceof DegradeException) {
            //BUSY_TOO_MANY_PEOPLE
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_UNREACHABLE));
        } else if (e instanceof ParamFlowException) {
            //热点参数限流
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_BUSINESS));
        } else if (e instanceof SystemBlockException) {
            //系统规则
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_UNREACHABLE));
        } else if (e instanceof AuthorityException) {
            //授权规则
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_UNREACHABLE));
        }
        response.setStatus(400);
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Type", "application/json;charset=utf-8");
        response.getWriter().write(msg);
        response.getWriter().close();
    }

}

  • 创建一个持久化配置CustomSentinelConfig
public abstract class CustomSentinelConfig {

    @PostConstruct
    private void config() {
        List<FlowRule> flowRules = new ArrayList<>();

        /**
         * 添加限流方式
         * 10次拒绝访问
         */
        FlowRule flowRule1 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule1.setResource("限流-10");
        //限流阈值
        flowRule1.setCount(10);
        //调用关系限流策略:直接、链路、关联
        flowRule1.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流
        flowRule1.setControlBehavior(0);

        /**
         * 添加限流方式
         * 5次等待排队
         */
        FlowRule flowRule2 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule2.setResource("限流等待-5");
        //限流阈值
        flowRule2.setCount(5);
        //调用关系限流策略:直接、链路、关联
        flowRule2.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule2.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流
        flowRule2.setControlBehavior(2);
        //超时时间设置
        flowRule2.setMaxQueueingTimeMs(60000);

        /**
         * 添加限流方式
         * 2次拒绝访问
         */
        FlowRule flowRule3 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule3.setResource("限流-2");
        //限流阈值
        flowRule3.setCount(2);
        //调用关系限流策略:直接、链路、关联
        flowRule3.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule3.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流
        flowRule3.setControlBehavior(0);

        /**
         * 添加限流方式
         * 10次等待排队
         */
        FlowRule flowRule4 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule4.setResource("限流等待-10");
        //限流阈值
        flowRule4.setCount(10);
        //调用关系限流策略:直接、链路、关联
        flowRule4.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule4.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流
        flowRule4.setControlBehavior(2);
        //超时时间设置
        flowRule4.setMaxQueueingTimeMs(60000);

        /**
         * 添加限流方式
         * 线程最多五个
         */
        FlowRule flowRule5 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule5.setResource("线程-5");
        //限流阈值
        flowRule5.setCount(5);
        //调用关系限流策略:直接、链路、关联
        flowRule5.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule5.setGrade(RuleConstant.FLOW_GRADE_THREAD);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流
        flowRule5.setControlBehavior(0);
        //超时时间设置
        flowRule5.setMaxQueueingTimeMs(60000);


        /**
         * 组装限流
         */
        flowRules.add(flowRule1);
        flowRules.add(flowRule2);
        flowRules.add(flowRule3);
        flowRules.add(flowRule4);
        flowRules.add(flowRule5);
        FlowRuleManager.loadRules(currentLimitRules(flowRules));
    }

    /**
     * 限流规则配置
     *
     * @param rules
     * @return
     */
    protected abstract List<FlowRule> currentLimitRules(List<FlowRule> rules);

}
  • 以上是一个abstract类,继承类为SentinelConfig,这里看个人配置,我这里是为了方便配置
@Configuration
public class SentinelConfig extends CustomSentinelConfig {

    @Override
    protected List<FlowRule> currentLimitRules(List<FlowRule> rules) {
        return rules;
    }
}
  • 以下开始有点特殊,创建一个测试类

@RestController
public class SentinelController {
    @SentinelResource(value = "线程-5")
    @RequestMapping(value = "/ss")
    public String ss(String id, HttpServletResponse response) throws Exception {
        try {
            Thread.sleep(5000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "访问结果";
    }
}
  • 按照官方写法应为
@RestController
public class SentinelController {

    @SentinelResource(value = "线程-5",blockHandler = "ssHandler")
    @RequestMapping(value = "/ss")
    public String ss(String id, HttpServletResponse response) throws Exception {
        try {
            Thread.sleep(5000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "访问结果";
    }
    
    public String ssHandler(String id, HttpServletResponse response, BlockException b) throws Exception {
        return "错误代码";
    }

}
  • 不好意思,个人代码风格有点接受不了,很恶心感觉,emmm没别的意思,注意:CustomBlockHandler只针对外部配置,内部的不生效,不要再问为什么

  • 那就把ssHandler剔掉,blockHandler = "ssHandler"也踢掉,变成了一个注释搞的

    @SentinelResource(value = "线程-5")
  • 当然还要加入其它配置,业务入口必须加入throws Exception,否则会报其它异常
  public String ss(String id, HttpServletResponse response) throws Exception {
  • 全局捕获异常加入,我这里使用文本比对的,你们可以替换为类比较
...
 else if (msg.contains("FlowException")) {
            logger.error("全局异常捕获,限流开始", "FlowException");
            restBean.setType(RestCodeType.BUSY_BUSINESS, e);
        } 
...
  • 基本就配置完成了,来一次测试,我这里是限制同时五个线程


    image.png
image.png image.png image.png image.png image.png
  • 比对限流响应时间


    全局异常捕获
自定义Handler捕获 正常结果时间
  • 置于响应时间为什么那么久,我这边请求软件高并发的问题。但是同样,全局捕获肯定比自定义要慢这是当然的,全局捕获还有其他判断。。这是当然的,以下去除休眠网页访问时间。
网页访问时间
image.png
  • 其它限流方式就不贴出了

结尾

  • 有不对的地方请您指正
  • 一定要加throws Exception不然就是另一个异常

相关文章

网友评论

      本文标题:sentinel注解配置

      本文链接:https://www.haomeiwen.com/subject/ftdxbltx.html