Sentinel 1.8.2 持久化到Nacos push模式文档及测试
[push模式改造链接](https://www.jianshu.com/p/9a6cf8634805
1.流控规则介绍
官方文档介绍https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81
1.1资源名: 唯一名称,默认请求路径,方法被 @SentinelResource(value = “test-zjxl”) 可以用 test-zjxl 代替
1.2针对来源:Sentinel可以针对调用者进行限流,填写微服务名,默认default (不区分来源)
1.3阈值/单机类型:
- QPS :表示每秒钟的请求数量,当调用该 api 的 QPS 达到阈值的时候,进行限流。
- 线程数 : 当调用该 api 的线程数达到阈值的时候,进行限流
1.4流控模式:
- 直接 : api 达到限流条件时,直接限流心
- 关联 : 当关联的资源达到阈值时,就限流自己
- 链路 : 只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【api级别的针对来源】
1.5流控效果:
- 快速失败 : 直接失败,抛异常
- Warm Up : 根据codeFactor(冷加载因子,默认3)的值,从阈值codeFactor,经过预热时长,才达到设置的QPS阈值
- 排队等待 : 匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效
@SentinelResource 注解说明
属性名 | 是否必填 | 说明 |
---|---|---|
value | 是 | 资源名称 。(必填项,需要通过 value 值找到对应的规则进行配置) |
entryType | 否 | entry类型,标记流量的方向,取值IN/OUT,默认是OUT |
blockHandler | 否 | 处理BlockException的函数名称(可以理解为对Sentinel的配置进行方法兜底)。函数要求: 1.必须是 public 修饰 2.返回类型与原方法一致 3. 参数类型需要和原方法相匹配,并在最后加 BlockException 类型的参数。 4. 默认需和原方法在同一个类中。若希望使用其他类的函数,可配置 blockHandlerClass ,并指定blockHandlerClass里面的方法。 |
blockHandlerClass | 否 | 存放blockHandler的类。 对应的处理函数必须 public static 修饰,否则无法解析,其他要求:同blockHandler。 |
fallback | 否 | 用于在抛出异常的时候提供fallback处理逻辑(可以理解为对Java异常情况方法兜底)。 fallback函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。函数要求: 1.返回类型与原方法一致 2.参数类型需要和原方法相匹配,Sentinel 1.6开始,也可在方法最后加 Throwable 类型的参数。 3.默认需和原方法在同一个类中。若希望使用其他类的函数,可配置 fallbackClass ,并指定fallbackClass里面的方法。 常常用来多服务建互相调用使用 |
fallbackClass | 否 | 存放fallback的类。 对应的处理函数必须static修饰,否则无法解析,其他要求:同fallback。 |
defaultFallback | 否 | 用于通用的 fallback 逻辑。 默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,以fallback为准。函数要求: 1.返回类型与原方法一致 2.方法参数列表为空,或者有一个 Throwable 类型的参数。 3.默认需要和原方法在同一个类中。若希望使用其他类的函数,可配置 fallbackClass ,并指定 fallbackClass 里面的方法。 |
exceptionsToIgnore | 否 | 指定排除掉哪些异常。 排除的异常不会计入异常统计,也不会进入fallback逻辑,而是原样抛出。 |
exceptionsToTrace | 否 | 需要trace的异常 |
2.流控模式演示
2.1 QPS直接模式 -快速失败
@ApiOperation("测试直接限流")
@PostMapping("/test-zjxl")
@SentinelResource(value = "test-zjxl")
public String save() {
return "此方法测试是直接限流~";
}
@SentinelResource(value = “test-zjxl”) 这里的value 值就是在Sentinel客户端-资源名一一对应的。
正常可以一秒一次可以访问
当一秒钟点击3次
这时候就报错了 。 我这里应该是拦截报错了,sentinel异常 Blocked by sentinel
2.2 关联模式
- 当关联的资源达到阈值时,就限流自己
- 实际场景 当支付下单和支付二个服务一起。当支付服务流量过高,就会限制下单服务,资源让给支付服务
@PostMapping("/testB")
@SentinelResource(value = "testB")
public String b() {
return "testB~";
}
这时候在去访问test-zjxl 就会出现访问异常
3.流控效果演示
3.1Warm Up(预热)
官方说明 :https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6
- 冷加载因子 :默认 coldFactor 为 3,即请求 QPS 从 threshold/3 开始,经预热时长逐渐升至设定的QPS阈值。
3.2排队等待
- 让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效
- 每个请求,愿意等就等,不愿意等就超时重试
修改流控规则后
3.2.1使用 Postman 模拟大量请求
3.2.2请求均速的执行
4. 热点 key 限流
官方文档:https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81
简单介绍:
4.1热点key 使用
配置
参数索引:当前接口第几个参数 从0开始
单机阈值:可以访问几次
统计窗口:几秒钟
参数类型:当前参数的数据类型
参数值:当前参数的值
限流值:超过多少被限流
总体:在一秒内超过5次就会被限流,如果一秒内第一个参数传值aaa的话 请求超过一次就会被限流。
针对某个key值去做限流
代码
@GetMapping("/testZhuJie")
@SentinelResource(value = "testZhuJie", blockHandler = "failBlockHandler")
public String testZhuJie(@RequestParam(value = "p1", required = false) String p1,
@RequestParam(value = "p2", required = false) String p2) {
return "1111111";
}
/**blockHandler 函数会在原方法被限流/降级/系统保护的时候调用*****/
public String failBlockHandler(@RequestParam(value = "p1", required = false) String p1,
@RequestParam(value = "p2", required = false) String p2, BlockException be) {
return "您访问的太频繁了,请稍后再试!";
}
测试结果:
5.熔断配置
此处对于熔断做一个解释:当我们满足熔断条件服务停止使用,当熔断时间过后变为探测态,如果此时进来的请求不触发熔断规则,则我们可以关闭熔断,如果此时进入的请求触发了熔断规则,那么我们继续熔断。
5.1慢调用
@GetMapping("/degrade")
@SentinelResource(value = "degrade")
public String doSlowCall() throws InterruptedException {
// 程序休眠 单位毫秒
// Thread.sleep(200);
try{
TimeUnit.SECONDS.sleep(2);
}catch (Exception e){
}
return "sentinel do slow call";
}
效果:当请求数大于5以后,如果请求的响应时间大于200毫秒的超过20%,则熔断10秒。
**注意:**RT指的响应时间,Sentinel 默认统计的 RT 上限是 4900ms,超出此阈值的都会算作 4900ms,若需要
变更此上限可以通过启动配置项-Dcsp.sentinel.statistic.max.rt=xxx 来配置
5.2异常比例
当单位统计时长(statIntervalMs
)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0]
,代表 0% - 100%。
当资源的请求数,并且异常总数占通过量的比例超过比例阈值时,
资源进入降级状态这时候会走blockHandler 方法!
效果:请求数量大于1,异常请求数量比例大于10%,熔断5s
模拟一个异常 int i = 10 / 0;
@GetMapping("/testZhuJie")
@SentinelResource(value = "testZhuJie", blockHandler = "failBlockHandler")
public String testZhuJie() {
int i = 10 / 0;
return "1111111";
}
/**blockHandler 函数会在原方法被限流/降级/系统保护的时候调用*****/
public String failBlockHandler(BlockException be) {
return "您访问的太频繁了,请稍后再试!";
}
5.2.1慢点击 原始By zero错误
5.2.2快点击 sentinel 熔断异常 走blockHandler 方法
5.3异常数 (较少使用)
当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
还是上面那个代码
@GetMapping("/testZhuJie")
@SentinelResource(value = "testZhuJie", blockHandler = "failBlockHandler")
public String testZhuJie() {
int i = 10 / 0;
return "1111111";
}
/**blockHandler 函数会在原方法被限流/降级/系统保护的时候调用*****/
public String failBlockHandler(BlockException be) {
return "您访问的太频繁了,请稍后再试!";
}
最终结果和异常比例一样都会走blockHandler!
", blockHandler = “failBlockHandler”)
public String testZhuJie() {
int i = 10 / 0;
return “1111111”;
}
/**blockHandler 函数会在原方法被限流/降级/系统保护的时候调用*****/
public String failBlockHandler(BlockException be) {
return "您访问的太频繁了,请稍后再试!";
}
最终结果和异常比例一样都会走blockHandler!