diff --git a/pom.xml b/pom.xml
index 6fcba990af..f2ca3d4d9f 100755
--- a/pom.xml
+++ b/pom.xml
@@ -50,8 +50,8 @@
UTF-8
- 1.6
- 1.6
+ 1.7
+ 1.7
UTF-8
3.8.0
2.22.1
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRule.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRule.java
index 318f6bef17..7a2ac333c5 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRule.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRule.java
@@ -34,6 +34,7 @@
*
*
* @author jialiang.linjl
+ * @author Carpenter Lee
* @see SystemRuleManager
*/
public class SystemRule extends AbstractRule {
@@ -42,6 +43,10 @@ public class SystemRule extends AbstractRule {
* negative value means no threshold checking.
*/
private double highestSystemLoad = -1;
+ /**
+ * cpu usage, between [0, 1]
+ */
+ private double highestCpuUsage = -1;
private double qps = -1;
private long avgRt = -1;
private long maxThread = -1;
@@ -110,6 +115,24 @@ public void setHighestSystemLoad(double highestSystemLoad) {
this.highestSystemLoad = highestSystemLoad;
}
+ /**
+ * Get highest cpu usage. Cpu usage is between [0, 1]
+ *
+ * @return highest cpu usage
+ */
+ public double getHighestCpuUsage() {
+ return highestCpuUsage;
+ }
+
+ /**
+ * set highest cpu usage. Cpu usage is between [0, 1]
+ *
+ * @param highestCpuUsage the value to set.
+ */
+ public void setHighestCpuUsage(double highestCpuUsage) {
+ this.highestCpuUsage = highestCpuUsage;
+ }
+
@Override
public boolean passCheck(Context context, DefaultNode node, int count, Object... args) {
return true;
@@ -132,6 +155,9 @@ public boolean equals(Object o) {
if (Double.compare(that.highestSystemLoad, highestSystemLoad) != 0) {
return false;
}
+ if (Double.compare(that.highestCpuUsage, highestCpuUsage) != 0) {
+ return false;
+ }
if (Double.compare(that.qps, qps) != 0) {
return false;
@@ -150,6 +176,9 @@ public int hashCode() {
temp = Double.doubleToLongBits(highestSystemLoad);
result = 31 * result + (int)(temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(highestCpuUsage);
+ result = 31 * result + (int)(temp ^ (temp >>> 32));
+
temp = Double.doubleToLongBits(qps);
result = 31 * result + (int)(temp ^ (temp >>> 32));
@@ -162,6 +191,7 @@ public int hashCode() {
public String toString() {
return "SystemRule{" +
"highestSystemLoad=" + highestSystemLoad +
+ ", highestCpuUsage=" + highestCpuUsage +
", qps=" + qps +
", avgRt=" + avgRt +
", maxThread=" + maxThread +
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRuleManager.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRuleManager.java
index f25155a100..2e2fe635a6 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRuleManager.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRuleManager.java
@@ -66,6 +66,10 @@
public class SystemRuleManager {
private static volatile double highestSystemLoad = Double.MAX_VALUE;
+ /**
+ * cpu usage, between [0, 1]
+ */
+ private static volatile double highestCpuUsage = Double.MAX_VALUE;
private static volatile double qps = Double.MAX_VALUE;
private static volatile long maxRt = Long.MAX_VALUE;
private static volatile long maxThread = Long.MAX_VALUE;
@@ -73,6 +77,7 @@ public class SystemRuleManager {
* mark whether the threshold are set by user.
*/
private static volatile boolean highestSystemLoadIsSet = false;
+ private static volatile boolean highestCpuUsageIsSet = false;
private static volatile boolean qpsIsSet = false;
private static volatile boolean maxRtIsSet = false;
private static volatile boolean maxThreadIsSet = false;
@@ -134,6 +139,12 @@ public static List getRules() {
result.add(loadRule);
}
+ if (highestCpuUsageIsSet) {
+ SystemRule rule = new SystemRule();
+ rule.setHighestCpuUsage(highestCpuUsage);
+ result.add(rule);
+ }
+
if (maxRtIsSet) {
SystemRule rtRule = new SystemRule();
rtRule.setAvgRt(maxRt);
@@ -185,9 +196,18 @@ public void configUpdate(List rules) {
checkSystemStatus.set(false);
}
-
- RecordLog.info(String.format("[SystemRuleManager] Current system check status: %s, highestSystemLoad: "
- + highestSystemLoad + ", " + "maxRt: %d, maxThread: %d, maxQps: " + qps, checkSystemStatus.get(), maxRt, maxThread));
+ RecordLog.info(String.format("[SystemRuleManager] Current system check status: %s, "
+ + "highestSystemLoad: %e, "
+ + "highestCpuUsage: %e, "
+ + "maxRt: %d, "
+ + "maxThread: %d, "
+ + "maxQps: %e",
+ checkSystemStatus.get(),
+ highestSystemLoad,
+ highestCpuUsage,
+ maxRt,
+ maxThread,
+ qps));
}
protected void restoreSetting() {
@@ -195,6 +215,7 @@ protected void restoreSetting() {
// should restore changes
highestSystemLoad = Double.MAX_VALUE;
+ highestCpuUsage = Double.MAX_VALUE;
maxRt = Long.MAX_VALUE;
maxThread = Long.MAX_VALUE;
qps = Double.MAX_VALUE;
@@ -229,6 +250,12 @@ public static void loadSystemConf(SystemRule rule) {
checkStatus = true;
}
+ if (rule.getHighestCpuUsage() >= 0) {
+ highestCpuUsage = Math.min(highestCpuUsage, rule.getHighestCpuUsage());
+ highestCpuUsageIsSet = true;
+ checkStatus = true;
+ }
+
if (rule.getAvgRt() >= 0) {
maxRt = Math.min(maxRt, rule.getAvgRt());
maxRtIsSet = true;
@@ -284,17 +311,34 @@ public static void checkSystem(ResourceWrapper resourceWrapper) throws BlockExce
throw new SystemBlockException(resourceWrapper.getName(), "rt");
}
- // BBR algorithm.
+ // load. BBR algorithm.
if (highestSystemLoadIsSet && getCurrentSystemAvgLoad() > highestSystemLoad) {
- if (currentThread > 1 &&
- currentThread > Constants.ENTRY_NODE.maxSuccessQps() * Constants.ENTRY_NODE.minRt() / 1000) {
+ if (!checkBbr(currentThread)) {
throw new SystemBlockException(resourceWrapper.getName(), "load");
}
}
+ // cpu usage
+ if (highestCpuUsageIsSet && getCurrentCpuUsage() > highestCpuUsage) {
+ if (!checkBbr(currentThread)) {
+ throw new SystemBlockException(resourceWrapper.getName(), "cpu");
+ }
+ }
+ }
+
+ private static boolean checkBbr(int currentThread) {
+ if (currentThread > 1 &&
+ currentThread > Constants.ENTRY_NODE.maxSuccessQps() * Constants.ENTRY_NODE.minRt() / 1000) {
+ return false;
+ }
+ return true;
}
public static double getCurrentSystemAvgLoad() {
return statusListener.getSystemAverageLoad();
}
+
+ public static double getCurrentCpuUsage() {
+ return statusListener.getCpuUsage();
+ }
}
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemStatusListener.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemStatusListener.java
index 2ccf6c633a..8cf45a37c6 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemStatusListener.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemStatusListener.java
@@ -16,11 +16,12 @@
package com.alibaba.csp.sentinel.slots.system;
import java.lang.management.ManagementFactory;
-import java.lang.management.OperatingSystemMXBean;
+import com.alibaba.csp.sentinel.Constants;
import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.util.StringUtil;
-import com.alibaba.csp.sentinel.Constants;
+
+import com.sun.management.OperatingSystemMXBean;
/**
* @author jialiang.linjl
@@ -28,6 +29,7 @@
public class SystemStatusListener implements Runnable {
volatile double currentLoad = -1;
+ volatile double currentCpuUsage = -1;
volatile String reason = StringUtil.EMPTY;
@@ -37,6 +39,10 @@ public double getSystemAverageLoad() {
return currentLoad;
}
+ public double getCpuUsage() {
+ return currentCpuUsage;
+ }
+
@Override
public void run() {
try {
@@ -44,13 +50,22 @@ public void run() {
return;
}
- // system average load
- OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
- currentLoad = operatingSystemMXBean.getSystemLoadAverage();
+ OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
+ currentLoad = osBean.getSystemLoadAverage();
+ /**
+ * Java Doc copied from {@link OperatingSystemMXBean#getSystemCpuLoad()}:
+ * Returns the "recent cpu usage" for the whole system. This value is a double in the [0.0,1.0] interval.
+ * A value of 0.0 means that all CPUs were idle during the recent period of time observed, while a value
+ * of 1.0 means that all CPUs were actively running 100% of the time during the recent period being
+ * observed. All values betweens 0.0 and 1.0 are possible depending of the activities going on in the
+ * system. If the system recent cpu usage is not available, the method returns a negative value.
+ */
+ currentCpuUsage = osBean.getSystemCpuLoad();
StringBuilder sb = new StringBuilder();
if (currentLoad > SystemRuleManager.getHighestSystemLoad()) {
sb.append("load:").append(currentLoad).append(";");
+ sb.append("cpu:").append(currentCpuUsage).append(";");
sb.append("qps:").append(Constants.ENTRY_NODE.passQps()).append(";");
sb.append("rt:").append(Constants.ENTRY_NODE.avgRt()).append(";");
sb.append("thread:").append(Constants.ENTRY_NODE.curThreadNum()).append(";");
diff --git a/sentinel-demo/sentinel-demo-basic/src/main/java/com/alibaba/csp/sentinel/demo/system/SystemGuardDemo.java b/sentinel-demo/sentinel-demo-basic/src/main/java/com/alibaba/csp/sentinel/demo/system/SystemGuardDemo.java
index ac8706c47c..f0e1ddffcb 100755
--- a/sentinel-demo/sentinel-demo-basic/src/main/java/com/alibaba/csp/sentinel/demo/system/SystemGuardDemo.java
+++ b/sentinel-demo/sentinel-demo-basic/src/main/java/com/alibaba/csp/sentinel/demo/system/SystemGuardDemo.java
@@ -91,6 +91,8 @@ private static void initSystemRule() {
SystemRule rule = new SystemRule();
// max load is 3
rule.setHighestSystemLoad(3.0);
+ // max cpu usage is 60%
+ rule.setHighestCpuUsage(0.6);
// max avg rt of all request is 10 ms
rule.setAvgRt(10);
// max total qps is 20