流量控制

控制模式

  1. 直接: 针对资源自己直接进行流量控制
  2. 关联: 监控关联资源的流量情况来对自身资源进行限制
  3. 链路: 对资源内部调用的资源进行入口来源的限制
    注意: 链路的支持需要设置sentinel的url关闭聚合,在某些版本(1.7.2+)提供了属性来关闭

    1. spring:
    2. cloud:
    3. sentinel:
    4. web-context-unify: false #关闭聚合
  4. 没有提供属性就只能改写内部代码。

    控制效果

  5. 快速失败: 达到阀值之后直接抛异常

  6. Warm Up: 当流量在某一瞬间很大的时候,它不会让流量立即到达阀值,而是进过一段时间慢慢的预热增长
  7. 排队通过:请求达到阀值进行匀速排队通过

    降级策略

  8. RT: 平均响应时间,当 1s 内持续进入 N 个请求,对应时刻的平均响应时间(秒级)均超过阈值(count,以 ms 为单位),那么在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单 位)之内,对这个方法的调用都会自动地熔断(抛出 DegradeException)。

  9. 异常比例: 通过每秒的异常总数计算比例
  10. 异常数量

    热点参数

    热点参数是对调用接口时候传入某个参数进行流控,这种方式需要设置@SentinelResource

    集群流控(了解)

    集群流控中共有两种身份:
    Token Client:集群流控客户端,用于向所属 Token Server 通信请求 token。集群限流服务端会返回给客户端结果,决定是否限流。Token Server:即集群流控服务端,处理来自 Token Client 的请求,根据配置的集群规则判断是否应该发放 token(是否允许通过)。
    Sentinel流控设置 - 图1

    三大接口

  11. 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();
     }
    }
    
  12. RequestOriginParser: 请求解析,可以用在正对来源以及黑白名单里面来返回来源数据进行匹配,下面的例子,通过参数Who来携带来源信息,代码中提取来源数据返回

    @Component
    public class MyReqeustParse implements RequestOriginParser {
     @Override
     public String parseOrigin(HttpServletRequest request) {
         return request.getParameter("who");                    
     }
    }
    
  13. 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 "限流或则降级了....";
    }
    

    属性解释:

  14. value: 资源的名称

  15. blockHandler: 流控异常处理的函数名称
    函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配,并且最后加一个额外的参数,类型为 BlockException。函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数。
  16. fallback : 异常处理的函数名称
    返回值类型必须与原函数返回值类型一致,方法参数列表需要和原函数一致,可以多一个Throwable参数用于接收对应的异常。函数默认需要和原方法在同一个类中。若希望使用其他类的函数,可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数。

    对Feign以及RestTemplate的支持

  17. 对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";
     }
    }
    
  18. 对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) {
         ...
     }
    }
    

理论

  1. Sentinel的流控模式有哪些
    直接: 针对资源自己直接进行流量控制
    关联: 监控关联资源的流量情况来对自身资源进行限制
    链路: 对资源内部调用的资源进行入口来源的限制
    注意: 链路的支持需要设置sentinel的url关闭聚合,在某些版本(1.7.2+)提供了属性来关闭
    
  2. Sentinel的应用来源的设置流程
    xxxxxxxxxx @SentinelResource用于定义需要流控的资源,并提供可选的异常处理和 fallback 配置项,可以通过以下属性关闭掉默认的埋点,关闭 之后就只能通过@SentinelResource来自定义资源,自定义资源需要自己定义流控异常的处理。
    
  3. 集群流控的模型
    Token Client:集群流控客户端,用于向所属 Token Server 通信请求 token。集群限流服务端会返回给客户端结果,决定是否限流。Token Server:即集群流控服务端,处理来自 Token Client 的请求,根据配置的集群规则判断是否应该发放 token(是否允许通过)