赞
踩
https://gitee.com/zh_0209_java/springcloud-alibaba.git
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 具有以下特征:
Sentinel-dashboard
Sentinel-dashboard 是Sentinel 的web可视化界面
下载地址
现在的最新版本为1.8.2,那我们就下载1.8.2
下载到本地后,可以使用cmd进入黑窗口,启动sentinel-dashboard-1.8.2.jar
,
启动完成后浏览器访问 localhost:8080 ,这是sentinel-dashboard 的默认端口,注意不要产生端口冲突,
默认账号和密码都是 sentinel
自此sentinel-dashboard 安装成功
<dependencies> <!--SpringCloud alibaba Nacos--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--SpringCloud alibaba sentinel-datasource-nacos 后续做持久化用到的依赖--> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency> <!--SpringCloud alibaba 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-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </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 # 默认9719端口,假如被占用会自动从8719开始依次+1扫描,直至找到违背占用的端口 port: 8719 # 暴露监控端点 management: endpoints: web: exposure: include: '*'
@SpringBootApplication
@EnableDiscoveryClient
public class SentinelApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelApplication.class,args);
}
}
@RestController
public class SentinelController {
@GetMapping("/testA")
public String testA(){
return "=====testA";
}
@GetMapping("/testB")
public String testB(){
return "=====testB";
}
}
sentinel-dashnoard
说明:
QPS (每秒的请求数量)
: 当调用该api的QPS达到阈值的时候,进行限流线程数
:当调用该API 的线程数达到阈值的时候,进行限流直接
: API达到限流条件时,直接限流关联
: 当关联的资源达到阈值时,就限流自己链路
:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【API级别的针对】快速失败
:直接失败,抛出异常Warm Up
: 根据codeFactor (冷加载因子,默认3)的值,从阈值/codeFactor, 经过预热时长,才达到设置的QPS阈值排队等待
: 匀速排队,让请求以均匀的速度通过,阈值类型必须设置为QPS, 否则无效关联
测试发现最开始快速访问 /testB,会抛出异常,慢慢的经过5秒后,当每秒访问不超过10QPS时,就不会抛出异常
Sentinel 提供以下几种熔断策略:
何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效
@GetMapping("/testHotKey")
// /testHotKey 代表rest地址,testHotKey 代表资源名,要唯一
@SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")
public String testHotKey(@RequestParam(value = "p1",required = false) String p1,@RequestParam(value = "p2",required = false) String p2){
return " test 测试 -》 testHotKey"+ "p1 ->"+p1+",p2 ->" +p2;
}
public String deal_testHotKey(String p1, String p2, BlockException exception){
// sentinel 系统的默认提示: Blocked by Sentintel (flow limiting)
// 这里等于是指定了/testHotKey 接口的默认提示
return " test 测试 -》 deal_testHotKey"+ "p1 ->"+p1+",p2 ->" +p2;
}
参数索引: 代表该资源的入参的第一个参数,是p1
单机阈值:携带该参数访问的阈值
统计时长:对设置规则的统计时长
如上图设置的热点规则就是在1秒内 访问 testHotKey 资源 携带参数索引为0(也就是第一个参数p1)的访问次数的阈值为1,超过阈值就会跳转到@SentinelResource注解中blockHandler 指定的方法中
访问测试,当参数p1的值不等于5的时候,阈值仍然是1,但当p1的值为5时,阈值到了199.
注意,参数类型只能是基本类型和String.
当代码发生运行时异常时,会直接抛出异常,而不会进入@SentinelResource
注解中blockHandler 指定的方法中,因为@SentinelResource
注解管的是sentinel控制台流控的错误。
@SentinelResource
主管配置出错,运行时出错该走异常走异常。
Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量(EntryType.IN),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。
系统规则支持以下的模式:
系统规则就相当于是整个系统入口的流控,比如这里设置的是入口QPS为1,那么访问该系统的所有请求的总QPS不能超过1
他的作用根Hystrix 中的@HystrixCommand 差不多
现在的问题,使用@SentinelResource
注解中的blockHandler 来做兜底方法,发现和代码耦合度太高,并且每一个方法都要写的话太多。
解决办法,新建自定义异常处理类
/** * @Description: 自定义全局异常处理 * @ClassName MyBlockHandler * @date: 2021.07.29 16:21 * @Author: zhanghang */ public class MyBlockHandler { /** * description: 自定义兜底方法 ,必须是静态方法,返回值必须和业务方法一致 * date: 2021年-07月-29日 16:22 * author: zhanghang * * @param exception * @return java.lang.String */ public static String blockMethod(BlockException exception){ return "-----统一异常处理--blockMethod"; } }
@SentinelResource使用
@GetMapping("/globalBlockHandler")
// /testHotKey 代表rest地址,testHotKey 代表资源名,要唯一
@SentinelResource(value = "testHotKey", // 指定资源名
blockHandlerClass = MyBlockHandler.class, // 指定兜底方法的类
blockHandler = "blockMethod") // 指定兜底方法
public String globalBlockHandler(){
return " test 测试 -》 globalBlockHandler";
}
经过测试发现,兜底方法可以调到自定义类里面的方法,兜底方法和业务方法彻底耦合。
注意:1, 兜底方法的返回值必须和业务方法的返回值一致,2,兜底方法必须是静态的
注意:注解方式埋点不支持 private 方法。
@SentinelResource
用于定义资源,并提供可选的异常处理和 fallback 配置项。 @SentinelResource
注解包含以下属性:
// exceptionsToIgnore 的意思就是忽略指定的异常,当报出IllEgalArgumentException异常不调用fallback兜底方法,没有降级效果了
@SentinelResource(exceptionsToIgnore = {IllEgalArgumentException.class})
问题:一旦重启服务应用,sentinel规则将消失,生产环境需要将配置规则进行持久化
效果:
将限流配置规则持久化进Nacos保存,只要刷新8401某个rest地址,sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对8401上sentinel上的流控规则持续有效
<!--SpringCloud alibaba sentinel-datasource-nacos 后续做持久化用到的依赖-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
server: port: 8402 spring: application: name: cloudalibaba-sentinel-service cloud: nacos: discovery: # Nacos 服务注册中心地址 server-addr: localhost:8848 sentinel: transport: # 配置sentinel dashboard 地址 dashboard: localhost:8080 # 默认9719端口,假如被占用会自动从8719开始依次+1扫描,直至找到违背占用的端口 port: 8719 datasource: ds1: nacos: server-addr: localhost:8848 # nacos注册地址 dataId: cloudalibaba-sentinel-service # dataId,也就是nacos配置规则的dataId groupId: DEFAULT_GROUP # nacos配置规则的groupId # namespace: public # nacos 的命名空间 data-type: json # nacos配置规则的数据类型 rule-type: flow # 暴露监控端点 management: endpoints: web: exposure: include: '*'
[
{
"resource":"/testA",
"limitApp":"default",
"grade":1,
"count":1,
"strategy":0,
"controlBehavior":0,
"clusterMode":false
}
]
重启服务,访问/testA ,发现sentinel规则已经持久化上去
可能出现的问题,我在配置的时候持久化不生效,原因为我的java版本有问题,当我使用idea新建一个项目,使用默认版本时就可以了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。