它从开始阈值到最大QPS阈值会有一个缓冲阶段,一开始的阈值是最大QPS阈值的1/3,然后慢慢.增长,直到最大阈值,适用于将突然增大的流量转换为缓步增长的场景。
设置阈值为 10,预热时间是 5 秒,逐渐增加到阈值上限,所以会有一个初始阈值
初始阈值 = 阈值上限 / coldFactor, coldFactor 是冷加载因子,默认为3
上面这个配置的效果就是:在 10 秒内最大阈值是 2(10/codeFactor),超过5秒,最大阈值为6
开始10秒内每秒访问2次限流,或者十秒后每秒访问6次限流
让请求以均匀的速度通过,单机阈值为每秒通过数量,其余的排队等待; 它还会让设置一个超时时间,当请求超过超时间时间还未处理,则会被丢弃。
排队等待方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。
注意:匀速排队,让请求以匀速通过,阈值类型必须设置为QPS,否则无效,匀速排队模式暂时不支持 QPS > 1000 的场景
当阈值设为 2 的时候,则代表一秒匀速的通过 2 个请求,也就是每个请求平均间隔恒定为 1000 / 2 = 500 ms
,每一个请求的最长等待时间(maxQueueingTimeMs
)为 1s 。
降级规则就是设置当满足什么条件的时候,对服务进行降级。Sentinel提供了三个衡量条件:
l 平均响应时间 :当资源的平均响应时间超过阈值(以 ms 为单位)之后,资源进入准降级状态。如果接下来 1s 内持续进入 5 个请求,它们的 RT都持续超过这个阈值,那么在接下的时间窗口(以 s 为单位)之内,就会对这个方法进行服务降级。
表示 : 规定每个请求最大的时间是50ms超过这个时间就认为是慢调用
慢调用的比例大于等于0.5(最小的请求时2 慢调用/总调用) 的时候熔断 , 熔断时长 1s
RT:平均响应时间 (DEGRADE_GRADE_RT);当 1s 内持续进入 5 个请求,对应时刻的平均响应时间(秒级)均超过阈值(count,以 ms 为单位),那么在接下来的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地熔断(抛出 DegradeException)。
注意 Sentinel 默认统计的 RT 上限是 4900 ms,超出此阈值的都会算作 4900 ms
若需要 变更此上限可以通过启动配置项 -Dcsp.sentinel.statistic.max.rt=xxx 来配置
创建测试类
访问页面 熔断时间内无法访问
创建测试类
多次访问第一个参数
添加例外项
访问haha不限流
很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源 访问控制的功能。来源访问控制根据资源的请求来源(origin)限制资源是否通过: 若配置白名单,则只有请求来源位于白名单内时才可通过; 若配置黑名单,则请求来源位于黑名单时不通过,其余的请求通过
创建测试类
package com.example.config; import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; @Component public class MyRequestOriginParser implements RequestOriginParser { @Override public String parseOrigin(HttpServletRequest request) { // 解析来源 //定义 流控的应用的参数的名字是 servicename String servicename = request.getParameter("servicename"); return servicename; } }
当servicename=test时才能访问成功
添加到nacos里面
1)在配置文件application中添加以下内容
spring.cloud.sentinel.datasource.ds1.nacos.data-id=${spring.application.name} spring.cloud.sentinel.datasource.ds1.nacos.data-type=json spring.cloud.sentinel.datasource.ds1.nacos.server-addr=localhost:8848 spring.cloud.sentinel.datasource.ds1.nacos.group-id=DEFAULT_GROUP spring.cloud.sentinel.datasource.ds1.nacos.rule-type=flow
2)在nacos中为cloudalibaba-sentinel-service(可以在配置文件自定义)服务添加对应配置。
[ { "resource": "/rateLimit/customerBlockHandler",#/rateLimit/customerBlockHandler "limitApp": "default", "grade": 1, "count": 1, "strategy": 0, "controlBehavior": 0, "clusterMode": false } ]
resource: 资源名称;
imitApp: 来源应用;
grade: 阈值类型,0表示线程数,1表示QPS;
count: 单机阈值;
strategy: 流控模式,0表示直接,1表示关联,2表示链路;
controlBehavior: 流控效果,0表示快速失败,1表示。Warm Up,2表示排队等待。
clusterMode: 是否集群。
使用文件
package com.pro.config; import com.alibaba.csp.sentinel.command.handler.ModifyParamFlowRulesCommandHandler; import com.alibaba.csp.sentinel.datasource.*; import com.alibaba.csp.sentinel.init.InitFunc; import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule; import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule; import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager; import com.alibaba.csp.sentinel.slots.system.SystemRule; import com.alibaba.csp.sentinel.slots.system.SystemRuleManager; import com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import org.springframework.beans.factory.annotation.Value; import java.io.File; import java.io.IOException; import java.util.List; public class FilePersistence implements InitFunc { @Value("${spring.application.name}") private String appcationName; @Override public void init() throws Exception { String ruleDir = System.getProperty("user.home") + "/sentinel-rules/" + appcationName; String flowRulePath = ruleDir + "/flow-rule.json"; String degradeRulePath = ruleDir + "/degrade-rule.json"; String systemRulePath = ruleDir + "/system-rule.json"; String authorityRulePath = ruleDir + "/authority-rule.json"; String paramFlowRulePath = ruleDir + "/param-flow-rule.json"; this.mkdirIfNotExits(ruleDir); this.createFileIfNotExits(flowRulePath); this.createFileIfNotExits(degradeRulePath); this.createFileIfNotExits(systemRulePath); this.createFileIfNotExits(authorityRulePath); this.createFileIfNotExits(paramFlowRulePath); // 流控规则 ReadableDataSource> flowRuleRDS = new FileRefreshableDataSource<>( flowRulePath, flowRuleListParser ); FlowRuleManager.register2Property(flowRuleRDS.getProperty()); WritableDataSource > flowRuleWDS = new FileWritableDataSource<>( flowRulePath, this::encodeJson ); WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS); // 降级规则 ReadableDataSource
> degradeRuleRDS = new FileRefreshableDataSource<>( degradeRulePath, degradeRuleListParser ); DegradeRuleManager.register2Property(degradeRuleRDS.getProperty()); WritableDataSource > degradeRuleWDS = new FileWritableDataSource<>( degradeRulePath, this::encodeJson ); WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS); // 系统规则 ReadableDataSource
> systemRuleRDS = new FileRefreshableDataSource<>( systemRulePath, systemRuleListParser ); SystemRuleManager.register2Property(systemRuleRDS.getProperty()); WritableDataSource > systemRuleWDS = new FileWritableDataSource<>( systemRulePath, this::encodeJson ); WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS); // 授权规则 ReadableDataSource
> authorityRuleRDS = new FileRefreshableDataSource<>( authorityRulePath, authorityRuleListParser ); AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty()); WritableDataSource > authorityRuleWDS = new FileWritableDataSource<>( authorityRulePath, this::encodeJson ); WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS); // 热点参数规则 ReadableDataSource
> paramFlowRuleRDS = new FileRefreshableDataSource<>( paramFlowRulePath, paramFlowRuleListParser ); ParamFlowRuleManager.register2Property(paramFlowRuleRDS.getProperty()); WritableDataSource > paramFlowRuleWDS = new FileWritableDataSource<>( paramFlowRulePath, this::encodeJson ); ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWDS); } private Converter
> flowRuleListParser = source -> JSON.parseObject( source, new TypeReference >() { } ); private Converter
> degradeRuleListParser = source -> JSON.parseObject( source, new TypeReference >() { } ); private Converter
> systemRuleListParser = source -> JSON.parseObject( source, new TypeReference >() { } ); private Converter
> authorityRuleListParser = source -> JSON.parseObject( source, new TypeReference >() { } ); private Converter
> paramFlowRuleListParser = source -> JSON.parseObject( source, new TypeReference >() { } ); private void mkdirIfNotExits(String filePath) throws IOException { File file = new File(filePath); if (!file.exists()) { file.mkdirs(); } } private void createFileIfNotExits(String filePath) throws IOException { File file = new File(filePath); if (!file.exists()) { file.createNewFile(); } } private
String encodeJson(T t) { return JSON.toJSONString(t); } }
将这个配置文件使用
在对应的微服务下面的resources里面创建一个目录
META-INF/services
并在目录下面写一个文件
com.alibaba.csp.sentinel.init.InitFunc
文件里面写的是刚才的配置类的包名加类名 :com.pro.config.FilePersistence
配置完成后 重启规则不再消失