Add highestCpuUsage in system rule.
Signed-off-by: Carpenter Lee <hooleeucas@163.com>
This commit is contained in:
parent
b4422407ae
commit
5279895581
|
|
@ -34,6 +34,7 @@ import com.alibaba.csp.sentinel.slots.block.AbstractRule;
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author jialiang.linjl
|
* @author jialiang.linjl
|
||||||
|
* @author Carpenter Lee
|
||||||
* @see SystemRuleManager
|
* @see SystemRuleManager
|
||||||
*/
|
*/
|
||||||
public class SystemRule extends AbstractRule {
|
public class SystemRule extends AbstractRule {
|
||||||
|
|
@ -42,6 +43,10 @@ public class SystemRule extends AbstractRule {
|
||||||
* negative value means no threshold checking.
|
* negative value means no threshold checking.
|
||||||
*/
|
*/
|
||||||
private double highestSystemLoad = -1;
|
private double highestSystemLoad = -1;
|
||||||
|
/**
|
||||||
|
* cpu usage, between [0, 1]
|
||||||
|
*/
|
||||||
|
private double highestCpuUsage = -1;
|
||||||
private double qps = -1;
|
private double qps = -1;
|
||||||
private long avgRt = -1;
|
private long avgRt = -1;
|
||||||
private long maxThread = -1;
|
private long maxThread = -1;
|
||||||
|
|
@ -110,6 +115,24 @@ public class SystemRule extends AbstractRule {
|
||||||
this.highestSystemLoad = 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
|
@Override
|
||||||
public boolean passCheck(Context context, DefaultNode node, int count, Object... args) {
|
public boolean passCheck(Context context, DefaultNode node, int count, Object... args) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -132,6 +155,9 @@ public class SystemRule extends AbstractRule {
|
||||||
if (Double.compare(that.highestSystemLoad, highestSystemLoad) != 0) {
|
if (Double.compare(that.highestSystemLoad, highestSystemLoad) != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (Double.compare(that.highestCpuUsage, highestCpuUsage) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (Double.compare(that.qps, qps) != 0) {
|
if (Double.compare(that.qps, qps) != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -150,6 +176,9 @@ public class SystemRule extends AbstractRule {
|
||||||
temp = Double.doubleToLongBits(highestSystemLoad);
|
temp = Double.doubleToLongBits(highestSystemLoad);
|
||||||
result = 31 * result + (int)(temp ^ (temp >>> 32));
|
result = 31 * result + (int)(temp ^ (temp >>> 32));
|
||||||
|
|
||||||
|
temp = Double.doubleToLongBits(highestCpuUsage);
|
||||||
|
result = 31 * result + (int)(temp ^ (temp >>> 32));
|
||||||
|
|
||||||
temp = Double.doubleToLongBits(qps);
|
temp = Double.doubleToLongBits(qps);
|
||||||
result = 31 * result + (int)(temp ^ (temp >>> 32));
|
result = 31 * result + (int)(temp ^ (temp >>> 32));
|
||||||
|
|
||||||
|
|
@ -162,6 +191,7 @@ public class SystemRule extends AbstractRule {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SystemRule{" +
|
return "SystemRule{" +
|
||||||
"highestSystemLoad=" + highestSystemLoad +
|
"highestSystemLoad=" + highestSystemLoad +
|
||||||
|
", highestCpuUsage=" + highestCpuUsage +
|
||||||
", qps=" + qps +
|
", qps=" + qps +
|
||||||
", avgRt=" + avgRt +
|
", avgRt=" + avgRt +
|
||||||
", maxThread=" + maxThread +
|
", maxThread=" + maxThread +
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,10 @@ import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||||
public class SystemRuleManager {
|
public class SystemRuleManager {
|
||||||
|
|
||||||
private static volatile double highestSystemLoad = Double.MAX_VALUE;
|
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 double qps = Double.MAX_VALUE;
|
||||||
private static volatile long maxRt = Long.MAX_VALUE;
|
private static volatile long maxRt = Long.MAX_VALUE;
|
||||||
private static volatile long maxThread = 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.
|
* mark whether the threshold are set by user.
|
||||||
*/
|
*/
|
||||||
private static volatile boolean highestSystemLoadIsSet = false;
|
private static volatile boolean highestSystemLoadIsSet = false;
|
||||||
|
private static volatile boolean highestCpuUsageIsSet = false;
|
||||||
private static volatile boolean qpsIsSet = false;
|
private static volatile boolean qpsIsSet = false;
|
||||||
private static volatile boolean maxRtIsSet = false;
|
private static volatile boolean maxRtIsSet = false;
|
||||||
private static volatile boolean maxThreadIsSet = false;
|
private static volatile boolean maxThreadIsSet = false;
|
||||||
|
|
@ -134,6 +139,12 @@ public class SystemRuleManager {
|
||||||
result.add(loadRule);
|
result.add(loadRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (highestCpuUsageIsSet) {
|
||||||
|
SystemRule rule = new SystemRule();
|
||||||
|
rule.setHighestCpuUsage(highestCpuUsage);
|
||||||
|
result.add(rule);
|
||||||
|
}
|
||||||
|
|
||||||
if (maxRtIsSet) {
|
if (maxRtIsSet) {
|
||||||
SystemRule rtRule = new SystemRule();
|
SystemRule rtRule = new SystemRule();
|
||||||
rtRule.setAvgRt(maxRt);
|
rtRule.setAvgRt(maxRt);
|
||||||
|
|
@ -185,9 +196,18 @@ public class SystemRuleManager {
|
||||||
checkSystemStatus.set(false);
|
checkSystemStatus.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RecordLog.info(String.format("[SystemRuleManager] Current system check status: %s, "
|
||||||
RecordLog.info(String.format("[SystemRuleManager] Current system check status: %s, highestSystemLoad: "
|
+ "highestSystemLoad: %e, "
|
||||||
+ highestSystemLoad + ", " + "maxRt: %d, maxThread: %d, maxQps: " + qps, checkSystemStatus.get(), maxRt, maxThread));
|
+ "highestCpuUsage: %e, "
|
||||||
|
+ "maxRt: %d, "
|
||||||
|
+ "maxThread: %d, "
|
||||||
|
+ "maxQps: %e",
|
||||||
|
checkSystemStatus.get(),
|
||||||
|
highestSystemLoad,
|
||||||
|
highestCpuUsage,
|
||||||
|
maxRt,
|
||||||
|
maxThread,
|
||||||
|
qps));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void restoreSetting() {
|
protected void restoreSetting() {
|
||||||
|
|
@ -195,6 +215,7 @@ public class SystemRuleManager {
|
||||||
|
|
||||||
// should restore changes
|
// should restore changes
|
||||||
highestSystemLoad = Double.MAX_VALUE;
|
highestSystemLoad = Double.MAX_VALUE;
|
||||||
|
highestCpuUsage = Double.MAX_VALUE;
|
||||||
maxRt = Long.MAX_VALUE;
|
maxRt = Long.MAX_VALUE;
|
||||||
maxThread = Long.MAX_VALUE;
|
maxThread = Long.MAX_VALUE;
|
||||||
qps = Double.MAX_VALUE;
|
qps = Double.MAX_VALUE;
|
||||||
|
|
@ -229,6 +250,12 @@ public class SystemRuleManager {
|
||||||
checkStatus = true;
|
checkStatus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rule.getHighestCpuUsage() >= 0) {
|
||||||
|
highestCpuUsage = Math.min(highestCpuUsage, rule.getHighestCpuUsage());
|
||||||
|
highestCpuUsageIsSet = true;
|
||||||
|
checkStatus = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (rule.getAvgRt() >= 0) {
|
if (rule.getAvgRt() >= 0) {
|
||||||
maxRt = Math.min(maxRt, rule.getAvgRt());
|
maxRt = Math.min(maxRt, rule.getAvgRt());
|
||||||
maxRtIsSet = true;
|
maxRtIsSet = true;
|
||||||
|
|
@ -284,17 +311,34 @@ public class SystemRuleManager {
|
||||||
throw new SystemBlockException(resourceWrapper.getName(), "rt");
|
throw new SystemBlockException(resourceWrapper.getName(), "rt");
|
||||||
}
|
}
|
||||||
|
|
||||||
// BBR algorithm.
|
// load. BBR algorithm.
|
||||||
if (highestSystemLoadIsSet && getCurrentSystemAvgLoad() > highestSystemLoad) {
|
if (highestSystemLoadIsSet && getCurrentSystemAvgLoad() > highestSystemLoad) {
|
||||||
if (currentThread > 1 &&
|
if (!checkBbr(currentThread)) {
|
||||||
currentThread > Constants.ENTRY_NODE.maxSuccessQps() * Constants.ENTRY_NODE.minRt() / 1000) {
|
|
||||||
throw new SystemBlockException(resourceWrapper.getName(), "load");
|
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() {
|
public static double getCurrentSystemAvgLoad() {
|
||||||
return statusListener.getSystemAverageLoad();
|
return statusListener.getSystemAverageLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static double getCurrentCpuUsage() {
|
||||||
|
return statusListener.getCpuUsage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,12 @@
|
||||||
package com.alibaba.csp.sentinel.slots.system;
|
package com.alibaba.csp.sentinel.slots.system;
|
||||||
|
|
||||||
import java.lang.management.ManagementFactory;
|
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.log.RecordLog;
|
||||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||||
import com.alibaba.csp.sentinel.Constants;
|
|
||||||
|
import com.sun.management.OperatingSystemMXBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author jialiang.linjl
|
* @author jialiang.linjl
|
||||||
|
|
@ -28,6 +29,7 @@ import com.alibaba.csp.sentinel.Constants;
|
||||||
public class SystemStatusListener implements Runnable {
|
public class SystemStatusListener implements Runnable {
|
||||||
|
|
||||||
volatile double currentLoad = -1;
|
volatile double currentLoad = -1;
|
||||||
|
volatile double currentCpuUsage = -1;
|
||||||
|
|
||||||
volatile String reason = StringUtil.EMPTY;
|
volatile String reason = StringUtil.EMPTY;
|
||||||
|
|
||||||
|
|
@ -37,6 +39,10 @@ public class SystemStatusListener implements Runnable {
|
||||||
return currentLoad;
|
return currentLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getCpuUsage() {
|
||||||
|
return currentCpuUsage;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
|
@ -44,13 +50,22 @@ public class SystemStatusListener implements Runnable {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// system average load
|
OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
|
||||||
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
|
currentLoad = osBean.getSystemLoadAverage();
|
||||||
currentLoad = operatingSystemMXBean.getSystemLoadAverage();
|
/**
|
||||||
|
* Java Doc copied from {@link OperatingSystemMXBean#getSystemCpuLoad()}:</br>
|
||||||
|
* 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();
|
StringBuilder sb = new StringBuilder();
|
||||||
if (currentLoad > SystemRuleManager.getHighestSystemLoad()) {
|
if (currentLoad > SystemRuleManager.getHighestSystemLoad()) {
|
||||||
sb.append("load:").append(currentLoad).append(";");
|
sb.append("load:").append(currentLoad).append(";");
|
||||||
|
sb.append("cpu:").append(currentCpuUsage).append(";");
|
||||||
sb.append("qps:").append(Constants.ENTRY_NODE.passQps()).append(";");
|
sb.append("qps:").append(Constants.ENTRY_NODE.passQps()).append(";");
|
||||||
sb.append("rt:").append(Constants.ENTRY_NODE.avgRt()).append(";");
|
sb.append("rt:").append(Constants.ENTRY_NODE.avgRt()).append(";");
|
||||||
sb.append("thread:").append(Constants.ENTRY_NODE.curThreadNum()).append(";");
|
sb.append("thread:").append(Constants.ENTRY_NODE.curThreadNum()).append(";");
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,8 @@ public class SystemGuardDemo {
|
||||||
SystemRule rule = new SystemRule();
|
SystemRule rule = new SystemRule();
|
||||||
// max load is 3
|
// max load is 3
|
||||||
rule.setHighestSystemLoad(3.0);
|
rule.setHighestSystemLoad(3.0);
|
||||||
|
// max cpu usage is 60%
|
||||||
|
rule.setHighestCpuUsage(0.6);
|
||||||
// max avg rt of all request is 10 ms
|
// max avg rt of all request is 10 ms
|
||||||
rule.setAvgRt(10);
|
rule.setAvgRt(10);
|
||||||
// max total qps is 20
|
// max total qps is 20
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue