dashboard: Refactor degrade service/controller and adapt to new features
Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
parent
8643dac943
commit
5334f51d21
|
|
@ -22,40 +22,46 @@ import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
|
|||
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
|
||||
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
|
||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
|
||||
import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.circuitbreaker.CircuitBreakerStrategy;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
|
||||
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
||||
import com.alibaba.csp.sentinel.dashboard.repository.rule.InMemDegradeRuleStore;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author leyou
|
||||
* Controller regarding APIs of degrade rules. Refactored since 1.8.0.
|
||||
*
|
||||
* @author Carpenter Lee
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping(value = "/degrade", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@RestController
|
||||
@RequestMapping("/degrade")
|
||||
public class DegradeController {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(DegradeController.class);
|
||||
|
||||
@Autowired
|
||||
private InMemDegradeRuleStore repository;
|
||||
private RuleRepository<DegradeRuleEntity, Long> repository;
|
||||
@Autowired
|
||||
private SentinelApiClient sentinelApiClient;
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/rules.json")
|
||||
@GetMapping("/rules.json")
|
||||
@AuthAction(PrivilegeType.READ_RULE)
|
||||
public Result<List<DegradeRuleEntity>> queryMachineRules(String app, String ip, Integer port) {
|
||||
|
||||
public Result<List<DegradeRuleEntity>> apiQueryMachineRules(String app, String ip, Integer port) {
|
||||
if (StringUtil.isEmpty(app)) {
|
||||
return Result.ofFail(-1, "app can't be null or empty");
|
||||
}
|
||||
|
|
@ -75,117 +81,65 @@ public class DegradeController {
|
|||
}
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/new.json")
|
||||
@PostMapping("/rule")
|
||||
@AuthAction(PrivilegeType.WRITE_RULE)
|
||||
public Result<DegradeRuleEntity> add(String app, String ip, Integer port, String limitApp, String resource,
|
||||
Double count, Integer timeWindow, Integer grade) {
|
||||
if (StringUtil.isBlank(app)) {
|
||||
return Result.ofFail(-1, "app can't be null or empty");
|
||||
public Result<DegradeRuleEntity> apiAddRule(@RequestBody DegradeRuleEntity entity) {
|
||||
Result<DegradeRuleEntity> checkResult = checkEntityInternal(entity);
|
||||
if (checkResult != null) {
|
||||
return checkResult;
|
||||
}
|
||||
if (StringUtil.isBlank(ip)) {
|
||||
return Result.ofFail(-1, "ip can't be null or empty");
|
||||
}
|
||||
if (port == null) {
|
||||
return Result.ofFail(-1, "port can't be null");
|
||||
}
|
||||
if (StringUtil.isBlank(limitApp)) {
|
||||
return Result.ofFail(-1, "limitApp can't be null or empty");
|
||||
}
|
||||
if (StringUtil.isBlank(resource)) {
|
||||
return Result.ofFail(-1, "resource can't be null or empty");
|
||||
}
|
||||
if (count == null) {
|
||||
return Result.ofFail(-1, "count can't be null");
|
||||
}
|
||||
if (timeWindow == null) {
|
||||
return Result.ofFail(-1, "timeWindow can't be null");
|
||||
}
|
||||
if (grade == null) {
|
||||
return Result.ofFail(-1, "grade can't be null");
|
||||
}
|
||||
if (grade < RuleConstant.DEGRADE_GRADE_RT || grade > RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT) {
|
||||
return Result.ofFail(-1, "Invalid grade: " + grade);
|
||||
}
|
||||
DegradeRuleEntity entity = new DegradeRuleEntity();
|
||||
entity.setApp(app.trim());
|
||||
entity.setIp(ip.trim());
|
||||
entity.setPort(port);
|
||||
entity.setLimitApp(limitApp.trim());
|
||||
entity.setResource(resource.trim());
|
||||
entity.setCount(count);
|
||||
entity.setTimeWindow(timeWindow);
|
||||
entity.setGrade(grade);
|
||||
Date date = new Date();
|
||||
entity.setGmtCreate(date);
|
||||
entity.setGmtModified(date);
|
||||
try {
|
||||
entity = repository.save(entity);
|
||||
} catch (Throwable throwable) {
|
||||
logger.error("add error:", throwable);
|
||||
return Result.ofThrowable(-1, throwable);
|
||||
}
|
||||
if (!publishRules(app, ip, port)) {
|
||||
logger.info("publish degrade rules fail after rule add");
|
||||
}
|
||||
return Result.ofSuccess(entity);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/save.json")
|
||||
@AuthAction(PrivilegeType.WRITE_RULE)
|
||||
public Result<DegradeRuleEntity> updateIfNotNull(Long id, String app, String limitApp, String resource,
|
||||
Double count, Integer timeWindow, Integer grade) {
|
||||
if (id == null) {
|
||||
return Result.ofFail(-1, "id can't be null");
|
||||
}
|
||||
if (grade != null) {
|
||||
if (grade < RuleConstant.DEGRADE_GRADE_RT || grade > RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT) {
|
||||
return Result.ofFail(-1, "Invalid grade: " + grade);
|
||||
}
|
||||
}
|
||||
DegradeRuleEntity entity = repository.findById(id);
|
||||
if (entity == null) {
|
||||
return Result.ofFail(-1, "id " + id + " dose not exist");
|
||||
}
|
||||
|
||||
if (StringUtil.isNotBlank(app)) {
|
||||
entity.setApp(app.trim());
|
||||
}
|
||||
|
||||
if (StringUtil.isNotBlank(limitApp)) {
|
||||
entity.setLimitApp(limitApp.trim());
|
||||
}
|
||||
if (StringUtil.isNotBlank(resource)) {
|
||||
entity.setResource(resource.trim());
|
||||
}
|
||||
if (count != null) {
|
||||
entity.setCount(count);
|
||||
}
|
||||
if (timeWindow != null) {
|
||||
entity.setTimeWindow(timeWindow);
|
||||
}
|
||||
if (grade != null) {
|
||||
entity.setGrade(grade);
|
||||
}
|
||||
Date date = new Date();
|
||||
entity.setGmtModified(date);
|
||||
try {
|
||||
entity = repository.save(entity);
|
||||
} catch (Throwable throwable) {
|
||||
logger.error("save error:", throwable);
|
||||
return Result.ofThrowable(-1, throwable);
|
||||
} catch (Throwable t) {
|
||||
logger.error("Failed to add new degrade rule, app={}, ip={}", entity.getApp(), entity.getIp(), t);
|
||||
return Result.ofThrowable(-1, t);
|
||||
}
|
||||
if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {
|
||||
logger.info("publish degrade rules fail after rule update");
|
||||
logger.warn("Publish degrade rules failed, app={}", entity.getApp());
|
||||
}
|
||||
return Result.ofSuccess(entity);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/delete.json")
|
||||
@PutMapping("/rule/{id}")
|
||||
@AuthAction(PrivilegeType.WRITE_RULE)
|
||||
public Result<DegradeRuleEntity> apiUpdateRule(@PathVariable("id") Long id,
|
||||
@RequestBody DegradeRuleEntity entity) {
|
||||
if (id == null || id <= 0) {
|
||||
return Result.ofFail(-1, "id can't be null or negative");
|
||||
}
|
||||
DegradeRuleEntity oldEntity = repository.findById(id);
|
||||
if (oldEntity == null) {
|
||||
return Result.ofFail(-1, "Degrade rule does not exist, id=" + id);
|
||||
}
|
||||
entity.setApp(oldEntity.getApp());
|
||||
entity.setIp(oldEntity.getIp());
|
||||
entity.setPort(oldEntity.getPort());
|
||||
entity.setId(oldEntity.getId());
|
||||
Result<DegradeRuleEntity> checkResult = checkEntityInternal(entity);
|
||||
if (checkResult != null) {
|
||||
return checkResult;
|
||||
}
|
||||
|
||||
entity.setGmtCreate(oldEntity.getGmtCreate());
|
||||
entity.setGmtModified(new Date());
|
||||
try {
|
||||
entity = repository.save(entity);
|
||||
} catch (Throwable t) {
|
||||
logger.error("Failed to save degrade rule, id={}, rule={}", id, entity, t);
|
||||
return Result.ofThrowable(-1, t);
|
||||
}
|
||||
if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {
|
||||
logger.warn("Publish degrade rules failed, app={}", entity.getApp());
|
||||
}
|
||||
return Result.ofSuccess(entity);
|
||||
}
|
||||
|
||||
@DeleteMapping("/rule/{id}")
|
||||
@AuthAction(PrivilegeType.DELETE_RULE)
|
||||
public Result<Long> delete(Long id) {
|
||||
public Result<Long> delete(@PathVariable("id") Long id) {
|
||||
if (id == null) {
|
||||
return Result.ofFail(-1, "id can't be null");
|
||||
}
|
||||
|
|
@ -198,11 +152,11 @@ public class DegradeController {
|
|||
try {
|
||||
repository.delete(id);
|
||||
} catch (Throwable throwable) {
|
||||
logger.error("delete error:", throwable);
|
||||
logger.error("Failed to delete degrade rule, id={}", id, throwable);
|
||||
return Result.ofThrowable(-1, throwable);
|
||||
}
|
||||
if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {
|
||||
logger.info("publish degrade rules fail after rule delete");
|
||||
logger.warn("Publish degrade rules failed, app={}", oldEntity.getApp());
|
||||
}
|
||||
return Result.ofSuccess(id);
|
||||
}
|
||||
|
|
@ -211,4 +165,57 @@ public class DegradeController {
|
|||
List<DegradeRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
|
||||
return sentinelApiClient.setDegradeRuleOfMachine(app, ip, port, rules);
|
||||
}
|
||||
|
||||
private <R> Result<R> checkEntityInternal(DegradeRuleEntity entity) {
|
||||
if (StringUtil.isBlank(entity.getApp())) {
|
||||
return Result.ofFail(-1, "app can't be blank");
|
||||
}
|
||||
if (StringUtil.isBlank(entity.getIp())) {
|
||||
return Result.ofFail(-1, "ip can't be null or empty");
|
||||
}
|
||||
if (entity.getPort() == null || entity.getPort() <= 0) {
|
||||
return Result.ofFail(-1, "invalid port: " + entity.getPort());
|
||||
}
|
||||
if (StringUtil.isBlank(entity.getLimitApp())) {
|
||||
return Result.ofFail(-1, "limitApp can't be null or empty");
|
||||
}
|
||||
if (StringUtil.isBlank(entity.getResource())) {
|
||||
return Result.ofFail(-1, "resource can't be null or empty");
|
||||
}
|
||||
Double threshold = entity.getCount();
|
||||
if (threshold == null || threshold < 0) {
|
||||
return Result.ofFail(-1, "invalid threshold: " + threshold);
|
||||
}
|
||||
Integer recoveryTimeoutSec = entity.getTimeWindow();
|
||||
if (recoveryTimeoutSec == null || recoveryTimeoutSec <= 0) {
|
||||
return Result.ofFail(-1, "recoveryTimeout should be positive");
|
||||
}
|
||||
Integer strategy = entity.getGrade();
|
||||
if (strategy == null) {
|
||||
return Result.ofFail(-1, "circuit breaker strategy cannot be null");
|
||||
}
|
||||
if (strategy < CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType()
|
||||
|| strategy > RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT) {
|
||||
return Result.ofFail(-1, "Invalid circuit breaker strategy: " + strategy);
|
||||
}
|
||||
if (entity.getMinRequestAmount() == null || entity.getMinRequestAmount() <= 0) {
|
||||
return Result.ofFail(-1, "Invalid minRequestAmount");
|
||||
}
|
||||
if (entity.getStatIntervalMs() == null || entity.getStatIntervalMs() <= 0) {
|
||||
return Result.ofFail(-1, "Invalid statInterval");
|
||||
}
|
||||
if (strategy == RuleConstant.DEGRADE_GRADE_RT) {
|
||||
Double slowRatio = entity.getSlowRatioThreshold();
|
||||
if (slowRatio == null) {
|
||||
return Result.ofFail(-1, "SlowRatioThreshold is required for slow request ratio strategy");
|
||||
} else if (slowRatio < 0 || slowRatio > 1) {
|
||||
return Result.ofFail(-1, "SlowRatioThreshold should be in range: [0.0, 1.0]");
|
||||
}
|
||||
} else if (strategy == RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) {
|
||||
if (threshold > 1) {
|
||||
return Result.ofFail(-1, "Ratio threshold should be in range: [0.0, 1.0]");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,18 +23,22 @@ import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
|
|||
* @author leyou
|
||||
*/
|
||||
public class DegradeRuleEntity implements RuleEntity {
|
||||
|
||||
private Long id;
|
||||
private String app;
|
||||
|
||||
private String ip;
|
||||
private Integer port;
|
||||
|
||||
private String resource;
|
||||
private String limitApp;
|
||||
private Double count;
|
||||
private Integer timeWindow;
|
||||
/**
|
||||
* 0 rt 限流; 1为异常;
|
||||
*/
|
||||
private Integer grade;
|
||||
private Integer minRequestAmount;
|
||||
private Double slowRatioThreshold;
|
||||
private Integer statIntervalMs;
|
||||
|
||||
private Date gmtCreate;
|
||||
private Date gmtModified;
|
||||
|
||||
|
|
@ -48,6 +52,9 @@ public class DegradeRuleEntity implements RuleEntity {
|
|||
entity.setCount(rule.getCount());
|
||||
entity.setTimeWindow(rule.getTimeWindow());
|
||||
entity.setGrade(rule.getGrade());
|
||||
entity.setMinRequestAmount(rule.getMinRequestAmount());
|
||||
entity.setSlowRatioThreshold(rule.getSlowRatioThreshold());
|
||||
entity.setStatIntervalMs(rule.getStatIntervalMs());
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
|
@ -128,6 +135,33 @@ public class DegradeRuleEntity implements RuleEntity {
|
|||
this.grade = grade;
|
||||
}
|
||||
|
||||
public Integer getMinRequestAmount() {
|
||||
return minRequestAmount;
|
||||
}
|
||||
|
||||
public DegradeRuleEntity setMinRequestAmount(Integer minRequestAmount) {
|
||||
this.minRequestAmount = minRequestAmount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Double getSlowRatioThreshold() {
|
||||
return slowRatioThreshold;
|
||||
}
|
||||
|
||||
public DegradeRuleEntity setSlowRatioThreshold(Double slowRatioThreshold) {
|
||||
this.slowRatioThreshold = slowRatioThreshold;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Integer getStatIntervalMs() {
|
||||
return statIntervalMs;
|
||||
}
|
||||
|
||||
public DegradeRuleEntity setStatIntervalMs(Integer statIntervalMs) {
|
||||
this.statIntervalMs = statIntervalMs;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getGmtCreate() {
|
||||
return gmtCreate;
|
||||
|
|
@ -153,6 +187,16 @@ public class DegradeRuleEntity implements RuleEntity {
|
|||
rule.setCount(count);
|
||||
rule.setTimeWindow(timeWindow);
|
||||
rule.setGrade(grade);
|
||||
if (minRequestAmount != null) {
|
||||
rule.setMinRequestAmount(minRequestAmount);
|
||||
}
|
||||
if (slowRatioThreshold != null) {
|
||||
rule.setSlowRatioThreshold(slowRatioThreshold);
|
||||
}
|
||||
if (statIntervalMs != null) {
|
||||
rule.setStatIntervalMs(statIntervalMs);
|
||||
}
|
||||
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,9 @@ app.controller('DegradeCtl', ['$scope', '$stateParams', 'DegradeService', 'ngDia
|
|||
app: $scope.app,
|
||||
ip: mac[0],
|
||||
port: mac[1],
|
||||
limitApp: 'default'
|
||||
limitApp: 'default',
|
||||
minRequestAmount: 5,
|
||||
statIntervalMs: 1000,
|
||||
};
|
||||
$scope.degradeRuleDialog = {
|
||||
title: '新增降级规则',
|
||||
|
|
@ -95,7 +97,7 @@ app.controller('DegradeCtl', ['$scope', '$stateParams', 'DegradeService', 'ngDia
|
|||
function parseDegradeMode(grade) {
|
||||
switch (grade) {
|
||||
case 0:
|
||||
return 'RT';
|
||||
return '慢调用比例';
|
||||
case 1:
|
||||
return '异常比例';
|
||||
case 2:
|
||||
|
|
@ -137,7 +139,7 @@ app.controller('DegradeCtl', ['$scope', '$stateParams', 'DegradeService', 'ngDia
|
|||
getMachineRules();
|
||||
confirmDialog.close();
|
||||
} else {
|
||||
alert('失败!');
|
||||
alert('失败:' + data.msg);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
@ -148,7 +150,7 @@ app.controller('DegradeCtl', ['$scope', '$stateParams', 'DegradeService', 'ngDia
|
|||
getMachineRules();
|
||||
degradeRuleDialog.close();
|
||||
} else {
|
||||
alert('失败!');
|
||||
alert('失败:' + data.msg);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
@ -163,7 +165,7 @@ app.controller('DegradeCtl', ['$scope', '$stateParams', 'DegradeService', 'ngDia
|
|||
confirmDialog.close();
|
||||
}
|
||||
} else {
|
||||
alert('失败!');
|
||||
alert('失败:' + data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,6 +132,8 @@ app.controller('IdentityCtl', ['$scope', '$stateParams', 'IdentityService',
|
|||
strategy: 0,
|
||||
resource: resource,
|
||||
limitApp: 'default',
|
||||
minRequestAmount: 5,
|
||||
statIntervalMs: 1000,
|
||||
app: $scope.app,
|
||||
ip: mac[0],
|
||||
port: mac[1]
|
||||
|
|
|
|||
|
|
@ -15,21 +15,10 @@ app.service('DegradeService', ['$http', function ($http) {
|
|||
};
|
||||
|
||||
this.newRule = function (rule) {
|
||||
var param = {
|
||||
id: rule.id,
|
||||
resource: rule.resource,
|
||||
limitApp: rule.limitApp,
|
||||
count: rule.count,
|
||||
timeWindow: rule.timeWindow,
|
||||
grade: rule.grade,
|
||||
app: rule.app,
|
||||
ip: rule.ip,
|
||||
port: rule.port
|
||||
};
|
||||
return $http({
|
||||
url: '/degrade/new.json',
|
||||
params: param,
|
||||
method: 'GET'
|
||||
url: '/degrade/rule',
|
||||
data: rule,
|
||||
method: 'POST'
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -41,24 +30,22 @@ app.service('DegradeService', ['$http', function ($http) {
|
|||
grade: rule.grade,
|
||||
count: rule.count,
|
||||
timeWindow: rule.timeWindow,
|
||||
statIntervalMs: rule.statIntervalMs,
|
||||
minRequestAmount: rule.minRequestAmount,
|
||||
slowRatioThreshold: rule.slowRatioThreshold,
|
||||
};
|
||||
return $http({
|
||||
url: '/degrade/save.json',
|
||||
params: param,
|
||||
method: 'GET'
|
||||
url: '/degrade/rule/' + rule.id,
|
||||
data: param,
|
||||
method: 'PUT'
|
||||
});
|
||||
};
|
||||
|
||||
this.deleteRule = function (rule) {
|
||||
var param = {
|
||||
id: rule.id,
|
||||
app: rule.app
|
||||
};
|
||||
return $http({
|
||||
url: '/degrade/delete.json',
|
||||
params: param,
|
||||
method: 'GET'
|
||||
});
|
||||
return $http({
|
||||
url: '/degrade/rule/' + rule.id,
|
||||
method: 'DELETE'
|
||||
});
|
||||
};
|
||||
|
||||
this.checkRuleValid = function (rule) {
|
||||
|
|
@ -74,8 +61,20 @@ app.service('DegradeService', ['$http', function ($http) {
|
|||
alert('降级阈值不能为空或小于 0');
|
||||
return false;
|
||||
}
|
||||
if (rule.timeWindow === undefined || rule.timeWindow === '' || rule.timeWindow <= 0) {
|
||||
alert('降级时间窗口必须大于 0');
|
||||
if (rule.timeWindow == undefined || rule.timeWindow === '' || rule.timeWindow <= 0) {
|
||||
alert('熔断时长必须大于 0s');
|
||||
return false;
|
||||
}
|
||||
if (rule.minRequestAmount == undefined || rule.minRequestAmount <= 0) {
|
||||
alert('最小请求数目需大于 0');
|
||||
return false;
|
||||
}
|
||||
if (rule.statIntervalMs == undefined || rule.statIntervalMs <= 0) {
|
||||
alert('统计窗口时长需大于 0s');
|
||||
return false;
|
||||
}
|
||||
if (rule.statIntervalMs !== undefined && rule.statIntervalMs > 60 * 1000 * 2) {
|
||||
alert('统计窗口时长不能超过 120 分钟');
|
||||
return false;
|
||||
}
|
||||
// 异常比率类型.
|
||||
|
|
@ -83,6 +82,16 @@ app.service('DegradeService', ['$http', function ($http) {
|
|||
alert('异常比率超出范围:[0.0 - 1.0]');
|
||||
return false;
|
||||
}
|
||||
if (rule.grade == 0) {
|
||||
if (rule.slowRatioThreshold == undefined) {
|
||||
alert('慢调用比率不能为空');
|
||||
return false;
|
||||
}
|
||||
if (rule.slowRatioThreshold < 0 || rule.slowRatioThreshold > 1) {
|
||||
alert('慢调用比率超出范围:[0.0 - 1.0]');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}]);
|
||||
|
|
@ -33,21 +33,15 @@
|
|||
<td style="width: 40%">
|
||||
资源名
|
||||
</td>
|
||||
<!--<td style="width: 10%;">-->
|
||||
<!--降级应用-->
|
||||
<!--</td>-->
|
||||
<td style="width: 10%;">
|
||||
降级模式
|
||||
降级策略
|
||||
</td>
|
||||
<td style="width: 10%;">
|
||||
阈值
|
||||
</td>
|
||||
<td style="width: 10%;">
|
||||
时间窗口(s)
|
||||
熔断时长(s)
|
||||
</td>
|
||||
<!--<td style="width: 8%;">-->
|
||||
<!--状态-->
|
||||
<!--</td>-->
|
||||
<td style="width: 12%;">
|
||||
操作
|
||||
</td>
|
||||
|
|
@ -59,9 +53,9 @@
|
|||
<td style="word-wrap:break-word;word-break:break-all;">{{rule.resource}}</td>
|
||||
<!--<td style="word-wrap:break-word;word-break:break-all;">{{rule.limitApp }}</td>-->
|
||||
<td>
|
||||
<span ng-if="rule.grade == 0">RT</span>
|
||||
<span ng-if="rule.grade == 1" title="秒级异常比例">异常比例</span>
|
||||
<span ng-if="rule.grade == 2" title="分钟级异常数">异常数</span>
|
||||
<span ng-if="rule.grade == 0">慢调用比例</span>
|
||||
<span ng-if="rule.grade == 1" title="异常比例">异常比例</span>
|
||||
<span ng-if="rule.grade == 2" title="异常数">异常数</span>
|
||||
</td>
|
||||
<td style="word-wrap:break-word;word-break:break-all;">
|
||||
{{rule.count}}
|
||||
|
|
|
|||
|
|
@ -22,30 +22,53 @@
|
|||
<!--</div>-->
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label">降级策略</label>
|
||||
<label class="col-sm-2 control-label">熔断策略</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="form-control highlight-border" align="center">
|
||||
<input type="radio" name="grade" value="0" checked ng-model='currentRule.grade' title="秒级平均响应时间" /> RT
|
||||
<input type="radio" name="grade" value="1" ng-model='currentRule.grade' title="秒级异常比例" /> 异常比例
|
||||
<input type="radio" name="grade" value="2" ng-model='currentRule.grade' title="分钟级异常数,仅 1.3.0 及以上版本生效" /> 异常数
|
||||
<input type="radio" name="grade" value="0" checked ng-model='currentRule.grade' title="慢调用比例(1.8.0+ 版本生效)" /> 慢调用比例
|
||||
<input type="radio" name="grade" value="1" ng-model='currentRule.grade' title="异常比例" /> 异常比例
|
||||
<input type="radio" name="grade" value="2" ng-model='currentRule.grade' title="异常数" /> 异常数
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label ng-if="currentRule.grade == 0" class="col-sm-2 control-label">RT</label>
|
||||
<label ng-if="currentRule.grade == 1" class="col-sm-2 control-label">异常比例</label>
|
||||
<label ng-if="currentRule.grade == 0" class="col-sm-2 control-label" title="最大 RT,超过该值则计为慢调用">最大 RT</label>
|
||||
<label ng-if="currentRule.grade == 1" class="col-sm-2 control-label">比例阈值</label>
|
||||
<label ng-if="currentRule.grade == 2" class="col-sm-2 control-label">异常数</label>
|
||||
<div class="col-sm-3">
|
||||
<input type='number' class="form-control highlight-border" ng-model='currentRule.count' ng-if="currentRule.grade == 0" placeholder="毫秒"/>
|
||||
<input type='number' class="form-control highlight-border" ng-model='currentRule.count' ng-if="currentRule.grade == 1" placeholder="0.0~1.0"/>
|
||||
<div class="col-sm-4">
|
||||
<input type='number' class="form-control highlight-border" ng-model='currentRule.count' ng-if="currentRule.grade == 0" placeholder="RT (毫秒)"/>
|
||||
<input type='number' class="form-control highlight-border" ng-model='currentRule.count' ng-if="currentRule.grade == 1" placeholder="取值范围 [0.0,1.0]"/>
|
||||
<input type='number' class="form-control highlight-border" ng-model='currentRule.count' ng-if="currentRule.grade == 2" placeholder="异常数"/>
|
||||
</div>
|
||||
<label class="col-sm-2 control-label">时间窗口</label>
|
||||
<div class="col-sm-4">
|
||||
<input type='number' min="0" class="form-control highlight-border" ng-model='currentRule.timeWindow' placeholder="降级时间间隔, 单位秒" />
|
||||
<div ng-if="currentRule.grade == 0">
|
||||
<label class="col-sm-2 control-label">比例阈值</label>
|
||||
<div class="col-sm-3">
|
||||
<input type='number' min="0" class="form-control highlight-border" ng-model='currentRule.slowRatioThreshold'
|
||||
placeholder="取值 [0.0, 1.0]" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label">熔断时长</label>
|
||||
<div class="col-sm-4">
|
||||
<div class="input-group">
|
||||
<input type='number' min="0" class="form-control highlight-border" ng-model='currentRule.timeWindow'
|
||||
placeholder="熔断时长(s)" />
|
||||
<span class="input-group-addon">s</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label class="col-sm-2 control-label" style="text-align: center; padding-right: 5px;"
|
||||
title="触发熔断的最小请求数目,若当前统计窗口内的请求数小于此值,即使达到熔断条件规则也不会触发">最小请求数</label>
|
||||
<div class="col-sm-3">
|
||||
<input type='number' min="1" class="form-control highlight-border" ng-model='currentRule.minRequestAmount'
|
||||
placeholder="最小请求数目" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<div class="separator"></div>
|
||||
|
|
|
|||
2
sentinel-dashboard/src/main/webapp/resources/dist/js/app.js
vendored
Normal file → Executable file
2
sentinel-dashboard/src/main/webapp/resources/dist/js/app.js
vendored
Normal file → Executable file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -48,7 +48,7 @@ const JS_APP = [
|
|||
'app/scripts/services/appservice.js',
|
||||
'app/scripts/services/flow_service_v1.js',
|
||||
'app/scripts/services/flow_service_v2.js',
|
||||
'app/scripts/services/degradeservice.js',
|
||||
'app/scripts/services/degrade_service.js',
|
||||
'app/scripts/services/systemservice.js',
|
||||
'app/scripts/services/machineservice.js',
|
||||
'app/scripts/services/identityservice.js',
|
||||
|
|
|
|||
Loading…
Reference in New Issue