一、Sentinel控制台
二、实时监控
2.1、概述
实时监控,顾名思义是用来实时监控的,具体监控的是接口请求通过的QPS和拒绝的QPS,默认情况下没有访问记录,所以看不到任何记录,需要访问接口才会有记录。另外需要注意,当A时间段方案/a接口很频繁,实时监控页面会看到如下的数据,如果这个时间段有多个接口请求的话,会依次列出所有访问的接口。当过了一段时间没有任何访问的话,该接口对应的访问记录也不会再这里继续显示。
2.2、概览
三、簇点链路
3.1、概述
簇点链路是用来显示微服务中哪些接口可以用来监控。比如order-service-sentinel服务里面有两个接口,/sentinel/order/placingOrder和/sentinel/order/getOrderDetail/1,某一时间段只调用了/sentinel/order/placingOrder接口,则簇点链路页面将只会看到/sentinel/order/placingOrder的信息,/sentinel/order/getOrderDetail/1对应的信息是看不到的,反言之,簇点链路中显示的是微服务中哪些接口曾经被访问过,如果该服务中的接口都没有被访问过,则不会显示该服务下的任何接口。
四、流控规则
4.1、概览
4.2、实战(QPS + 直接 + 快速失败)
4.2.1、配置
4.2.2、代码
@SentinelResource(value = "flow",blockHandler = "flowBlockHandler")
@GetMapping("/flow")
public String flow() {
return "flow success!(*^▽^*)";
}
public String flowBlockHandler(BlockException e) {
log.error("出错了,error:{}",e.getMessage());
e.printStackTrace();
return "flow blocked!(灬ꈍ ꈍ灬)";
}
4.2.3、测试效果
当QPS小于等于2时,正常访问,当QPS大于2时,被流控!
4.2.4、原理
4.2.5、注意事项
如果使用的是@SentinelResource注解进行的流控,上述配置没问题。但是如果采用了统一日常处理,流控规则要配置在 /sentinel/order/flow 上
4.3、实战(并发线程数 + 直接)
4.3.1、配置
4.3.2、代码
@SentinelResource(value = "flowThread",blockHandler = "flowThreadBlockHandler")
@GetMapping("/flowThread")
public String flowThread() {
// 线程休眠(单位:秒)
try { TimeUnit.SECONDS.sleep(5); } catch (Exception e) {e.printStackTrace();}
return "flowThread success!(*^▽^*)";
}
public String flowThreadBlockHandler(BlockException e) {
log.error("出错了,error:{}",e.getMessage());
e.printStackTrace();
return "flowThread blocked!(灬ꈍ ꈍ灬)";
}
4.3.3、测试结果
根据上面的配置可以清晰的知道,资源处理需要的时间是5s,配置的阈值类型为线程数,其值为2,也就意味着在资源处理的时间段内最多允许2个线程进来,其他的线程在这5s内再进来将会被限流。测试结果如下:
4.3.4、原理
4.4、实战(QPS + 关联 + 快速失败)
4.4.1、概述
为了方便大家伙的理解,我这边举个例子:小明追女神小芳,小芳有一个闺蜜秀芹,某一天秀芹被渣男伤害了(秀芹告诉小芳,天底下没有一个好男人,分了吧!),然后小芳和小明分手了,小明追的是小芳,但是却因为秀芹被渣男的伤害,导致自己莫名躺枪,不得不和女神Say Good Bye!
4.4.2、配置
4.4.3、代码
@GetMapping("/xiaoFang")
public String xiaoFang() {
return "小明追小芳success!(*^▽^*)";
}
@GetMapping("/xiuQin")
public String xiuQin() {
return "秀芹被渣男伤害了!(灬ꈍ ꈍ灬)";
}
4.4.4、测试
为了测试效果,我这边借用了Apache Jmeter压测工具进行测试,如果不知道Jmeter如何使用的,请参考【系列二十七、Apache Jmeter使用】,这里不再赘述!
Jmeter配置:
4.4.5、结果分析
由于资源/sentinel/order/xiaoFang配置的流控规则是关联模式,关联的资源为 /sentinel/order/xiuQin,当/sentinel/order/xiuQin出事儿时,资源/sentinel/order/xiaoFang也将受牵连。
4.5、实战(QPS + 链路 + 快速失败)
4.5.1、概述
链路的官方语言解释有点儿晦涩难懂,为了方便大家伙儿的理解,我这边还是举个例子,让大家伙儿在轻松愉快中理解链路是个什么玩意儿,例如当前controller层中有如下两个方法,即:/sentinel/order/test1和/sentinel/order/test2,这俩方法都调用了OrderService#listAllUser方法,那么这里就涉及到了3个资源,这3个资源可以构成一颗树,其中listAllUser为根节点,
/sentinel/order/test1和/sentinel/order/test2为这颗树的子节点,我现在有个需求,针对/sentinel/order/test1请求,不流控,随便访问都OK;对/sentinel/order/test2进行限流,QPS为2,当超过2时就限流,针对这种多个方法调用同一个资源,只想对某些方法进行限流的场景就可以使用链路模式。
4.5.2、配置
4.5.3、代码
@GetMapping("/test1")
public String test1() {
return orderService.listAllOrder();
}
@GetMapping("/test2")
public String test2() {
return orderService.listAllOrder();
}
@Service
public class OrderService {
/**
* @return
*/
@SentinelResource(value = "listAllOrder")
public String listAllOrder() {
return "查询所有订单success!(*^▽^*)";
}
}
spring.cloud.sentinel.web-context-unify=false # 默认将调用链路收敛了
4.5.4、测试
/sentinel/order/test1随便访问都OK
/sentinel/order/test2 QPS大于2时,报如下错误:
4.6、实战(QPS + 直接 + Warm Up)
4.6.1、概述
所谓Warm Up是指某一时刻,例如双11秒杀,一瞬间涌入了大量的请求,这个时候服务器可能一下子扛不住那么大的压力,可以将请求一点一点的放进来,最终达到最高阈值。结合下面的配置可以这样理解:某一时刻来了15个请求来访问/sentinel/order/flow接口,但是服务器扛不住这么大的压力,于是设置了Warm Up的流控效果,这样既可以避免一瞬间将服务器打垮,又可以慢慢处理用户的请求,好比跑步热身的过程,第一公里配速8,第二公里配速7.5,第三公里配速630...,第十公里630。Warm Up还有一个默认的效果,即:第一秒处理3个请求,之后的每一秒都当前请求的基础上 + threshold/codeFactor,其中codeFactor的默认值为3
4.6.2、配置
4.6.3、代码
@SentinelResource(value = "flow",blockHandler = "flowBlockHandler")
@GetMapping("/flow")
public String flow() {
return "flow success!(*^▽^*)";
}
public String flowBlockHandler(BlockException e) {
log.error("出错了,error:{}",e.getMessage());
e.printStackTrace();
return "flow blocked!(灬ꈍ ꈍ灬)";
}
4.6.4、测试结果
4.7、实战(QPS + 直接 + 排队等待)
4.7.1、概述
排队等待模式主要用于处理间隔性突发的流量,例如:消息队列。想像一下这样的场景,在某一秒有大量的请求过来,而接下来的一段时间服务器则处于空闲状态,我们希望希望能够在接下来的空闲时间里逐步处理请求,而不是第一秒直接拒绝多余的请求。生活中的案例:海底捞休息区排队等待,而不是餐桌满了之后直接将用餐的客人拒绝掉(老板打死你)
4.7.2、配置
4.7.3、代码
@SentinelResource(value = "flow",blockHandler = "flowBlockHandler")
@GetMapping("/flow")
public String flow() {
return "flow success!(*^▽^*)";
}
public String flowBlockHandler(BlockException e) {
log.error("出错了,error:{}",e.getMessage());
e.printStackTrace();
return "flow blocked!(灬ꈍ ꈍ灬)";
}
4.7.4、测试步骤
4.7.5、测试结果
五、熔断规则
5.1、概览
5.2、实战(慢调用比例)
5.2.1、概述
慢调用比例是指客户端针对某个资源发起的一些列请求中,服务端响应时长大于自己所能忍受的最大时长的比例。例如客户端想访问资源 /sentinel/order/fusing,能接受的超时比例为0.1,即如果用户发起10个请求,这10个请求中,如果有一个响应时长大于客户端忍受的时长(RT对应的值,单位:毫秒),那么就会触发熔断。
5.2.2、配置
5.2.3、代码
@GetMapping("/fusing")
public String fusing() {
// 线程休眠(单位:秒)
try { TimeUnit.SECONDS.sleep(2); } catch (Exception e) {e.printStackTrace();}
log.info("fusing success!(*^▽^*)");
return "fusing success!(*^▽^*)";
}
5.2.4、测试步骤
5.2.5、测试结果
5.3、实战(异常比例)
5.3.1、概述
熔断规则的异常比例,顾名思义是指客户端发送的一系列请求中,异常比例达到多少是将会触发服务熔断。熔断期间,服务将不可用
5.3.2、配置
5.3.3、代码
@GetMapping("/fusingError")
public String fusingError() {
int number = new Random().nextInt(10);
log.info("number:{}", number);
if (number < 5) {
int i = 10 / 0;
}
return "(*^▽^*)";
}
5.3.4、测试结果
5.4、实战(异常数)
5.4.1、概述
熔断规则的异常数,顾名思义是指,发送N个请求,当有M个是异常时,将会触发熔断。
5.4.2、配置
5.4.3、代码
@GetMapping("/fusingError")
public String fusingError() {
int number = new Random().nextInt(10);
log.info("number:{}", number);
if (number < 5) {
int i = 10 / 0;
}
return "(*^▽^*)";
}