作用简单描述
主要作用就是进行流量控制。也就是通过定制不同的规则去进行流量控制。
下载地址
https://github.com/alibaba/Sentinel/releases
开启服务命令
java -Dserver.port=8180 -Dcsp.sentinel.dashboard.server=localhost:8180 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.2.jar
默认网站:http://localhost:8180
账户密码:sentinel
简单名词解释
阈值类型/单机阈值
- QPS:每秒请求数量;
- 线程数:调用当前接口的线程数
流控规则
- 直接:接口达到限流条件时,直接限流
- 关联:当关联的资源达到阈值时,就限流自己
- 链路:只记录指定链路上的流量换句话说,只记录指定资源从入口资源进来的流量,如果达到阈值,就限流
流控效果
- 快速失败:直接失败;
- Warm Up:即请求 QPS 从 一个值开始,经预热时长逐渐升至设定的 QPS 阈值
- 排队等待
项目引入
简单配置
服务消费方依赖添加
<!-- sentinel依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
yml文件:
spring:
cloud:
sentinel:
transport:
port: 8099
dashboard: localhost:8180
eager: true
web-context-unify: false
流控模式为链路模式时,假如是 sentinel 1.7.2 以后版本,Sentinel Web 过滤器默认收敛所有 URL 的入口上下文,因此互连限流不生效,需要在 application.yml 添加如下语句来关闭 URL PATH 聚合;
设计限流规则
在此处默认所有限流效果为直接失败
直接限流
@GetMapping("/direct")
public String doDirect(){
sentinelService.doSentinelGet();
return "sentinel do direct";
}
流控规则:
效果:每秒只能有一次请求获取到结果,其他请求直接失败。
关联限流
@GetMapping("/relation1")
public String doRelation1(){
sentinelService.doSentinelGet();
return "sentinel do relation1";
}
@GetMapping("/relation2")
public String doRelation2(){
sentinelService.doSentinelGet();
return "sentinel do relation2";
}
流控规则:
效果:当我们过多的请求relation2(每秒超过0.5次),那么我们会对relation1进行限流
链路限流
这个比较麻烦,首先需要写一个业务,让不同的请求去调用它:
@Service
public class SentinelService {
@SentinelResource("doSentinel")
public String doSentinelGet(){
System.out.println("sentinel do link");
return "sentinel do link";
}
}
然后在控制层对业务进行调用:
@Autowired
private SentinelService sentinelService;
@GetMapping("/link1")
public String doLink1(){
sentinelService.doSentinelGet();
return "sentinel do link1";
}
@GetMapping("/link2")
public String doLink2(){
sentinelService.doSentinelGet();
return "sentinel do link2";
}
流控规则: 流控地址:
此时有link1,link2都需要调取diSentinel 资源,但仅对于link1的调用进行限制:每秒请求数量大于1,直接失败。
设计限流效果
在此处默认所有限流规则为直接限流
快速失败
快速失败就是当达到限流规则后直接不能访问。在设计限流规则的时候有介绍此处就不在额外描述了。
WarmUp预热
秒杀系统等,可能一开始就会有大量的流量,这个时候需要后台进行慢慢适应(第一批请求过去后有了缓存就可以有效防止频繁的数据库操作)
此种相当于我们规定了一个阈值,但是它需要一个缓慢的过程来达到这个阈值。给了一个系统适应过程。
默认的初始阈值是我们给定的阈值/codeFactor,codeFactor默认为3
@GetMapping("/warm")
public String wramup(){
return "sentinel warm up";
}
预热规则:
效果:每秒请求数量为3,那么初始阈值就是1,预热时长就是10s
排队等待
当大量数据来的时候,部分数据先不失败而是进行排队并给了一个等待时间,如果等待时间依旧没有得到结果,那么就失败。
@GetMapping("/queue")
public String queue(){
return "sentinel Queue up";
}
编辑规则:
效果:单机阈值是3,大于3的请求就处于等待状态,当1s内解决不完,就失败。超时时间单位微秒。
degrade降级规则
此处对于熔断做一个解释:当我们满足熔断条件服务停止使用,当熔断时间过后变为探测态,如果此时进来的请求不触发熔断规则,则我们可以关闭熔断,如果此时进入的请求触发了熔断规则,那么我们继续熔断。
慢调用
给一个休眠时间,使其慢调用
@GetMapping("/demotion/slowcall")
public String doSlowCall() throws InterruptedException {
try{
TimeUnit.SECONDS.sleep(2);
}catch (Exception e){
}
return "sentinel do slow call";
}
编辑规则
效果:当请求数大于5以后,如果请求的响应时间大于200毫秒的超过20%,则熔断10秒。
**注意:**RT指的响应时间,Sentinel 默认统计的 RT 上限是 4900ms,超出此阈值的都会算作 4900ms,若需要 变更此上限可以通过启动配置项-Dcsp.sentinel.statistic.max.rt=xxx 来配置
异常比例
当资源的每秒请求数大于等于最小请求数,并且异常总数占通过量的比例超过比例阈值时, 资源进入降级状态。
@GetMapping("/demotion/abnormalproportion")
public String doAbnormalProportion() throws Exception {
throw new Exception("失败");
}
编辑规则:
效果:请求数量大于1,异常请求数量比例大于20%,熔断10s
异常数量
当资源近 1 分钟的异常数目超过阈值(异常数)之后会进行服务降级。
@GetMapping("/demotion/abnormalnum")
public String doAbnormalNum() throws Exception {
throw new Exception("失败");
}
编辑规则:
效果:请求数量大于5,异常数量有一个以上,熔断十秒。
热点规则
入门操作
热点也就是一段时间内被经常访问的数据,我们在进行网络请求的时候,比如一个商品管理系统,我们通常需要一些基本的信息来获取特定的物品,此时我们就可以通过对某个数据的限制来对热点数据进行限流操作。
@GetMapping("/hotpoint/introduction/url/{id}")
@SentinelResource("doIntroductionUrl")
public String doIntroductionUrl(@PathVariable Integer id) {
return "sentinel do hot point introduction url = "+id;
}
@GetMapping("/hotpoint/introduction/param")
@SentinelResource("doIntroductionParam")
public String doIntroductionParam(@RequestParam("id") Integer id) {
return "sentinel do hot point introduction param = "+id;
}
热点规则:通过@SentinelResource 注解内容进行规定
效果:对第一个参数进行限流操作,每秒只能通过1个。
高级操作
针对某个数据进行限流。
热点规则:
当该参数为10的时候,每秒可以得到两次回复,其他数值为1次回复。
系统规则
参数介绍
- Load(仅对 Linux/Unix-like 机器生效):当系统 load1 超过阈值,且系统当前的并
发线程数超过系统容量时才会触发系统保护。系统容量由系统的 maxQps * minRt 计 算得出。设定参考值一般是 CPU cores * 2.5。 - CPU 使用率:当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0)。
- RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
- 线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
- 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流 量指的是进入应用的流量(EntryType.IN),比如 Web 服务。
样例操作
此处使用了热点请求样例:
@GetMapping("/system/introduction")
@SentinelResource("doIntroduction")
public String doIntroduction() {
return "sentinel do system introduction.";
}
定制规则:
当CPU利用率超过5%,就会锁住所有该服务器程序,以防止系统崩溃。
授权规则
有些消费者无权限调用部分请求,需要加入黑名单
有些服务只能被部分消费者使用,需要加入白名单
请求路径:
@GetMapping("/authorize/whitenumber")
public String doAuthorizeWhiteNumber(){
return "do Authorize White Number";
}
@GetMapping("/authorize/blacknumber")
public String doAuthorizeBlackNumber(){
return "do Authorize black number";
}
规则定制:
@Component
public class SentinelAuthorizeConfig implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest request) {
String origin = request.getParameter("origin");
return origin;
}
}
实际请求为:/consumer/sentinel/authorize/blacknumber?orign=app2 这里放这个就是告诉各位看官老爷,需要一个orgin参数
黑名单:
两个都访问不了。
白名单:
只有app1可以访问。
Sentinel自定义异常
@Component
public class ServiceBlockExceptionConfig implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("text/html;charset=UTF-8");
Map<String,Object> map = new HashMap<>();
if(e instanceof DegradeException){
map.put("status",601);
map.put("message", "服务被熔断了!");
}
else if(e instanceof FlowException){
map.put("status",602);
map.put("message", "服务被限流了!");
}
else{
map.put("status",603);
map.put("message",
"Blocked by Sentinel (flow limiting)");
}
String jsonStr=new ObjectMapper().writeValueAsString(map);
PrintWriter out = httpServletResponse.getWriter();
out.println(jsonStr);
out.flush();
}
}
Sentinel持久化处理
依赖添加
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
yml文件配置
sentinel:
datasource:
ds:
nacos:
server-addr: localhost:8848
group-id: DEFAULT_GROUP
rule-type: flow
data-id: nacos-consumer
data-type: json
sentinel先连接nacos,通过DEFAULT_GROUP 与文件名称nacos-consumer 找到类型为json字符串,将规则获取。
nacos配置中心配置规则
[
{
"resource": "/consumer/sentinel/direct",
"controlBehavior": 0,
"count": 1.0,
"grade": 1,
"limitApp": "default",
"strategy": 0
}
]
存的时候存取该资源,限流的控制效果为快速失败,阈值为1,根据QPS进行控制,调用关系为直接限流。 此种方式的存储地址为:\studynacos\data\config-data\DEFAULT_GROUP 下的nacos-consumer文件
名词解释:
- resource:资源名,即限流规则的作用对象
- limitApp:流控针对的调用来源,若为 default 则不区分调用来源
- grade:限流阈值类型(QPS 或并发线程数);0 代表根据并发数量来限流,1 代表根据 QPS 来进行流量控制
- count:限流阈值
- strategy:调用关系限流策略(直接限流,关联限流,)
- controlBehavior:流量控制效果(0快速失败、1Warm Up、2匀速排队)
- clusterMode:是否为集群模式
|