• Spring Cloud Alibaba学习笔记(6)


    使用Sentinel API

    Sentinel主要有三个核心Api:
    SphU:定义资源,让资源收到监控,保护资源
    SphU 包含了 try-catch 风格的 API。用这种方式,当资源发生了限流之后会抛出 BlockException。这个时候可以捕捉异常,进行限流之后的逻辑处理。

    String resourceName = "test_sentinel_api";
    Entry test_sentinel_api = null;
    // 定义一个Sentinel保护的资源
    try {
        test_sentinel_api = SphU.entry(resourceName);
        ...
    }
    // 若被保护的资源被限流或者降级
    catch (BlockException e) {
        e.printStackTrace();
        return "限流,或者降级了";
    }
    finally {
        if (test_sentinel_api != null) {
            test_sentinel_api.exit();
        }
    }
    

    PS:SphU.entry(xxx) 需要与 entry.exit() 方法成对出现,匹配调用,否则会导致调用链记录异常,抛出 ErrorEntryFreeException 异常。
    若 entry 的时候传入了热点参数,那么 exit 的时候也一定要带上对应的参数(exit(count, args)),否则可能会有统计错误。这个时候不能使用 try-with-resources 的方式。

    Tracer:异常统计

    // 针对来源
    String resourceName = "test_sentinel_api";
    Entry test_sentinel_api = null;
    // 定义一个Sentinel保护的资源
    try {
        test_sentinel_api = SphU.entry(resourceName);
        if (StringUtils.isBlank(a)) {
            throw new IllegalArgumentException("a不能为空");
        }
        return a;
    }
    // 若被保护的资源被限流或者降级
    catch (BlockException e) {
        e.printStackTrace();
        return "限流,或者降级了";
    }
    catch (IllegalArgumentException e2) {
        // 统计IllegalArgumentException
        Tracer.trace(e2);
        return "参数非法";
    }
    finally {
        if (test_sentinel_api != null) {
            test_sentinel_api.exit();
        }
    }
    

    通过 Tracer.trace(ex) 来统计异常信息时,由于 try-with-resources 语法中 catch 调用顺序的问题,会导致无法正确统计异常数,因此统计异常信息时也不能在 try-with-resources 的 catch 块中调用 Tracer.trace(ex)。

    ContextUtil:实现调用来源,实现调用

    // 针对来源
    String resourceName = "test_sentinel_api";
    ContextUtil.enter(resourceName, "study01");
    

    通过SentinelResource注解的方式

    Sentinel 支持通过 @SentinelResource 注解定义资源并配置 blockHandler 和 fallback 函数来进行限流之后的处理。

    @GetMapping("test_sentinel_resource")
    @SentinelResource(
            value = "test_sentinel_resource",
            blockHandler = "block",
            fallback = "fallback"
    )
    public String testSentinelResource(@RequestParam(required = false) String a) {
        if (StringUtils.isBlank(a)) {
            throw new IllegalArgumentException("a不能为空");
        }
        return a;
    }
    
    /**
     * 处理限流或者降级
     */
    public String block(String a, BlockException e) {
        log.warn("限流,或者降级了", e);
        return "限流,或者降级了 block";
    }
    
    public String fallback(String a, BlockException e) {
        return "限流,或者降级了 fallback";
    }
    

    @SentinelResource同样支持通过配置blockHandlerClass和fallbackClass配置类来进行限流后的处理

    RestTemplate整合Sentinel

    在初始化restTemplate的时候添加@SentinelRestTemplate注解就可以为RestTemplate整合Sentinel,代码如下:

    @Bean
    @LoadBalanced
    @SentinelRestTemplate
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    

    可以通过配置resttemplate. sentinel.enabled来开启或关闭整合,代码如下:

    resttemplate:
      sentinel:
        # 关闭、打开SentinelRestTemplate注解
        enabled: true
    

    Feign整合Sentinel

    在配置文件中添加如下配置便可以为Feign整合Sentinel:

    feign:
      # feign整合sentinel
      sentinel:
        enabled: true
    

    如果服务被限流或降级时,如果想要定制定制自己的处理逻辑,可以使用@FeignClient注解的fallback属性;如果定制处理逻辑的同时,还想拿到异常的具体细节,可以使用fallbackFactory属性,示例代码如下:

    @FeignClient(
            name = "study02",
            // 拿不到异常
            fallback = CommentFeignClientFallback.class,
            // 拿到异常
            fallbackFactory = CommentFeignClientFallbackFactory.class
    )
    public interface CommentFeignClient {
        @GetMapping("/find")
        DemoComment find();
    }
    
    
    @Component
    public class CommentFeignClientFallback implements CommentFeignClient {
    
        /**
         * 一旦被限流,就会进入这个方法
         * @return
         */
        @Override
        public DemoComment find() {
            DemoComment demoComment = new DemoComment();
            return demoComment;
        }
    }
    
    
    @Component
    @Slf4j
    public class CommentFeignClientFallbackFactory implements FallbackFactory<CommentFeignClient> {
        @Override
        public CommentFeignClient create(Throwable throwable) {
            return new CommentFeignClient() {
                @Override
                public DemoComment find() {
                    DemoComment demoComment = new DemoComment();
                    return demoComment;
                }
            };
        }
    }
    
  • 相关阅读:
    通过理解List和IList的区别,加深对接口回调的理解
    mysql学习笔记之mysqlparameter(摘)
    MSSQL表中字段更新后,视图中的字段不更新的解决办法
    如何设置firefox,使其可以支持剪贴板
    CSS图片下载器
    VS2008下.NET 单元测试工具 NUnit2.5 配置与集成方法
    discuz x1.5通过uchome注册后免激活补丁(自动激活)
    (转)七秘诀工作效率与薪水翻番
    TRIGGER OF ORACLE
    SQL LOADER 的使用
  • 原文地址:https://www.cnblogs.com/fx-blog/p/11725989.html
Copyright © 2020-2023  润新知