有时候会搞乱的blockHandler与fallback

前言

之前老顾先容了sentinel的降级熔断文章,有些小伙伴在使用的过程中对blockhandler和fallback的使用会搞乱,这里老顾在这里在继续强化一下他们的区别以及使用。

两者区别

这里说明一下,老顾使用的是阿里巴巴的Sentinel限流降级框架,再之前老顾先容了Sentinel的限流、服务降级功能,但是只是限制后,返回不可控的结果肯定是不行的,大家还要保证调用者在调用那些被限制的服务时候,不管是不是被限制,都要让他们拿到一个合理的结果,而不是扔回去一个异常就完事了。

Sentinel提供了这样的功能,让大家可以另外定义一个方法来代替被限制或异常服务返回数据,这就是fallback和blockHandler

fallback:若本接口出现未知异常,则调用fallback指定的接口。

blockHandler:若本次访问被限流或服务降级,则调用blockHandler指定的接口。

fallback

此回调是针对接口出现异常了,就进入此fallback方法,大家看一下代码。

从代码看出,只要请求http://localhost:8081/test?id=2,接口就会报异常,继而会调用fallback中的方法,走到了testFallback方法中:

在testFallback增加一个Throwable 类型的参数,可以通过这个参数来实现捕获不同的异常,从而做对应的异常处理。

外置类

fallback 函数位置是有要求的,必须和原方法在同一个类中,但在实际需求中,大家需要放在其他类中。@SentinelResource提供了通过fallbackClass指定对应的类的Class对象,添加一个static函数,否则无法解析。

创建一个FallBackService类,并定义一个static 函数;请求同一个url,效果是一样的;此好处就是业务代码类比较简洁了。

fallback中还有一个defaultFallback

defaultFallback(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。

同时配置了fallback和defaultFallback,则只有 fallback 会生效。 defaultFallback 函数签名要求:返回值类型必须与原函数返回值类型一致; 方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。defaultFallback函数默认需要和原方法在同一个类中。若希翼使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必须为 static 函数,否则无法解析。

blockHandler

超出流量限制的部分是否会进入到blockHandler的方法,要注意是超出流量限制的请求调用,会进入blockHandler方法。

blockHandler是针对流量超出的请求,即针对的是BlockException异常;上面的请求都包含了fallback和blockHandler,那效果应该是什么呢?在Sentinel控制台配置一下流控规则。

如果请求url的参数id值为1,如果快速在1秒内请求多次,就超出了流控的设置,进入blockHandler方法。

如果请求url的参数id为2,因为会产生异常,所以第一次请求的时候 ,会进入fallback方法,后面快速请求多次就超出了流控,进入blockHandler方法。

i

总结

fallback是针对方法出现异常了,则会进入fallback方法。blockhandler是针对流控设置,超出规则,则会进入blockhandler方法。若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出BlockException时只会进入 blockHandler 处理逻辑。若未配置 blockHandler、fallback 和 defaultFallback,则被限流降级时会将 BlockException 直接抛出。

注:1.6.0 之前的版本 fallback 函数只针对降级异常(DegradeException)进行处理,不能针对业务异常进行处理。