服务流控(Sentinel)

引入依赖

XML 复制代码
<!-- 必须的 -->
<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>

实现流控

编码实现

  • 限流实现
java 复制代码
    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);
    private static final String RESOURCE_NAME = "hello";

    @RequestMapping("/hello")
    public String hello() {
        Entry entry = null;
        // 务必保证finally会被执行
        try {
            // 资源名可使用任意有业务语义的字符串
            entry = SphU.entry(RESOURCE_NAME);
            // 被保护的业务逻辑
            // do something...
            String str = "hello world";
            logger.info("++++++++++++" + str);
            return str;
        } catch (BlockException e1) {
            // 资源访问阻止,被限流或被降级
            // 进行相应的处理操作
            logger.info("block!!!!!");
            return "被流控了!!!!";
        } catch (Exception e) {
            // 若需要配置降级规则。则需要通过这种方式记录业务异常
            Tracer.traceEntry(e, entry);
        } finally {
            if (entry != null) {
                entry.exit();
            }
        }
        return null;
    }
  • 注册流控规则
java 复制代码
    @PostConstruct
    private static void initFlowControlRules() { // 通常设置在服务提供方
        // 流控规则列表
        List<FlowRule> flowRuleList = new ArrayList<>();

        // 流控规则
        FlowRule helloFlowRule = new FlowRule();
        // 设置流控的资源名称
        helloFlowRule.setResource(RESOURCE_NAME);
        // 设置流控规则 QPS
        helloFlowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 设置流控的阈值
        // Set limit QPS to 20
        helloFlowRule.setCount(1);

        flowRuleList.add(helloFlowRule);
        
        FlowRuleManager.loadRules(flowRuleList);
   }
  • 效果呈现

注解实现

  • 引入依赖
XML 复制代码
<!--  @SentinelResource  -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-annotation-aspectj</artifactId>
    <version>1.8.0</version>
</dependency>
  • 增加切面
    • 启动类
java 复制代码
    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();
    }
    • 配置类
java 复制代码
/**
 * 1. 使用注解@SentinelResource
 * 2. 使用了 Spring AOP
 * 3. 通过配置的方式将 SentinelResourceAspect 注册为一个 Spring Bean
 */
@Configuration
public class AopConfiguration {

    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();
    }
}
  • 注解使用
java 复制代码
    /**
     * 使用注解 使用Sentinel
     *
     * @SentinelResource: 依赖:
     * <dependency>
     *      <groupId>com.alibaba.csp</groupId>
     *      <artifactId>sentinel-annotation-aspectj</artifactId>
     *      <version>1.8.0</version>
     * </dependency>
     * 1. value: 资源名称
     * 2. blockHandler 流控降低处理器 (默认和接口实现方法在同一个类中)
     * 3. blockHandlerClass 指定处理器类
     * 4. fallback  业务异常处理
     * 5. fallbackClass 指定异常处理器类
     * 6. blockHandler 和 fallback 同时配置, blockHandler 优先级高
     * 7. exceptionsToIgnore 排除不需要处理的异常 -> exceptionsToIgnore = {}
     */
    @RequestMapping("/user")
    @SentinelResource(value = USER_RESOURCE_NAME, blockHandler = "blockHandlerForGetUser",
//            fallback = "fallBackForGetUser",
            exceptionsToIgnore = {})
    public User getUser(String id) {
        // int i = 1 / 0;
        return new User(id, "Quentin");
    }

    /**
     * 注意:
     * 1. 必须是public, 若放在其他类中 blockHandlerClass 则必须为 public static
     * 2. 返回值 需和原接口方法的返回值保持一致 且 参数包含原方法的参数
     * 3. 额外增加  异常参数 BlockException
     *
     * @param id
     * @param be
     * @return
     */
    public User blockHandlerForGetUser(String id, BlockException be) {
        logger.info("++++++++注解流控");
        return new User(id, "被流控了!!!");
    }
  • 增加流控规则
java 复制代码
    @PostConstruct
    private static void initFlowControlRules() { // 通常设置在服务提供方
        // 流控规则列表
        List<FlowRule> flowRuleList = new ArrayList<>();


        // 流控规则
        FlowRule userFlowRule = new FlowRule();
        // 设置流控的资源名称
        userFlowRule.setResource(USER_RESOURCE_NAME);
        // 设置流控规则 QPS
        userFlowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 设置流控的阈值
        // Set limit QPS to 20
        userFlowRule.setCount(1);

        flowRuleList.add(userFlowRule);

        FlowRuleManager.loadRules(flowRuleList);
    }
  • 效果
相关推荐
路上阡陌7 分钟前
Java学习笔记(二十四)
java·笔记·学习
何中应17 分钟前
Spring Boot中选择性加载Bean的几种方式
java·spring boot·后端
苏苏大大19 分钟前
zookeeper
java·分布式·zookeeper·云原生
wclass-zhengge1 小时前
03垃圾回收篇(D3_垃圾收集器的选择及相关参数)
java·jvm
涛ing1 小时前
23. C语言 文件操作详解
java·linux·c语言·开发语言·c++·vscode·vim
5xidixi1 小时前
Java TCP协议(2)
java·tcp/ip
2013crazy1 小时前
Java 基于 SpringBoot+Vue 的校园兼职平台(附源码、部署、文档)
java·vue.js·spring boot·兼职平台·校园兼职·兼职发布平台
小高不明1 小时前
仿 RabbitMQ 的消息队列3(实战项目)
java·开发语言·spring·rabbitmq·mybatis
兩尛1 小时前
订单状态定时处理、来单提醒和客户催单(day10)
java·前端·数据库
web2u1 小时前
MySQL 中如何进行 SQL 调优?
java·数据库·后端·sql·mysql·缓存