SpringCloud Alibaba Sentinel是当前最为流行一种熔断降级框架,简单易用的方式可以快速帮助我们实现服务的限流和降级,保证服务的稳定性。
Sentinel 是什么?
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
不可否认的是,Sentinel功能丰富,并且在提供好用的dashboard提供配置,但是Sentinel在集成到项目中时需要引入多个依赖,并且需要阅读相关文档,以及dashboard中的相关配置才可以接入到项目中,这个过程还是较为复杂的。
如果我们的项目并不需要这么多的功能,只是需要当某个方法或者某个功能发生异常的时候可以实现降级,并不是直接中断程序,该业务功能不是主流程,那么我们为了实现这样一个小功能的时候,将Sentinel
集成到项目中的过程显然是较为复杂的,那么这个时候,就需要我们实现一个简答的功能降级的通用方式,下面就一起看看一个简易版的Sentinel
的实现
当然,实现这个功能,只需要一个try-catch就可以搞定个,但是我们需要的是try-catch吗?No! 我们需要的是优雅~ 我想你也不想看到满屏的try-catch吧,如果哪天这个方法无需降级的时候,再去一行一行删代码吗?
代码已收录到Github: https://github.com/chenliang15405/common-study/tree/main/resource-degrade
定义注解
第一步,定义一个通用注解,这个注解可以帮助我们无侵入性的实现功能降级,并且提供丰富的属性,让注解的通用性和灵活性更强
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
@Inherited
public @interface DegradeResource {
// 降级的方法名称
String fallback();
// 降级的类名称,可选
Class<?>[] fallbackClass() default {
};
// 指定降级异常,可选
Class<? extends Throwable>[] exceptionHandle() default {
};
}
-
fallback:降价方法的名称,需要指定降级方法的名称,才可以在发生异常时调用降级方法,必选参数。
降级方法须知:
- 必须为public
- 方法返回类型、方法参数必须和原始方法保持一致,最后一个参数允许多一个
Throwable
,用来接收发生的异常
-
fallbackClass:指定降级方法所在的class,可选参数,如果不指定则默认降级方法在当前class中
-
exceptionHandle:指定异常处理,当发生指定的异常时才选择进行降级,可选参数,数组类型,可以接收多个异常类型
定义切面处理器
当资源降级注解定义之后,我们就需要一个切面处理器,对定义的降级注解做切面处理,当调用的方法上有@DegradeResource
注解时,会通过切面处理器进行处理
@Aspect
public class DegradeResourceAspect {
@Around("@annotation(degradeResource)")
public Object doAround(ProceedingJoinPoint pjp, DegradeResource degradeResource) throws Throwable {
try {
return pjp.proceed();
} catch(Throwable e){
// need to trace exception list
Class<? extends Throwable>[] exceptions = degradeResource.exceptionHandle();
if(exceptions.length > 0) {
List