本篇继续我们的Sentinel,本篇记录一下Sentinel的热点参数限流,各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!
热点参数限流官方文档 点此查看
@SentinelResource 注解官方文档 点此查看
环境说明: 统一改为官方推荐的版本。
版本对应 点此查看
目录
热点参数介绍
@SentinelResource 注解
使用@SentinelResource + 配置热点参数限流
方式1 - 只配置value属性
增加测试方法
配置
测试
方式2 - value属性 + blockHandler
完善测试方法
配置
测试
何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。
先看下Sentinel新增热点规则的页面:
在进行热点参数限流的测试之前先看下这个@SentinelResource 注解:
@SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项,这里只记录一下接下来要使用的@SentinelResource属性:
value
:资源名称,必需项(不能为空)blockHandler
/blockHandlerClass
:blockHandler
对应处理BlockException
的函数名称,可选项。blockHandler 函数访问范围需要是public
,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为BlockException
。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定blockHandlerClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。fallback
/fallbackClass
:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了exceptionsToIgnore
里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:1、返回值类型必须与原函数返回值类型一致;2、方法参数列表需要和原函数一致,或者可以额外多一个Throwable
类型的参数用于接收对应的异常。3、fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定fallbackClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。defaultFallback
(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所有类型的异常(除了exceptionsToIgnore
里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:1、返回值类型必须与原函数返回值类型一致;2、方法参数列表需要为空,或者可以额外多一个Throwable
类型的参数用于接收对应的异常。3、defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定fallbackClass
为对应的类的Class
对象,注意对应的函数必需为 static 函数,否则无法解析。exceptionsToIgnore
(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
在FlowLimitController类中增加以下测试方法:
@GetMapping("/testHotKey")
@SentinelResource(value = "testHotKey")
public String testHotKey(@RequestParam(value = "p1", required = false) String p1,
@RequestParam(value = "p2", required = false) String p2) {
return "------testHotKey";
}
如下设置的含义为:当携带第一个参数(p1)访问/testHotKey的请求量超过1秒5个时,进行降级,携带第二个参数访问永远不会触发降级(效果不贴图了,感兴趣自己试试)。
使用jmeter创建如下线程组配置访问 http://localhost:8401/testHotKey?p1=1
每秒10个请求,超过了设置的阈值5会触发降级,我们通过浏览器再次 访问 http://localhost:8401/testHotKey?p1=1 结果如下:
我们修改线程组为一秒2个请求再测试下,一秒两个,并没有超过设定的阈值5,当通过浏览器访问的时候应该可以正常访问的,测试结果符合我们的预期效果,配置及结果如下:
在热点参数的高级选项中有个参数例外项设置, 它可以针对特别的参数进行降级,比如下面的配置的含义为:当携带第一个参数(p1)访问/testHotKey的请求量超过1秒5个时,进行降级,特殊的当传的参数为a时,请求量超过1秒100才进行降级。
我们修改线程组为一秒10个请求再测试下,一秒10个,没超过设定的阈值100,当通过浏览器访问的时候会,应该可以正常访问,测试结果符合我们的预期效果,配置及结果如下:
上面这种只配置value属性的方式,异常会提示到前台用户界面,不友好,下面我们通过追加blockHandler属性来自定义返回信息,类似于Hystrix的@HystrixCommand注解fallbackMethod方法。
在FlowLimitController类中增加以下测试方法:
@GetMapping("/testHotKey")
@SentinelResource(value = "testHotKey", blockHandler = "dealHandler_testHotKey")
public String testHotKey(@RequestParam(value = "p1", required = false) String p1,
@RequestParam(value = "p2", required = false) String p2) {
log.info("testE 热点参数");
return "------testHotKey";
}
public String dealHandler_testHotKey(String p1, String p2, BlockException exception) {
// 默认 Blocked by Sentinel (flow limiting)
return "-----dealHandler_testHotKey";
}
如下,我们该单机阈值为1,就不使用jmeter测试了,直接在浏览器快速访问就行。
通过浏览器快速 访问 http://localhost:8401/testHotKey?p1=1 2次,结果如下,返回了blockHandler属性指定方法的返回值,配置的降级生效,如下: