|
@@ -15,16 +15,6 @@ |
|
|
*/ |
|
|
*/ |
|
|
package com.alibaba.csp.sentinel.slots.block.flow; |
|
|
package com.alibaba.csp.sentinel.slots.block.flow; |
|
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
|
import java.util.Collections; |
|
|
|
|
|
import java.util.Comparator; |
|
|
|
|
|
import java.util.HashSet; |
|
|
|
|
|
import java.util.List; |
|
|
|
|
|
import java.util.Map; |
|
|
|
|
|
import java.util.Map.Entry; |
|
|
|
|
|
import java.util.Set; |
|
|
|
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
|
|
|
|
|
|
|
|
import com.alibaba.csp.sentinel.log.RecordLog; |
|
|
import com.alibaba.csp.sentinel.log.RecordLog; |
|
|
import com.alibaba.csp.sentinel.slots.block.ClusterRuleConstant; |
|
|
import com.alibaba.csp.sentinel.slots.block.ClusterRuleConstant; |
|
|
import com.alibaba.csp.sentinel.slots.block.RuleConstant; |
|
|
import com.alibaba.csp.sentinel.slots.block.RuleConstant; |
|
@@ -36,6 +26,10 @@ import com.alibaba.csp.sentinel.util.StringUtil; |
|
|
import com.alibaba.csp.sentinel.util.function.Function; |
|
|
import com.alibaba.csp.sentinel.util.function.Function; |
|
|
import com.alibaba.csp.sentinel.util.function.Predicate; |
|
|
import com.alibaba.csp.sentinel.util.function.Predicate; |
|
|
|
|
|
|
|
|
|
|
|
import java.util.*; |
|
|
|
|
|
import java.util.Map.Entry; |
|
|
|
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* @author Eric Zhao |
|
|
* @author Eric Zhao |
|
|
* @since 1.4.0 |
|
|
* @since 1.4.0 |
|
@@ -55,8 +49,8 @@ public final class FlowRuleUtil { |
|
|
/** |
|
|
/** |
|
|
* Build the flow rule map from raw list of flow rules, grouping by resource name. |
|
|
* Build the flow rule map from raw list of flow rules, grouping by resource name. |
|
|
* |
|
|
* |
|
|
* @param list raw list of flow rules |
|
|
|
|
|
* @param filter rule filter |
|
|
|
|
|
|
|
|
* @param list raw list of flow rules |
|
|
|
|
|
* @param filter rule filter |
|
|
* @return constructed new flow rule map; empty map if list is null or empty, or no wanted rules |
|
|
* @return constructed new flow rule map; empty map if list is null or empty, or no wanted rules |
|
|
*/ |
|
|
*/ |
|
|
public static Map<String, List<FlowRule>> buildFlowRuleMap(List<FlowRule> list, Predicate<FlowRule> filter) { |
|
|
public static Map<String, List<FlowRule>> buildFlowRuleMap(List<FlowRule> list, Predicate<FlowRule> filter) { |
|
@@ -66,9 +60,9 @@ public final class FlowRuleUtil { |
|
|
/** |
|
|
/** |
|
|
* Build the flow rule map from raw list of flow rules, grouping by resource name. |
|
|
* Build the flow rule map from raw list of flow rules, grouping by resource name. |
|
|
* |
|
|
* |
|
|
* @param list raw list of flow rules |
|
|
|
|
|
* @param filter rule filter |
|
|
|
|
|
* @param shouldSort whether the rules should be sorted |
|
|
|
|
|
|
|
|
* @param list raw list of flow rules |
|
|
|
|
|
* @param filter rule filter |
|
|
|
|
|
* @param shouldSort whether the rules should be sorted |
|
|
* @return constructed new flow rule map; empty map if list is null or empty, or no wanted rules |
|
|
* @return constructed new flow rule map; empty map if list is null or empty, or no wanted rules |
|
|
*/ |
|
|
*/ |
|
|
public static Map<String, List<FlowRule>> buildFlowRuleMap(List<FlowRule> list, Predicate<FlowRule> filter, |
|
|
public static Map<String, List<FlowRule>> buildFlowRuleMap(List<FlowRule> list, Predicate<FlowRule> filter, |
|
@@ -105,7 +99,6 @@ public final class FlowRuleUtil { |
|
|
if (StringUtil.isBlank(rule.getLimitApp())) { |
|
|
if (StringUtil.isBlank(rule.getLimitApp())) { |
|
|
rule.setLimitApp(RuleConstant.LIMIT_APP_DEFAULT); |
|
|
rule.setLimitApp(RuleConstant.LIMIT_APP_DEFAULT); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
TrafficShapingController rater = generateRater(rule); |
|
|
TrafficShapingController rater = generateRater(rule); |
|
|
rule.setRater(rater); |
|
|
rule.setRater(rater); |
|
|
|
|
|
|
|
@@ -141,12 +134,12 @@ public final class FlowRuleUtil { |
|
|
switch (rule.getControlBehavior()) { |
|
|
switch (rule.getControlBehavior()) { |
|
|
case RuleConstant.CONTROL_BEHAVIOR_WARM_UP: |
|
|
case RuleConstant.CONTROL_BEHAVIOR_WARM_UP: |
|
|
return new WarmUpController(rule.getCount(), rule.getWarmUpPeriodSec(), |
|
|
return new WarmUpController(rule.getCount(), rule.getWarmUpPeriodSec(), |
|
|
ColdFactorProperty.coldFactor); |
|
|
|
|
|
|
|
|
ColdFactorProperty.coldFactor); |
|
|
case RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER: |
|
|
case RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER: |
|
|
return new RateLimiterController(rule.getMaxQueueingTimeMs(), rule.getCount()); |
|
|
return new RateLimiterController(rule.getMaxQueueingTimeMs(), rule.getCount()); |
|
|
case RuleConstant.CONTROL_BEHAVIOR_WARM_UP_RATE_LIMITER: |
|
|
case RuleConstant.CONTROL_BEHAVIOR_WARM_UP_RATE_LIMITER: |
|
|
return new WarmUpRateLimiterController(rule.getCount(), rule.getWarmUpPeriodSec(), |
|
|
return new WarmUpRateLimiterController(rule.getCount(), rule.getWarmUpPeriodSec(), |
|
|
rule.getMaxQueueingTimeMs(), ColdFactorProperty.coldFactor); |
|
|
|
|
|
|
|
|
rule.getMaxQueueingTimeMs(), ColdFactorProperty.coldFactor); |
|
|
case RuleConstant.CONTROL_BEHAVIOR_DEFAULT: |
|
|
case RuleConstant.CONTROL_BEHAVIOR_DEFAULT: |
|
|
default: |
|
|
default: |
|
|
// Default mode or unknown mode: default traffic shaping controller (fast-reject). |
|
|
// Default mode or unknown mode: default traffic shaping controller (fast-reject). |
|
@@ -173,12 +166,42 @@ public final class FlowRuleUtil { |
|
|
*/ |
|
|
*/ |
|
|
public static boolean isValidRule(FlowRule rule) { |
|
|
public static boolean isValidRule(FlowRule rule) { |
|
|
boolean baseValid = rule != null && !StringUtil.isBlank(rule.getResource()) && rule.getCount() >= 0 |
|
|
boolean baseValid = rule != null && !StringUtil.isBlank(rule.getResource()) && rule.getCount() >= 0 |
|
|
&& rule.getGrade() >= 0 && rule.getStrategy() >= 0 && rule.getControlBehavior() >= 0; |
|
|
|
|
|
|
|
|
&& rule.getGrade() >= 0 && rule.getStrategy() >= 0 && rule.getControlBehavior() >= 0; |
|
|
if (!baseValid) { |
|
|
if (!baseValid) { |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
// Check strategy and control (shaping) behavior. |
|
|
|
|
|
return checkClusterField(rule) && checkStrategyField(rule) && checkControlBehaviorField(rule); |
|
|
|
|
|
|
|
|
if (rule.getGrade() == RuleConstant.FLOW_GRADE_QPS) { |
|
|
|
|
|
// Check strategy and control (shaping) behavior. |
|
|
|
|
|
return checkClusterField(rule) && checkStrategyField(rule) && checkControlBehaviorField(rule); |
|
|
|
|
|
} else if (rule.getGrade() == RuleConstant.FLOW_GRADE_THREAD) { |
|
|
|
|
|
return checkClusterConcurrentField(rule); |
|
|
|
|
|
} else { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static boolean checkClusterConcurrentField(/*@NonNull*/ FlowRule rule) { |
|
|
|
|
|
if (!rule.isClusterMode()) { |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
ClusterFlowConfig clusterConfig = rule.getClusterConfig(); |
|
|
|
|
|
if (clusterConfig == null) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
if (clusterConfig.getClientOfflineTime() <= 0 || clusterConfig.getResourceTimeout() <= 0) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (clusterConfig.getAcquireRefuseStrategy() < 0 || clusterConfig.getResourceTimeoutStrategy() < 0) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!validClusterRuleId(clusterConfig.getFlowId())) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return isWindowConfigValid(clusterConfig.getSampleCount(), clusterConfig.getWindowIntervalMs()); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private static boolean checkClusterField(/*@NonNull*/ FlowRule rule) { |
|
|
private static boolean checkClusterField(/*@NonNull*/ FlowRule rule) { |
|
@@ -234,5 +257,6 @@ public final class FlowRuleUtil { |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
private FlowRuleUtil() {} |
|
|
|
|
|
|
|
|
private FlowRuleUtil() { |
|
|
|
|
|
} |
|
|
} |
|
|
} |