SpringCloud Alibaba全集文章目录:
零、手把手教你搭建SpringCloudAlibaba项目
一、手把手教你搭建SpringCloud Alibaba之生产者与消费者
二、手把手教你搭建SpringCloudAlibaba之Nacos服务注册中心
三、手把手教你搭建SpringCloudAlibaba之Nacos服务配置中心
四、手把手教你搭建SpringCloudAlibaba之Nacos服务集群配置
五、手把手教你搭建SpringCloudAlibaba之Nacos服务持久化配置
六、手把手教你搭建SpringCloudAlibaba之Sentinel实现流量实时监控
七、手把手教你搭建SpringCloudAlibaba之Sentinel实现流量控制
八、手把手教你搭建SpringCloudAlibaba之Sentinel服务降级
九、手把手教你搭建SpringCloudAlibaba之Sentinel热点key限流
十、手把手教你搭建SpringCloudAlibaba之Sentinel系统保护规则
十一、手把手教你搭建SpringCloudAlibaba之Sentinel服务熔断
十二、手把手教你搭建SpringCloudAlibaba之Sentinel规则持久化
十三、手把手教你搭建SpringCloudAlibaba之Seata分布式事务
点击跳转学习 -------------->手把手教你搭建SpringCloud项目
在前边的几篇文章都使用到了SentinelResource的注解。这篇来仔细学习一下。
@SentinelResource的参数如下:
value:资源名称
entryType:entry 类型,可选项(默认为 EntryType.OUT),可选EntryType.OUT和EntryType.IN
blockHandler/ blockHandlerClass:定位对应处理 BlockException 的函数名称blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。
fallback / fallbackClass:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。
defaultFallback(since 1.6.0):默认的 fallback 函数名称,可选项
exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
fallback参数的使用
我们在代码中加入一个算术异常,然后再进行热点限流,看看会发现什么?
//测试热点限流的方法 传递参数p1与参数p2
@GetMapping("/testHotKey")
//注意不要加/
@SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey" ) //指定兜底的方法 就是用blockHandler指的方法 所以就是deal_testHotKey
public String testHotKey(@RequestParam(value="p1",required =false)String p1,
@RequestParam(value = "p2",required = false) String p2){
int a=10/0;
return "------成功访问了testHotKey方法________(*^▽^*)";
}
public String deal_testHotKey(String p1, String p2, BlockException e){
return "------进行了限流 deal_testHotKey,o(╥﹏╥)o";
}
热点限流规则还跟之前一样,如下图:
访问http://localhost:8401/testHotKey?p1=2&p2=1 可以看到出现算术的异常,直接显示在我们的浏览器上。
我们在1秒内点击超过一次还是会被正常限流,不会出现以上的算术异常。
这里可以得到结论:我们配置SentinelResource注解的兜底方法 deal_testHotKey。只会对Sentinel控制台配置的规则进行限流,并返回我们方法的提示,并不会对运行的异常进行提示。那那出现的情况怎么办?
这里就可以使用fallback参数,用于在抛出异常的时候提供 fallback 处理逻辑,代码如下。
@GetMapping("/testHotKey")
//注意不要加/
@SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey",fallback = "fallback")
public String testHotKey(@RequestParam(value="p1",required =false)String p1,
@RequestParam(value = "p2",required = false) String p2){
int a=10/0;
return "------成功访问了testHotKey方法________(*^▽^*)";
}
public String deal_testHotKey(String p1, String p2, BlockException e){
return "------进行了限流 deal_testHotKey,o(╥﹏╥)o";
}
public String fallback(@RequestParam(value="p1",required =false)String p1,
@RequestParam(value = "p2",required = false) String p2,Throwable e){
return "------进行了 fallback,出现了,"+e.getMessage()+"的错误,o(╥﹏╥)o";
}
踩坑提示:fallback方法的参数和返回类型都要与testHotKey方法保持一致,不然fallback参数不生效。
我们再次访问http://localhost:8401/testHotKey?p1=2&p2=1 ,可以看到出现了我们fallback中设置的提示,如下图:
我们1秒内请求多次,会走我们deal_testHotKey方法的限流的提示,由此可以得出:当同时配置了blockHandler和fallback,则被限流降级而抛出blockHandler的处理逻辑。如下图。
exceptionsToIgnore参数的使用
exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
我们在代码中加上该参数看下,指定当是算术异常。
@GetMapping("/testHotKey")
//注意不要加/
@SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey",fallback = "fallback",exceptionsToIgnore = {ArithmeticException.class})
public String testHotKey(@RequestParam(value="p1",required =false)String p1,
@RequestParam(value = "p2",required = false) String p2){
int a=10/0;
return "------成功访问了testHotKey方法________(*^▽^*)";
}
public String deal_testHotKey(String p1, String p2, BlockException e){
return "------进行了限流 deal_testHotKey,o(╥﹏╥)o";
}
public String fallback(@RequestParam(value="p1",required =false)String p1,
@RequestParam(value = "p2",required = false) String p2,Throwable e){
return "------进行了 fallback,出现了,"+e.getMessage()+"的错误,o(╥﹏╥)o";
}
我们再次访问http://localhost:8401/testHotKey?p1=2&p2=1 ,可以看到出现了了error page的页面,如下图:
blockHandlerClass参数的使用
现在我们使用降级的处理方式村子的问题有哪些?
1、系统默认的,没有体现我们自己的业务要求
2、 依照现有条件,我们自定义的处理方法又和业务代码稠合在一块,不直观。
3、每个业务方法都添加一个兜底的,那代码膨胀加剧。
4、全局统一的处理方法没有体现。
那如何解决,这里就需要使用blockHandlerClass函数进行解决。
新建全局兜底的类GlobalHandlerException ,里边有两个处理的方法。代码如下:
public class GlobalHandlerException {
public static String globalHandlerException(@RequestParam(value="p1",required =false)String p1,
@RequestParam(value = "p2",required = false) String p2, BlockException e){
return "------成功访问了globalHandlerException方法________(*^▽^*)";
}
public static String globalHandlerException1(@RequestParam(value="p1",required =false)String p1,
@RequestParam(value = "p2",required = false) String p2, BlockException e){
return "------成功访问了globalHandlerException1方法________(*^▽^*)";
}
}
修改 @SentinelResource(value = "testHotKey",blockHandlerClass = {GlobalHandlerException.class},blockHandler = "globalHandlerException")中的参数,使用blockHandlerClass,指定上边的全局兜底的类,blockHandler指定该类中具体的那个方法。
@GetMapping("/testHotKey")
//注意不要加/
@SentinelResource(value = "testHotKey",blockHandlerClass = {GlobalHandlerException.class},blockHandler = "globalHandlerException")
public String testHotKey(@RequestParam(value="p1",required =false)String p1,
@RequestParam(value = "p2",required = false) String p2){
return "------成功访问了testHotKey方法________(*^▽^*)";
}
我们访问请求,可以看到返回了全局兜底中的globalHandlerException方法返回的提示信息。
修改blockHandler参数指定该全局兜底中类中具体的globalHandlerException1的方法,可以看到
返回了全局兜底类中的globalHandlerException1方法返回的提示信息。
fallbackClass参数的使用
fallbackClass的使用和blockHandlerClass是一样的!!!
新建全局处理异常类GlobalFallBack,里边有两个处理的方法。代码如下:
public class GlobalFallBack {
public static String globalFallBack(@RequestParam(value="p1",required =false)String p1,
@RequestParam(value = "p2",required = false) String p2, Throwable e){
return "------进入了全局限流globalFallBack方法________(*^▽^*)";
}
public static String globalFallBack1(@RequestParam(value="p1",required =false)String p1,
@RequestParam(value = "p2",required = false) String p2, Throwable e){
return "------进入了全局限流globalFallBack1方法________(*^▽^*)";
}
修改@SentinelResource(value = "testHotKey",blockHandlerClass = {GlobalHandlerException.class},blockHandler = "globalHandlerException",
fallbackClass = {GlobalFallBack.class}, fallback = "globalFallBack")中的参数,使用fallbackClass ,指定上边的全局处理异常的类,fallback 指定该类中具体的那个方法。
@GetMapping("/testHotKey")
//注意不要加/
@SentinelResource(value = "testHotKey",blockHandlerClass = {GlobalHandlerException.class},blockHandler = "globalHandlerException",
fallbackClass = {GlobalFallBack.class}, fallback = "globalFallBack")
public String testHotKey(@RequestParam(value="p1",required =false)String p1,
@RequestParam(value = "p2",required = false) String p2){
int a=10/0;
return "------成功访问了testHotKey方法________(*^▽^*)";
}
我们访问请求,可以看到返回了全局处理异常中类中的globalFallBack方法返回的提示信息。
修改fallback 参数指定该全局异常类中具体的globalFallBack1的方法,可以看到
返回了全局异常类中的globalFallBack1方法返回的提示信息。
至此sentinel的注解SentinelResource就学完了。