流量控制
控制模式
- 直接: 针对资源自己直接进行流量控制
- 关联: 监控关联资源的流量情况来对自身资源进行限制
链路: 对资源内部调用的资源进行入口来源的限制
注意: 链路的支持需要设置sentinel的url关闭聚合,在某些版本(1.7.2+)提供了属性来关闭spring:
cloud:
sentinel:
web-context-unify: false #关闭聚合
-
控制效果
快速失败: 达到阀值之后直接抛异常
- Warm Up: 当流量在某一瞬间很大的时候,它不会让流量立即到达阀值,而是进过一段时间慢慢的预热增长
-
降级策略
RT: 平均响应时间,当 1s 内持续进入 N 个请求,对应时刻的平均响应时间(秒级)均超过阈值(count,以 ms 为单位),那么在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单 位)之内,对这个方法的调用都会自动地熔断(抛出 DegradeException)。
- 异常比例: 通过每秒的异常总数计算比例
-
热点参数
热点参数是对调用接口时候传入某个参数进行流控,这种方式需要设置@SentinelResource
集群流控(了解)
集群流控中共有两种身份:
Token Client:集群流控客户端,用于向所属 Token Server 通信请求 token。集群限流服务端会返回给客户端结果,决定是否限流。Token Server:即集群流控服务端,处理来自 Token Client 的请求,根据配置的集群规则判断是否应该发放 token(是否允许通过)。
三大接口
BlockExceptionHandler: 提供sentinel异常处理,Sentinel流控有默认的处理程序,可以通过实现该接口覆盖。
@Component public class MyUrlBlockHandler implements BlockExceptionHandler{ @Override public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception { System.out.println(e.getClass().getName()); response.setContentType("application/json;charset=utf8"); response.setCharacterEncoding("utf-8"); response.getWriter().write("{\"msg\":\"被流控了\"}"); response.getWriter().flush(); } }
RequestOriginParser: 请求解析,可以用在正对来源以及黑白名单里面来返回来源数据进行匹配,下面的例子,通过参数Who来携带来源信息,代码中提取来源数据返回
@Component public class MyReqeustParse implements RequestOriginParser { @Override public String parseOrigin(HttpServletRequest request) { return request.getParameter("who"); } }
UrlCleaner: 重新定义资源,可以从新定义资源埋点的名称,可以用来聚合一些动态的资源名。
@SentinelResource
用于定义需要流控的资源,并提供可选的异常处理和 fallback 配置项,可以通过以下属性关闭掉默认的埋点,关闭 之后就只能通过@SentinelResource来自定义资源,自定义资源需要自己定义流控异常的处理。
spring: cloud: sentinel: filter: enabled: false
下面是一个例子:
@SentinelResource(value = "newsServer", blockHandler = "blackNewsServer", fallback = "fallbackNewsServer") @GetMapping("/news4") public String newsServer(String id) { } public String fallbackNewsServer(String id,Throwable e) { return "出现异常了...."; } public String blackNewsServer(String id,BlockException e) { return "限流或则降级了...."; }
属性解释:
value: 资源的名称
- blockHandler: 流控异常处理的函数名称
函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配,并且最后加一个额外的参数,类型为 BlockException。函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数。 fallback : 异常处理的函数名称
返回值类型必须与原函数返回值类型一致,方法参数列表需要和原函数一致,可以多一个Throwable参数用于接收对应的异常。函数默认需要和原方法在同一个类中。若希望使用其他类的函数,可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数。
对Feign以及RestTemplate的支持
对Feign的支持
#配置开关: feign: sentinel: enabled: true
//fallback属性用来定义异常处理类 @FeignClient(name="service-provider",fallback=EchoServiceFallback.class,) public interface EchoService { @GetMapping("/echo/{str}") public String echo(@PathVariable("str") String str); } //异常处理类实现Feign接口重写所有接口方法的异常之后的处理 class EchoServiceFallback implements EchoService { @Override public String echo(@PathVariable("str") String str) { return "echo fallback"; } }
对RestTemplate的支持
@Bean @SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class) public RestTemplate restTemplate() { return new RestTemplate(); } //blockHandler 属性对应的处理方法 public ClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) { ... } //这是上面blockHandlerClass 属性对应的静态方法类 public class ExceptionUtil { public static ClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) { ... } }
理论
- Sentinel的流控模式有哪些
直接: 针对资源自己直接进行流量控制 关联: 监控关联资源的流量情况来对自身资源进行限制 链路: 对资源内部调用的资源进行入口来源的限制 注意: 链路的支持需要设置sentinel的url关闭聚合,在某些版本(1.7.2+)提供了属性来关闭
- Sentinel的应用来源的设置流程
xxxxxxxxxx @SentinelResource用于定义需要流控的资源,并提供可选的异常处理和 fallback 配置项,可以通过以下属性关闭掉默认的埋点,关闭 之后就只能通过@SentinelResource来自定义资源,自定义资源需要自己定义流控异常的处理。
- 集群流控的模型
Token Client:集群流控客户端,用于向所属 Token Server 通信请求 token。集群限流服务端会返回给客户端结果,决定是否限流。Token Server:即集群流控服务端,处理来自 Token Client 的请求,根据配置的集群规则判断是否应该发放 token(是否允许通过)