前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >服务流控(Sentinel)

服务流控(Sentinel)

作者头像
问天丶天问
发布2024-02-17 09:25:37
720
发布2024-02-17 09:25:37
举报
文章被收录于专栏:问天丶天问问天丶天问

引入依赖

代码语言:javascript
复制
<!-- 必须的 -->
<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>

实现流控

编码实现

  • 限流实现
代码语言:javascript
复制
    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;
    }
  • 注册流控规则
代码语言:javascript
复制
    @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);
   }
  • 效果呈现

注解实现

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

    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();
    }
}
  • 注解使用
代码语言:javascript
复制
    /**
     * 使用注解 使用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, "被流控了!!!");
    }
  • 增加流控规则
代码语言:javascript
复制
    @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);
    }
  • 效果
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-02-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引入依赖
  • 实现流控
    • 编码实现
      • 注解实现
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档