服务流控(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);
    }
  • 效果
相关推荐
【D'accumulation】15 分钟前
典型的MVC设计模式:使用JSP和JavaBean相结合的方式来动态生成网页内容典型的MVC设计模式
java·设计模式·mvc
试行29 分钟前
Android实现自定义下拉列表绑定数据
android·java
茜茜西西CeCe35 分钟前
移动技术开发:简单计算器界面
java·gitee·安卓·android-studio·移动技术开发·原生安卓开发
救救孩子把40 分钟前
Java基础之IO流
java·开发语言
小菜yh41 分钟前
关于Redis
java·数据库·spring boot·redis·spring·缓存
宇卿.1 小时前
Java键盘输入语句
java·开发语言
浅念同学1 小时前
算法.图论-并查集上
java·算法·图论
立志成为coding大牛的菜鸟.1 小时前
力扣1143-最长公共子序列(Java详细题解)
java·算法·leetcode
鱼跃鹰飞1 小时前
Leetcode面试经典150题-130.被围绕的区域
java·算法·leetcode·面试·职场和发展·深度优先
爱上语文2 小时前
Springboot的三层架构
java·开发语言·spring boot·后端·spring