Spring Cloud Alibaba学习笔记(6) - Sentinel使用总结

使用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;
            }
        };
    }
}
posted @ 2019-10-23 14:31  夜的那种黑丶  阅读(2012)  评论(0编辑  收藏  举报