1.Sentinel热点概念

何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:

  • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
  • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制

热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。
热点限流触发后会抛出ParamFlowException,该异常继承于BlockException

2.Sentinel热点原理

热点包括两部分。一部分是如何实现热点,一部分是如何实现限流

  • 热点:通过LRU算法(最近最少使用)具体理解点击这里
  • 限流:通过令牌桶算法进行参数级别的流控

    3.Sentinel热点参数

    如图:
    image.png
    image.png
属性 说明 默认值
资源名 规则的作用对象。 -
限流模式 限流模式 QPS 模式
参数索引 当前参数属于该资源的第几个参数,默认从0开始
单机阈值 单机请求阈值
统计窗口时长 统计时间 -
参数类型 参数例外项允许的参数类型,参考上图即可 -
参数值 指定当前索引参数的具体值是多少,当值为当前具体值时,会触发例外项的阈值流控,否则走默认的阈值流控 -
限流阈值 参数额外项阈值 -

4.Sentinel热点具体实现

定义携带参数的资源

如下定义了一个参数包括(name,age)的资源

  1. @GetMapping("2")
  2. @SentinelResource(value = "getNoParam2", blockHandler = "getHandler2")
  3. public String get(@RequestParam(required = false) String name,
  4. @RequestParam(required = false) Integer age) {
  5. ServiceInstance choose = loadBalancerClient.choose("service-provider");
  6. String url = "http://" + choose.getHost() + ":" + choose.getPort() + "/api/v1/provider";
  7. return restTemplate.getForObject(url, String.class);
  8. }

控制台定义热点流控规则

如图:

  • 对于getNoParam资源,只有当请求携带第1个参数时,才进行限流。统计时长=1,单机阈值=1
  • 同时对于第一个参数,当参数值=ftc时,单机阈值=10,而不是1

    image.png

    请求验证

    当请求不携带第一个参数时,不会触发热点流控
    image.png
    当请求携带第一个参数,并且参数值!=ftc时,触发常规流控
    image.png
    当请求携带第一个参数,并且参数值=ftc时,触发参数额外项流控
    image.png

    5.Sentinel授权概念

    热点规则可以让我们从参数层面对请求进行限流。但是有的时候,我们想通过一些其他维度去限流请求,比如说让带有标识的请求通过,不带有标识的请求被拒绝。这个时候授权规则就派上了用场
    授权可以让我们从来源的维度对请求进行限流。可以配置白名单以及黑名单。若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。
    授权触发限流后会抛出AuthorityException,该异常继承于BlockException

    6.Sentinel如何定义来源

    Sentinel提供了 RequestOriginParser 接口来处理来源。只要Sentinel保护的接口资源被访问,Sentinel就会调用 RequestOriginParser 的实现类去解析访问来源。
    我们可以创建一个@Component标签声明的Spring组件来实现 RequestOriginParser,重写parseOrign方法。在方法内部自定义来源的获取方式
    代码参考如下

    1. @Component
    2. public class RequestOriginParserDefinition implements RequestOriginParser {
    3. @Override
    4. public String parseOrigin(HttpServletRequest httpServletRequest) {
    5. //如下,是通过请求参数sourceName定义的来源。
    6. //可以通过通过其他来定义来源,具体看项目需要
    7. return httpServletRequest.getParameter("sourceName");
    8. }
    9. }

    7.Sentinel授权参数

    注意:同一个资源只能指定一条授权规则
    image.png

属性 说明
资源名 规则的作用对象。
流控应用 即来源的定义。可以通过sentinel指定的来源RequestOriginParser 定义方法来定义来源。
授权类型 白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。
同一个资源只能指定一条授权规则

8.Sentinel授权具体实现

定义资源

  1. @GetMapping
  2. @SentinelResource(value = "getById")
  3. public String get(@RequestParam Integer id) {
  4. return feignService.get(id, "哈哈哈我是老八");
  5. }

编写来源解析器

  1. import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
  2. import org.springframework.stereotype.Component;
  3. import javax.servlet.http.HttpServletRequest;
  4. /**
  5. * @author 冯铁城 [fengtiecheng@cyou-inc.com]
  6. * @date 2022-06-21 10:03:41
  7. * @describe:
  8. */
  9. @Component
  10. public class SourceProcessor implements RequestOriginParser {
  11. @Override
  12. public String parseOrigin(HttpServletRequest request) {
  13. //从请求头获取source参数,来定义来源
  14. String source = request.getHeader("source");
  15. if(null == source){
  16. source = "defaultSource";
  17. }
  18. return source;
  19. }
  20. }

控制台定义授权规则

image.png

请求验证

当授权类型为白名单时,source=ftc请求成功,source=skx请求失败
image.png
当授权类型为黑名单时,source=ftc请求失败,source=skx请求成功
image.png

9.Sentinel系统

发生系统规则中配置的情况的时候,会把整个应用都断掉,所有的接口对不能对外提供服务了,这个设计很少用,因为粒度太大了,用 Sentinel 一般都是做细粒度的维护,如果设置了系统规则,可能自己都不知道怎么回事,系统就用不了了;
系统规则源码解析
系统负载Load的理解和分析
系统规则参数参考