Spring-Clould-Alibaba-sentinel控制台
什么是sentinel
sentinel是阿里开源的项目,提供了流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性。
使用sentinel
-
下载sentinel控制台服务器
下载地址 链接 -
使用控制台
在jar目录当中打开控制台,输入java -jar sentinel-dashboard-1.7.0.jar
例:指定端口为8088 并且监控sentinel本身
java -dserver.port=8088 -dcsp.sentinel.dashboard.server=localhost:8088
-jar sentinel-dashboard-1.7.0.jar
在浏览器当中输入localhost:8088
用户名和密码为sentinel
- 添加依赖
<dependency> <groupid>com.alibaba.cloud</groupid> <artifactid>spring-cloud-starter-alibaba-sentinel</artifactid> </dependency>
- 添加配置
sentinel: transport: dashboard: localhost:8088
启动服务访问 :http://localhost:8000/getgoodswithid/1
查看控制台
sentinel功能介绍
资源名称,访问的路径,唯一名称** 针对来源:
- 可以针对调用者进行限流
- 假设两个微服务a和b调用,可以对a和b单独的设置限流规则
- default为不区别来源
阈值类型:
- qps 当调用api的qps达到阈值时,就去做限流
- 线程数
- 流控(限流) 当调用api的线程数达到一定的域值时就去做限流
设置阈值 一秒种超过一次时, 就会触发限流
流控模式:直接
流控模式:关联
当联的资源达到域值时, 限流自己
查询接口调用过快, 如果影响修改接口,或者修改接口影响查询接口, 根据业务需求,来进行关联限流
示例:
- 在控制台关联访问路径
- 在代码编写方法
@requestmapping("/test") public void test(){ system.out.println("test-------"); } public static void main(string[] args) throws interruptedexception { for (int i=0;i<1000;i++){ resttemplate resttemplate = new resttemplate(); resttemplate.getforobject("http://localhost:8000/test",object.class); thread.sleep(500); } }
- 启动main方法 执行test方法,getgoods因为设置了关联,就会被限流
- 链路:指定资源从入口资源进来的流量,如果达到阈值,就开启限流
流控效果
- 快速失败:直接失败,抛出异常信息
- warm up:
根据codefactor从设置的阈值除以codefactor,经过预热时长,才到达设置的qps阈值 假设设置的阈值为90
那么就会90/3(默认) 30 作为最初的阈值 ,预热指定的时长 才去达到90的值限流
- 排队等待
匀速排队,让请求以均匀的速度通过,阈值类型必须设置成qps,否则无效 超过了定义的时长, 就会抛出异常
代码配置
- 引入依赖
<dependency> <groupid>com.alibaba.csp</groupid> <artifactid>sentinel-core</artifactid> <version>1.7.0</version> </dependency>
- 定义资源名称
private static final string getgoods_key = "getmygoods";
- 定义限流规则
private static final string getgoods_key = "getmygoods"; @requestmapping("/initflowrules") public void initflowrules(){ list<flowrule> rules = new arraylist<>(); flowrule rule = new flowrule(); //设置资源名称 rule.setresource(getgoods_key); //设置针对来源 rule.setlimitapp("default"); //设置阈值类型 rule.setgrade(ruleconstant.flow_grade_qps); // 设置阈值 rule.setcount(1); rules.add(rule); flowrulemanager.loadrules(rules); }
- 应用到被限流的接口上
@requestmapping("/getmygoods") public string getmygoods(){ try (entry entry = sphu.entry(getgoods_key)) { // 被保护的逻辑 return "getmygoods"; } catch (blockexception ex) { // 处理被流控的逻辑 return "被限流了"; } }
启动运行 首先执行 initflowrules 方法开启限流
http://localhost:8000/initflowrules
然后执行http://localhost:8000/getmygoods
当刷新次数超过一秒一次的时候就会被限流
但是每次启动都需要先访问开启initflowrules方法,所以要设置服务启动时开启限流
- 自动执行流控代码
使用springboot自带的applicationrunner接口
使用方式,实现applicationrunner接口,在run方法当中执行流控代码
- 使用注解改进代码
- sentinel 支持通过 @sentinelresource 注解定义资源并配置 blockhandler
- 和 fallback 函数来进行限流之后的处理
- blockhandler 函数会在原方法被限流/降级/系统保护的时候调用
- fallback 函数会针对所有类型的异常
private static final string get_goods_key = "getmygoods"; @sentinelresource(value = get_goods_key,blockhandler = "blockhandlermethod") @requestmapping("/getmygoods") public string getmygoods(){ return "getmygoods"; } public string blockhandlermethod(blockexception e){ e.printstacktrace(); return "被限流了---"; }
降级
降级策略:
rt:
- 平均响应时间 (degrade_grade_rt):当 1s 内持续进入 5 个请求,
- 对应时刻的平均响应时间(秒级)均超过阈值(count,以 ms 为单位)
- 那么在接下的时间窗口之内,对这个方法的调用都会自动地熔断
异常比例:
- 当资源的每秒请求量 >= 5,并且每秒异常总数占通过量的比值超过阈值(degraderule 中的 count)之后
- 资源进入降级状态
异常次数:
- 当资源近 1 分钟的异常数目超过阈值之后会进行熔断。
- 注意由于统计时间窗口是分钟级别的,若 timewindow 小于 60s,则结束熔断状态后仍可能再进入熔断状态。
热点规则
指定索引参数,如果在时间窗口内超过了指定的阈值,就会触发熔断
参数例外项 可以对指定的参数再进行设置限流 参数级别
对指定的参数限流,甚至对指定参数的值进行限流
注意事项 :
参数必须是基本数据类型或string类型
系统规则
- 和其他的规则不太一样,它是针对应用来设的
- 前面设置的都是争对某一个资源。某一个方法来设置的
阈值类型
- load load是负载,只有在linux机器上才会生效。根据当前系统的负载来决定是不是触发保护。
- rt 这个应用上所有的流量的平均的响应时间,所有服务的平均响应时间超过一个值,那么我就停止接收新的请求,
- 线程数 所有服务访问的线程数加起来
- 入口qps 所有服务的qps加起来达到一个值
- cpu使用率 cpu的使用率超过一个百分比
发生以上这些情况的时候把你整个应用给你断掉。所有服务都不提供了
授权规则
使用授权时要先指定来源,对指定来源的内容进行限流
指定来源方式
新建配置类
@component public class requestorigin implements requestoriginparser { @override public string parseorigin(httpservletrequest httpservletrequest) { //从请求参数中获取origin的参数并返回 string origin = httpservletrequest.getparameter("origin"); //如果获取不到origin 就抛出异常 if (stringutils.isblank(origin)){ throw new illegalargumentexception("必须指定origin"); } //有参数就返回 return origin; } }
指定降级
sentinel整合feign
- 开启feign与sentinel集成
feign: sentinel: enabled: true
- 创建一个类实现服务goodsfeignclient接口
@component public class goodsfeignclientfalback implements goodsfeignclient { @override public object getgoods() { return responseresult.error("goodsfeignfallback服务器正在维护,请稍后重试--"); } @override public responseresult getgoodswithid(integer id) { return responseresult.error("goodsfeignfallback服务器正在维护,请稍后重试--"); } @override public responseresult getgoodsobj(goods goods) { return responseresult.error("goodsfeignfallback服务器正在维护,请稍后重试--"); } }
- 在goodsfeignclient接口
feignclient(name = "goods-provide",fallback = goodsfeignclientfalback.class)
正常访问
设置流控
刷新多次
规则持久化
使用nacos配置中心实现规则持久化
- 在nacos配置中心当中添加配置josn规则
- 添加依赖
<!--添加此依赖,项目一启动时, 就去到nacos当中读取配置中心--> <dependency> <groupid>com.alibaba.csp</groupid> <artifactid>sentinel-datasource-nacos</artifactid> <version>1.7.0</version> </dependency>
- 在配置文件当中添加sentinel读取nacos地址
eager: true datasource: ds: nacos: server-addr: localhost:8849 group-id: default_group rule-type: flow data-id: getgoods data-type: json
启动 读取nacos的流控规则
使用ahas实现规则持久化
-
选择公网
勾选java、sdk、springboot
- 添加依赖
- 去除sentinel的部分依赖 避免冲突
<dependency> <groupid>com.alibaba.cloud</groupid> <artifactid>spring-cloud-starter-alibaba-sentinel</artifactid> <exclusions> <exclusion> <groupid>com.alibaba.csp</groupid> <artifactid>sentinel-transport-simple-http</artifactid> </exclusion> </exclusions> </dependency>
访问一次服务后 看ahas控制台
和本地的sintinel一样的操作