1.Sentinel热点概念
何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:
- 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
- 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。
热点限流触发后会抛出ParamFlowException,该异常继承于BlockException
2.Sentinel热点原理
热点包括两部分。一部分是如何实现热点,一部分是如何实现限流
- 热点:通过LRU算法(最近最少使用)具体理解点击这里
- 限流:通过令牌桶算法进行参数级别的流控
3.Sentinel热点参数
如图:
属性 | 说明 | 默认值 |
---|---|---|
资源名 | 规则的作用对象。 | - |
限流模式 | 限流模式 | QPS 模式 |
参数索引 | 当前参数属于该资源的第几个参数,默认从0开始 | |
单机阈值 | 单机请求阈值 | |
统计窗口时长 | 统计时间 | - |
参数类型 | 参数例外项允许的参数类型,参考上图即可 | - |
参数值 | 指定当前索引参数的具体值是多少,当值为当前具体值时,会触发例外项的阈值流控,否则走默认的阈值流控 | - |
限流阈值 | 参数额外项阈值 | - |
4.Sentinel热点具体实现
定义携带参数的资源
如下定义了一个参数包括(name,age)的资源
@GetMapping("2")
@SentinelResource(value = "getNoParam2", blockHandler = "getHandler2")
public String get(@RequestParam(required = false) String name,
@RequestParam(required = false) Integer age) {
ServiceInstance choose = loadBalancerClient.choose("service-provider");
String url = "http://" + choose.getHost() + ":" + choose.getPort() + "/api/v1/provider";
return restTemplate.getForObject(url, String.class);
}
控制台定义热点流控规则
如图:
- 对于getNoParam资源,只有当请求携带第1个参数时,才进行限流。统计时长=1,单机阈值=1
同时对于第一个参数,当参数值=ftc时,单机阈值=10,而不是1
请求验证
当请求不携带第一个参数时,不会触发热点流控
当请求携带第一个参数,并且参数值!=ftc时,触发常规流控
当请求携带第一个参数,并且参数值=ftc时,触发参数额外项流控5.Sentinel授权概念
热点规则可以让我们从参数层面对请求进行限流。但是有的时候,我们想通过一些其他维度去限流请求,比如说让带有标识的请求通过,不带有标识的请求被拒绝。这个时候授权规则就派上了用场
授权可以让我们从来源的维度对请求进行限流。可以配置白名单以及黑名单。若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。
授权触发限流后会抛出AuthorityException,该异常继承于BlockException6.Sentinel如何定义来源
Sentinel提供了 RequestOriginParser 接口来处理来源。只要Sentinel保护的接口资源被访问,Sentinel就会调用 RequestOriginParser 的实现类去解析访问来源。
我们可以创建一个@Component标签声明的Spring组件来实现 RequestOriginParser,重写parseOrign方法。在方法内部自定义来源的获取方式
代码参考如下@Component
public class RequestOriginParserDefinition implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest httpServletRequest) {
//如下,是通过请求参数sourceName定义的来源。
//可以通过通过其他来定义来源,具体看项目需要
return httpServletRequest.getParameter("sourceName");
}
}
7.Sentinel授权参数
注意:同一个资源只能指定一条授权规则
属性 | 说明 |
---|---|
资源名 | 规则的作用对象。 |
流控应用 | 即来源的定义。可以通过sentinel指定的来源RequestOriginParser 定义方法来定义来源。 |
授权类型 | 白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。 同一个资源只能指定一条授权规则 |
8.Sentinel授权具体实现
定义资源
@GetMapping
@SentinelResource(value = "getById")
public String get(@RequestParam Integer id) {
return feignService.get(id, "哈哈哈我是老八");
}
编写来源解析器
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* @author 冯铁城 [fengtiecheng@cyou-inc.com]
* @date 2022-06-21 10:03:41
* @describe:
*/
@Component
public class SourceProcessor implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest request) {
//从请求头获取source参数,来定义来源
String source = request.getHeader("source");
if(null == source){
source = "defaultSource";
}
return source;
}
}
控制台定义授权规则
请求验证
当授权类型为白名单时,source=ftc请求成功,source=skx请求失败
当授权类型为黑名单时,source=ftc请求失败,source=skx请求成功
9.Sentinel系统
发生系统规则中配置的情况的时候,会把整个应用都断掉,所有的接口对不能对外提供服务了,这个设计很少用,因为粒度太大了,用 Sentinel 一般都是做细粒度的维护,如果设置了系统规则,可能自己都不知道怎么回事,系统就用不了了;
系统规则源码解析
系统负载Load的理解和分析
系统规则参数参考