如图,当调用接口时实时监控会记录接口调用时间以及通过拒绝的QPS还有接口响应时长。
用来显示微服务所监控的API,资源。
簇点链路面板中选择一个资源,可以进行流控设置。
QPS指的是服务每秒的请求数,阈值设置为1时,代表服务1秒钟只能被请求一次,其他的将会被流控。
线程数指的是线程数量,当阈值设置为1时,代表服务只同时处理一个请求,也就是第一个进来的请求在未做出响应时,其他再进来的请求都会被流控。
直接表示针对该资源被流控。
当A资源流控模式选择关联时,会出现关联资源,设置关联资源B后,就表示当B资源符合了所设置的流控规则后,A资源将会被流控。
如下图表示当资源/user/set
每秒访问数大于1时,/user/get
资源会被流控。
当资源A都被资源B和资源C所调用,那么相互之间就构成了一颗调用树,根节点为A,BC为调用链的入口称为子节点。
选择链路后,会出现入口资源,入口资源即资源A的子节点B或C,当入口资源符合流控规则时该入口资源会被流控。
示例:
注: 高版本(2.1.1.RELEASE开始)中,默认将调用链路收敛,链路限流不生效,需要配置中加入spring.cloud.sentinel.web-context-unify=false
实现链路限流。
创建一个getUser的资源,并创建两个接口调用该资源。
@SentinelResource(value = "getUser")
public User getUser() {
return new User(1,"张三");
}
@RequestMapping("/getUser1")
public User getUser1() {
return userService.getUser();
}
@RequestMapping("/getUser2")
public User getUser2() {
return userService.getUser();
}
做如上图设置后,/user/getUser1
资源一秒中访问超过1时会被流控,而/user/getUser2
资源不会。
直接拒绝(RuleConstant.CONTROL_BEHAVIOR_DEFAULT)方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。
Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。
冷加载因子: codeFactor 默认是3,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。
当有一个请求很少有人访问处于相对平稳,突然一大堆该请求涌入的现象就叫激增流量。这时,系统应对突然涌入的流量时很可能被冲垮,通过设置Warm Up,并设置其预热时长(单位秒)与阈值来应对激增流量。
示例:
如下图,阈值15预热时间5s,表示当遇到激增流量时,会在5秒的时间内将可接受的请求慢慢增加至15,然后开始稳定的1秒接收15个请求,相应的被流控的请求也会逐渐减少。
排队等待(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也就是让请求以均匀的速度通过,对应的是漏桶算法。
这种方式适合用于请求以突刺状来到,这个时候我们不希望一下子把所有的请求都通过,这样可能会把系统压垮;同时我们也期待系统以稳定的速度,逐步处理这些请求,以起到“削峰填谷”的效果,而不是拒绝所有请求。
示例:
如果将流控效果设置为快速失败,阈值为5时,然后让请求每1秒钟请求10次,间隔5秒后重复请求,如下图,每次都会通过5个,流控5个,而间隔时间没有利用起来。
因此,可以通过排队等待解决这个问题,如下图设置超时时间为5秒,阈值5。表示当请求进来时,先去处理5个,剩余的请求排队等待,在规定的超时时间5s内,处理掉一个进去一个。
现在,开始测试,让每秒请求10次,间隔5秒,重复操作,如下图,发现全部都请求成功了,说明在设置的超时时间内将本该流控的请求依次处理成功了。
最大RT: 慢调用的临界RT,单位毫秒,超过该时间的请求被视为慢调用。(RT为执行一个请求从开始到最后收到响应数据所花费的总体时间,即从客户端发起请求到收到服务器响应结果的时间。)
比例阈值: 统计时长内请求数目m大于最小请求数时,慢调用请求数除以m,超过比例阈值则触发熔断降级。
熔断时长: 断路器打开时的恢复超时。单位秒,当熔断触发后且没有请求时,超过熔断时长,断路器会处于半开状态,若接下来的第一个请求响应时间小于最大RT,则结束熔断;如果仍然超过最大RT,则会再次熔断。
最小请求数: 在统计时长内可以触发熔断的最小请求数,默认为5。
统计时长: 统计时长,默认为1000毫秒。
测试:
编写一个睡眠3秒的请求,将该请求设置如下降级规则:
@RequestMapping("/test/degrade")
public String degrade() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("degrade");
return "degrade";
}
这里使用的是Apifox工具,设置5个线程数(为了达到统计时长内最小请求数的要求),循环三次,时间间隔为3秒(不超过所设置的熔断时长),运行结束后,等10s过后再次单个请求两次,第二次直接降级,再等10s过后再次单个请求两次,第二次直接降级。
热点规则一般作用于两种场景:
示例:
@RequestMapping("/test/hotSpot")
@SentinelResource(value = "hotSpot",blockHandler = "hotSpotBlock")
public String hotSpot(Integer id) {
System.out.println("hotSpot: " + id);
return "hotSpot: " + id;
}
public String hotSpotBlock(Integer id,BlockException blockException) {
return "流控!!";
}
当入参为1时,每秒访问超过2次后的请求会被流控,当入参不为1时,每秒访问量超过5后的请求被流控。
Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5。
当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
来源访问控制根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。
,
分隔,如 appA,appB。AUTHORITY_WHITE
为白名单模式,AUTHORITY_BLACK
为黑名单模式,默认为白名单模式。测试:
通过实现RequestOriginParser接口来获取来源,设置为app
。
@Component
public class MyRequestOriginParser implements RequestOriginParser {
public String parseOrigin(HttpServletRequest request) {
return "app";
}
}
编写测试接口,并创建该资源的授权规则。
@RequestMapping("/test/auth")
@SentinelResource(value = "auth",blockHandler = "authBlock")
public String system() {
System.out.println("auth");
return "auth";
}
public String authBlock(BlockException blockException) {
return "授权";
}
浏览器请求/test/auth
时发现打印了“授权”两个字,说明已经限制了。