Add degrade rule data to ResourceConfig.
This commit is contained in:
@@ -38,6 +38,8 @@ import we.stats.BlockType;
|
||||
import we.stats.FlowStat;
|
||||
import we.stats.IncrRequestResult;
|
||||
import we.stats.ResourceConfig;
|
||||
import we.stats.degrade.DegradeRule;
|
||||
import we.stats.degrade.DegradeRuleService;
|
||||
import we.stats.ratelimit.ResourceRateLimitConfig;
|
||||
import we.stats.ratelimit.ResourceRateLimitConfigService;
|
||||
import we.util.*;
|
||||
@@ -87,6 +89,9 @@ public class FlowControlFilter extends FizzWebFilter {
|
||||
@Resource
|
||||
private SystemConfig systemConfig;
|
||||
|
||||
@Resource
|
||||
DegradeRuleService degradeRuleService;
|
||||
|
||||
@Override
|
||||
public Mono<Void> doFilter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||
|
||||
@@ -129,6 +134,33 @@ public class FlowControlFilter extends FizzWebFilter {
|
||||
|
||||
if (result != null && !result.isSuccess()) {
|
||||
String blockedResourceId = result.getBlockedResourceId();
|
||||
if (BlockType.DEGRADE == result.getBlockType()) {
|
||||
log.info("{} exceed {} degrade limit, trigger degrade", traceId, blockedResourceId, LogService.BIZ_ID, traceId);
|
||||
|
||||
String responseContentType = flowControlFilterProperties.getDegradeDefaultResponseContentType();
|
||||
String responseContent = flowControlFilterProperties.getDegradeDefaultResponseContent();
|
||||
|
||||
DegradeRule degradeRule = degradeRuleService.getDegradeRule(ResourceIdUtils.SERVICE_DEFAULT_RESOURCE);
|
||||
if (degradeRule != null) {
|
||||
responseContentType = degradeRule.getResponseContentType();
|
||||
responseContent = degradeRule.getResponseContent();
|
||||
}
|
||||
|
||||
degradeRule = degradeRuleService.getDegradeRule(blockedResourceId);
|
||||
if (degradeRule != null) {
|
||||
if (StringUtils.isNotBlank(degradeRule.getResponseContentType())) {
|
||||
responseContentType = degradeRule.getResponseContentType();
|
||||
}
|
||||
if (StringUtils.isNotBlank(degradeRule.getResponseContent())) {
|
||||
responseContent = degradeRule.getResponseContent();
|
||||
}
|
||||
}
|
||||
|
||||
ServerHttpResponse resp = exchange.getResponse();
|
||||
resp.setStatusCode(HttpStatus.OK);
|
||||
resp.getHeaders().add(HttpHeaders.CONTENT_TYPE, responseContentType);
|
||||
return resp.writeWith(Mono.just(resp.bufferFactory().wrap(responseContent.getBytes())));
|
||||
} else {
|
||||
if (BlockType.CONCURRENT_REQUEST == result.getBlockType()) {
|
||||
log.info("{} exceed {} flow limit, blocked by maximum concurrent requests", traceId, blockedResourceId, LogService.BIZ_ID, traceId);
|
||||
} else {
|
||||
@@ -151,7 +183,7 @@ public class FlowControlFilter extends FizzWebFilter {
|
||||
resp.setStatusCode(HttpStatus.OK);
|
||||
resp.getHeaders().add(HttpHeaders.CONTENT_TYPE, rt);
|
||||
return resp.writeWith(Mono.just(resp.bufferFactory().wrap(rc.getBytes())));
|
||||
|
||||
}
|
||||
} else {
|
||||
long start = System.currentTimeMillis();
|
||||
setTraceId(exchange);
|
||||
@@ -264,11 +296,15 @@ public class FlowControlFilter extends FizzWebFilter {
|
||||
private void checkRateLimitConfigAndAddTo(List<ResourceConfig> resourceConfigs, StringBuilder b, String app, String ip, String node, String service, String path, String defaultRateLimitConfigId) {
|
||||
ResourceIdUtils.buildResourceIdTo(b, app, ip, node, service, path);
|
||||
String resourceId = b.toString();
|
||||
checkRateLimitConfigAndAddTo(resourceConfigs, resourceId, defaultRateLimitConfigId);
|
||||
|
||||
// degrade rule only support service and path
|
||||
boolean checkDegradeRule = app == null && ip == null && node == null;
|
||||
|
||||
checkRateLimitConfigAndAddTo(resourceConfigs, resourceId, defaultRateLimitConfigId, checkDegradeRule);
|
||||
b.delete(0, b.length());
|
||||
}
|
||||
|
||||
private void checkRateLimitConfigAndAddTo(List<ResourceConfig> resourceConfigs, String resource, String defaultRateLimitConfigId) {
|
||||
private void checkRateLimitConfigAndAddTo(List<ResourceConfig> resourceConfigs, String resource, String defaultRateLimitConfigId, boolean checkDegradeRule) {
|
||||
ResourceConfig rc = null;
|
||||
ResourceRateLimitConfig rateLimitConfig = resourceRateLimitConfigService.getResourceRateLimitConfig(resource);
|
||||
if (rateLimitConfig != null && rateLimitConfig.isEnable()) {
|
||||
@@ -300,6 +336,24 @@ public class FlowControlFilter extends FizzWebFilter {
|
||||
resourceConfigs.add(rc);
|
||||
}
|
||||
}
|
||||
|
||||
if (checkDegradeRule) {
|
||||
DegradeRule degradeRule = degradeRuleService.getDegradeRule(resource);
|
||||
if (degradeRule != null && degradeRule.isEnable()) {
|
||||
if (rc == null) {
|
||||
rc = new ResourceConfig(resource, 0, 0);
|
||||
resourceConfigs.add(rc);
|
||||
}
|
||||
fillDegradeRuleData(rc, degradeRule);
|
||||
} else {
|
||||
if (defaultRateLimitConfigId != null && defaultRateLimitConfigId.equals(ResourceIdUtils.SERVICE_DEFAULT)) {
|
||||
degradeRule = degradeRuleService.getDegradeRule(ResourceIdUtils.SERVICE_DEFAULT_RESOURCE);
|
||||
if (degradeRule != null && degradeRule.isEnable()) {
|
||||
fillDegradeRuleData(rc, degradeRule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void something4appAndIp(List<ResourceConfig> resourceConfigs, ResourceRateLimitConfig rateLimitConfig) {
|
||||
@@ -366,4 +420,15 @@ public class FlowControlFilter extends FizzWebFilter {
|
||||
ResourceConfig rc = new ResourceConfig(r, 0, 0);
|
||||
resourceConfigs.add(rc);
|
||||
}
|
||||
|
||||
private void fillDegradeRuleData(ResourceConfig resourceConfig, DegradeRule degradeRule) {
|
||||
resourceConfig.setStrategy(degradeRule.getStrategy());
|
||||
resourceConfig.setRatioThreshold(degradeRule.getRatioThreshold());
|
||||
resourceConfig.setExceptionCount(degradeRule.getExceptionCount());
|
||||
resourceConfig.setMinRequestCount(degradeRule.getMinRequestCount());
|
||||
resourceConfig.setTimeWindow(degradeRule.getTimeWindow());
|
||||
resourceConfig.setStatInterval(degradeRule.getStatInterval());
|
||||
resourceConfig.setRecoveryStrategy(degradeRule.getRecoveryStrategy());
|
||||
resourceConfig.setRecoveryTimeWindow(degradeRule.getRecoveryTimeWindow());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,4 +33,10 @@ public class FlowControlFilterProperties {
|
||||
|
||||
@Value("${flowControl:false}")
|
||||
private boolean flowControl;
|
||||
|
||||
@Value("${fizz.degrade.default-response-content-type:application/json; charset=UTF-8;}")
|
||||
private String degradeDefaultResponseContentType;
|
||||
|
||||
@Value("${fizz.degrade.default-response-content:{\"code\":6002,\"msg\":\"The current service is unavailable, Please try again later.\"}}")
|
||||
private String degradeDefaultResponseContent;
|
||||
}
|
||||
|
||||
@@ -31,5 +31,10 @@ public enum BlockType {
|
||||
/**
|
||||
* Blocked by QPS
|
||||
*/
|
||||
QPS;
|
||||
QPS,
|
||||
|
||||
/**
|
||||
* Blocked by degrade
|
||||
*/
|
||||
DEGRADE
|
||||
}
|
||||
|
||||
@@ -17,17 +17,34 @@
|
||||
|
||||
package we.stats;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Francis Dong
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ResourceConfig {
|
||||
|
||||
public ResourceConfig(String resourceId, long maxCon, long maxQPS) {
|
||||
this.resourceId = resourceId;
|
||||
this.maxCon = maxCon;
|
||||
this.maxQPS = maxQPS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resouce ID
|
||||
*/
|
||||
private String resourceId;
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Flow control rule
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
* Maximum concurrent request, zero or negative for no limit
|
||||
*/
|
||||
@@ -38,37 +55,40 @@ public class ResourceConfig {
|
||||
*/
|
||||
private long maxQPS;
|
||||
|
||||
public ResourceConfig(String resourceId, long maxCon, long maxQPS) {
|
||||
this.resourceId = resourceId;
|
||||
this.maxCon = maxCon;
|
||||
this.maxQPS = maxQPS;
|
||||
}
|
||||
|
||||
public ResourceConfig() {
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public long getMaxCon() {
|
||||
return maxCon;
|
||||
}
|
||||
|
||||
public void setMaxCon(long maxCon) {
|
||||
this.maxCon = maxCon;
|
||||
}
|
||||
|
||||
public long getMaxQPS() {
|
||||
return maxQPS;
|
||||
}
|
||||
|
||||
public void setMaxQPS(long maxQPS) {
|
||||
this.maxQPS = maxQPS;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Degrade rule
|
||||
//---------------------------------------------------------------------
|
||||
/**
|
||||
* Degrade strategy: 1-exception ratio 2-exception count
|
||||
*/
|
||||
private Byte strategy;
|
||||
/**
|
||||
* Ratio threshold, not null when degrade strategy is 1-exception ratio
|
||||
*/
|
||||
private Float ratioThreshold;
|
||||
/**
|
||||
* Exception count, not null when degrade strategy is 2-exception count
|
||||
*/
|
||||
private Long exceptionCount;
|
||||
/**
|
||||
* Minimal request count
|
||||
*/
|
||||
private Long minRequestCount;
|
||||
/**
|
||||
* Time window(second)
|
||||
*/
|
||||
private Integer timeWindow;
|
||||
/**
|
||||
* Statistic interval(second)
|
||||
*/
|
||||
private Integer statInterval;
|
||||
/**
|
||||
* Recovery strategy: 1-try one 2-recover gradually 3-recover immediately
|
||||
*/
|
||||
private Byte recoveryStrategy;
|
||||
/**
|
||||
* Recovery time window(second),not null when recovery strategy is 2-recover gradually
|
||||
*/
|
||||
private Integer recoveryTimeWindow;
|
||||
}
|
||||
|
||||
@@ -31,68 +31,68 @@ import static we.util.ResourceIdUtils.SERVICE_DEFAULT;
|
||||
@Data
|
||||
public class DegradeRule {
|
||||
/**
|
||||
* 整型自增主键
|
||||
* ID
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 熔断类型 1-服务默认配置 2-服务 3-接口
|
||||
* Degrade type: 1-default service 2-service 3-path
|
||||
*/
|
||||
private Byte type;
|
||||
/**
|
||||
* 前端服务名
|
||||
* Front service name
|
||||
*/
|
||||
private String service;
|
||||
/**
|
||||
* 前端API路径
|
||||
* Front API path
|
||||
*/
|
||||
private String path;
|
||||
/**
|
||||
* 熔断策略 1-异常比例 2-异常数
|
||||
* Degrade strategy: 1-exception ratio 2-exception count
|
||||
*/
|
||||
private Byte strategy;
|
||||
/**
|
||||
* 比例阈值,当熔断策略为 1-异常比例 时该字段有值
|
||||
* Ratio threshold, not null when degrade strategy is 1-exception ratio
|
||||
*/
|
||||
private Float ratioThreshold;
|
||||
/**
|
||||
* 异常数,当熔断策略为 2-异常数 时该字段有值
|
||||
* Exception count, not null when degrade strategy is 2-exception count
|
||||
*/
|
||||
private Long exceptionCount;
|
||||
/**
|
||||
* 最小请求数
|
||||
* Minimal request count
|
||||
*/
|
||||
private Long minRequestCount;
|
||||
/**
|
||||
* 熔断时长(秒)
|
||||
* Time window(second)
|
||||
*/
|
||||
private Integer timeWindow;
|
||||
/**
|
||||
* 统计时长(秒)
|
||||
* Statistic interval(second)
|
||||
*/
|
||||
private Integer statInterval;
|
||||
/**
|
||||
* 恢复策略 1-尝试恢复 2-逐步恢复 3-立即恢复
|
||||
* Recovery strategy: 1-try one 2-recover gradually 3-recover immediately
|
||||
*/
|
||||
private Byte recoveryStrategy;
|
||||
/**
|
||||
* 恢复时长(秒),当恢复策略为 2-逐步恢复 时该字段有值
|
||||
* Recovery time window(second),not null when recovery strategy is 2-recover gradually
|
||||
*/
|
||||
private Integer recoveryTimeWindow;
|
||||
/**
|
||||
* 熔断响应ContentType
|
||||
* Response ContentType
|
||||
*/
|
||||
private String responseContentType;
|
||||
/**
|
||||
* 熔断响应报文
|
||||
* Response Content
|
||||
*/
|
||||
private String responseContent;
|
||||
|
||||
/**
|
||||
* 当type为1时,1启用,0反之
|
||||
* When type is 1-default service,1-enable 0-disable
|
||||
*/
|
||||
private Integer enable;
|
||||
/**
|
||||
* 是否删除 1-是 2-否
|
||||
* Is deleted, 1-yes 2-no
|
||||
*/
|
||||
private Integer isDeleted;
|
||||
|
||||
|
||||
@@ -68,6 +68,10 @@ public class DegradeRuleService {
|
||||
}
|
||||
}
|
||||
|
||||
public DegradeRule getDegradeRule(String resourceId) {
|
||||
return resourceId2DegradeRuleMap.get(resourceId);
|
||||
}
|
||||
|
||||
public void refreshLocalCache() throws Throwable {
|
||||
this.initDegradeRule();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user