分布式系统的流量防卫兵
又是一个Alibaba出现的技术,该技术与Hystrix作用是一致的。
目的监控保护我们的微服务
需要自己搭建一个监控平台。
没有一套web界面可以进行更方便的配置。
单独一个组件,不需要单独在搭建了
可以直接在界面画的统一配置
https://github.com/alibaba/Sentinel/releases
通过官网Github下载。可以看到是一个jar文件
前台就是控制台,后台对应核心库
执行jar文件打开控制台
默认端口是8080
和Tomcat默认一致,哈哈不知道为什么。
因为Nacos和Sentinel是不需要我们自己搭建的。所以可以先去启动
该模块注册到Nacos中,并被Sentinel进行监控管理
<dependencies>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cspgroupId>
<artifactId>sentinel-datasource-nacosartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>cn.hutoolgroupId>
<artifactId>hutool-allartifactId>
<version>4.6.3version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
server:
port: 8401
spring:
application:
name: cloudalibaba-sentinel-service
cloud:
nacos:
discovery:
#Nacos服务注册中心地址
server-addr: localhost:8848
sentinel:
transport:
#配置Sentinel dashboard地址
dashboard: localhost:8080
#默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
port: 8719
#这里表示暴漏端点 实在 配置中心的时候用到的
management:
endpoints:
web:
exposure:
include: '*'
@SpringBootApplication
//表示开启 发现客户端
@EnableDiscoveryClient
public class CloudMain {
public static void main(String[] args) {
SpringApplication.run(CloudMain.class,args);
}
}
@Controller
public class ControllerOne {
@RequestMapping("showOne")
@ResponseBody
public String showOne(){
return "showOne";
}
}
看到Sentinel并没有展示到服务
Sentinel采用的是懒加载,只有当服务第一次执行的时候才会被加载
懒加载
这个哨兵控制台看着可真舒服
表示对于流量的控制
添加流控规则可以在这两个地方进行添加
在这里可以看到该服务下存在哪些 发送过的 请求
并可以添加流控
该图可以看到在添加流控的时候可以进行 阈值类型 流控模式 流控效果 等
当阈值类型是QPS可以存在流控效果。线程数阈值类型不存在流控效果
表示该请求只能1秒1次
QPS:表示每秒的访问数量
上面设定每秒1 次 超出就给给出提示错误。
在我们添加流量控制的时候,可以看到 阈值类型存在一个线程数
表示
每打开一个浏览器就表示一个新的线程
线程数控制表示,此时之后一个线程在工作。如果多个在一起抢占式。就会给出中止
如果等待另一个结束,我在执行,就可以避免。
当关联的资源达到阈值,就关闭当前
当关联资源/testB的qps阀值超过1时,就限流/testA的Rest访问地址,当关联资源到阈值后限制配置好的资源名
演示就自行演示吧
**场景: 我订单系统 请求过多 那么我就在前台限流。自然订单就会变少 **
实际上,链路的控制指的就是对一条链路的访问进行控制。
a
/ \
b c
/ | | \
d e f g
a->b->d, a->b->e, a->c->f, a->c->g均可视作链路。
假设我以a为入口资源,d为终点资源,对这条链路进行限制的话,则资源a,b,d均会被限制访问。
指定的请求达到阈值,该请求进行限流
很直接就是一旦阈值就失败就行了
平时访问是很少,某个点突然变高
需求: 默认 coldFactor 为 3,即请求QPS从(threshold / 3) 开始,经多少预热时长才逐渐升至设定的 QPS 阈值。
案例,阀值为10+预热时长设置5秒。
系统初始化的阀值为10 / 3 约等于3,即阀值刚开始为3;然后过了5秒后阀值才慢慢升高恢复到10
匀速排队,让请求以均匀的速度通过,阀值类型必须设成QPS,否则无效。
设置含义:/testA每秒1次请求,超过的话就排队等待,等待的超时时间为20000毫秒。
随着Sentinel的版本提升,会进行这个页面的升级。
在使用的时候自己根据规则测试一下就好了
配置这些都是规则,满足了就开启断路器(这已开启,加下来请求就无法正常执行。)
达到一定约定时间或规则 就会进行关闭。之后再次满足异常条件还是会开启
降级于Hystrix的断路器概念很像
Hystrix:当服务的错误比例超过约定。进行开启。之后无论是否正确都进行降级操作。直到错误比例恢复正常。
降级规则:设定的规则更加灵活
平均响应时间 超出阈值 且 在时间窗口内通过的请求>=5,两个条件同时满足后触发降级
窗口期过后关闭断路器
RT最大4900(更大的需要通过-Dcsp.sentinel.statistic.max.rt=XXXX才能生效)
QPS >= 5 且异常比例(秒级统计)超过阈值时,触发降级;时间窗口结束后,关闭降级
异常数(分钟统计)超过阈值时,触发降级;时间窗口结束后,关闭降级
热点即经常访问的数据,很多时候我们希望统计或者限制某个热点数据中访问频次最高的TopN数据,并对其访问进行限流或者其它操作
热点指的就是请求中参数 对请求中指定的参数添加条件 进行限流
前面的异常页面都是Sentinel提供的。Hystrix存在一个保底方法。下面就介绍**@SentinelResource()**
// 表示发送该请求
@RequestMapping("/hotTest")
// 这里value表示将这个请求取一个资源名字
// blockHandler指定异常的兜底方法
@SentinelResource(value = "hotTest",blockHandler = "hotTestBlock")
// 这里表示参数可以添加可以添加
@ResponseBody
public String hotTest(@RequestParam(name = "one",required = false)String one,
@RequestParam(name = "two",required = false)String two ){
return "success";
}
public String hotTestBlock(String one, String two, BlockException exception){
//系统默认异常页面 换成该页面
return "error";
}
参数索引从0开始
在我们设置热点规则的时候,发现下方还存在一个高级的设置
该设置表示对于参数值的配置
参数类型:8中基本数据类型+String
参数值=多少的时候。阈值改变的配置。
这里就是自己测一测就明白了
前面的限制条件,都是针对具体的一个请求。
现在出现一个可以通过系统规则进行一个整体的配置规则
当总请求达到一个条件进行限制
这个注解可以说是来自Hystrix的复制版本
@RequestMapping("testDiyError")
@SentinelResource(value = "test",blockHandlerClass = DiyError.class,blockHandler = "error01")
@ResponseBody
public String TestDiyError(){
return "success";
}
public class DiyError {
public static String error01(BlockException exception){
return "自定义的异常处理";
}
}
这里设定的是test指定的是
@SentinelResource指定的资源名字。
我试过直接指定请求路径会匹配不上去哦
我们现在可以再Sentinel中客户端直接进行配置。
还可以使用代码来代替我们的配置,但是当然还是配置更加方便
感兴趣可以去了解。但是应该不实用
注意版本,不同版本的使用都有小差别
@SentinelResource注解最主要的两个用法:限流控制和熔断降级的具体使用案例介绍完了。另外,该注解还有一些其他更精细化的配置,比如忽略某些异常的配置、默认降级函数等等,具体可见如下说明:
value:资源名称,必需项(不能为空)
entryType:entry类型,可选项(默认为 EntryType.OUT)
fallback:fallback函数名称,可选项,用于在抛出异常的时候提供 fallback处理逻辑。fallback函数可以针对所有类型的异常(除了exceptionsToIgnore里面排除掉的异常类型)进行处理。fallback函数签名和位置要求: 返回值类型必须与原函数返回值类型一致;方法参数列表需要和原函数一致,或者可以额外多一个 Throwable类型的参数用于接收对应的异常。
fallback函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass为对应的类的 Class 对象,注意对应的函数必需为 static函数,否则无法解析。 defaultFallback(since 1.6.0):默认的 fallback函数名称,可选项,通常用于通用的 fallback逻辑(即可以用于很多服务或方法)。默认 fallback函数可以针对所有类型的异常(除了exceptionsToIgnore里面排除掉的异常类型)进行处理。若同时配置了 fallback和 defaultFallback,则只有 fallback会生效。defaultFallback函数签名要求:返回值类型必须与原函数返回值类型一致;
方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
defaultFallback函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
在我们Hystrix中,我们设定规则是代码出现java异常的时候,给出应急方案。
在Sentinel中同样可以实现
@SentinelResource(value = "test",fallback = "fall",blockHandler = "block")
那么调用blockHandler的处理异常方法
@SentinelResource(value = "test",fallback = "fall",blockHandler = "block",exceptionsToIgnore = {})
在这里指定异常的数组。
表示即使出现该异常,我也不会做降级处理。
当我们在关闭微服务的时候在重启的时候,我们的sentinel中针对该服务配置的规则。就可能被清除。
重启服务就会清除Sentinel中的配置过该服务的规则
com.alibaba.csp
sentinel-datasource-nacos
spring:
application:
name: cloudalibaba-sentinel-service
cloud:
nacos:
discovery:
#Nacos服务注册中心地址
server-addr: localhost:8848
sentinel:
#############################################
datasource:
ds1:
# 这里指定nacos
nacos:
server-addr: localhost:8848
dataId: test
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow
###################################
transport:
#配置Sentinel dashboard地址
dashboard: localhost:8080
#默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
port: 8719
对应添加到Nacos配置文件中
[
{
"resource": "/testOne",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
resource:资源名称;
limitApp:来源应用;
grade:阈值类型,0表示线程数,1表示QPS;
count:单机阈值;
strategy:流控模式,0表示直接,1表示关联,2表示链路;
controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待;
clusterMode:是否集群。
也就是说将微服连接Nacos。
微服务在连接Sntinel。在开启Sentinel的时候读取linux中写号的内容即可。
每次加一个规则就写一个