handle total block requests

This commit is contained in:
hongqiaowei
2021-07-06 09:00:04 +08:00
parent 20e91b18c5
commit 1bb09f76d6
3 changed files with 167 additions and 109 deletions

View File

@@ -92,7 +92,7 @@ public class FlowStatSchedConfig extends SchedConfig {
private long startTimeSlot = 0; private long startTimeSlot = 0;
private Map<String, AtomicLong> resourceTimeWindow2totalBlockRequestsMap = new HashMap<>(128); // private Map<String, AtomicLong> resourceTimeWindow2totalBlockRequestsMap = new HashMap<>(128);
@Scheduled(cron = "${flow-stat-sched.cron}") @Scheduled(cron = "${flow-stat-sched.cron}")
public void sched() { public void sched() {
@@ -112,24 +112,24 @@ public class FlowStatSchedConfig extends SchedConfig {
return; return;
} }
resourceTimeWindow2totalBlockRequestsMap.clear(); // resourceTimeWindow2totalBlockRequestsMap.clear();
resourceTimeWindowStats.forEach(rtws -> { // resourceTimeWindowStats.forEach(rtws -> {
String resource = rtws.getResourceId(); // String resource = rtws.getResourceId();
List<TimeWindowStat> wins = rtws.getWindows(); // List<TimeWindowStat> wins = rtws.getWindows();
wins.forEach(w -> { // wins.forEach(w -> {
long t = w.getStartTime(); // long t = w.getStartTime();
long blockRequests = w.getBlockRequests(); // long blockRequests = w.getBlockRequests();
resourceTimeWindow2totalBlockRequestsMap.put(resource + t, new AtomicLong(blockRequests)); // resourceTimeWindow2totalBlockRequestsMap.put(resource + t, new AtomicLong(blockRequests));
}); // });
}); // });
resourceTimeWindowStats.forEach(rtws -> { // resourceTimeWindowStats.forEach(rtws -> {
String resource = rtws.getResourceId(); // String resource = rtws.getResourceId();
List<TimeWindowStat> wins = rtws.getWindows(); // List<TimeWindowStat> wins = rtws.getWindows();
wins.forEach(w -> { // wins.forEach(w -> {
accumulateParents(resource, w.getStartTime(), w.getBlockRequests()); // accumulateParents(resource, w.getStartTime(), w.getBlockRequests());
}); // });
}); // });
resourceTimeWindowStats.forEach( resourceTimeWindowStats.forEach(
rtws -> { rtws -> {
@@ -138,7 +138,7 @@ public class FlowStatSchedConfig extends SchedConfig {
int type = ResourceRateLimitConfig.Type.NODE, id = 0; int type = ResourceRateLimitConfig.Type.NODE, id = 0;
ResourceRateLimitConfig c = resourceRateLimitConfigService.getResourceRateLimitConfig(resource); ResourceRateLimitConfig c = resourceRateLimitConfigService.getResourceRateLimitConfig(resource);
if (c == null) { // _global, service, app, ip, ip+service if (c == null) { // _global, service, app, app+service, ip, ip+service
node = ResourceRateLimitConfig.getNode(resource); node = ResourceRateLimitConfig.getNode(resource);
if (node != null && node.equals(ResourceRateLimitConfig.NODE)) { if (node != null && node.equals(ResourceRateLimitConfig.NODE)) {
} else { } else {
@@ -157,10 +157,14 @@ public class FlowStatSchedConfig extends SchedConfig {
} }
} }
} else { } else {
if (pi == null) { if (app == null && pi == null) {
type = ResourceRateLimitConfig.Type.SERVICE_DEFAULT; type = ResourceRateLimitConfig.Type.SERVICE_DEFAULT;
} else { } else {
type = ResourceRateLimitConfig.Type.IP; if (app == null) {
type = ResourceRateLimitConfig.Type.IP;
} else {
type = ResourceRateLimitConfig.Type.APP;
}
} }
} }
} }
@@ -186,8 +190,9 @@ public class FlowStatSchedConfig extends SchedConfig {
qps = rps.doubleValue(); qps = rps.doubleValue();
} }
AtomicLong totalBlockRequests = resourceTimeWindow2totalBlockRequestsMap.get(resource + timeWin); // AtomicLong totalBlockRequests = resourceTimeWindow2totalBlockRequestsMap.get(resource + timeWin);
long tbrs = (totalBlockRequests == null ? w.getBlockRequests() : totalBlockRequests.longValue()); // long tbrs = (totalBlockRequests == null ? w.getBlockRequests() : w.getBlockRequests() + totalBlockRequests.longValue());
long tbrs = w.getTotalBlockRequests();
b.append(Constants.Symbol.LEFT_BRACE); b.append(Constants.Symbol.LEFT_BRACE);
b.append(_ip); toJsonStringValue(b, ip); b.append(Constants.Symbol.COMMA); b.append(_ip); toJsonStringValue(b, ip); b.append(Constants.Symbol.COMMA);
@@ -253,17 +258,17 @@ public class FlowStatSchedConfig extends SchedConfig {
} }
} }
private void accumulateParents(String resource, long timeWin, long blockRequests) { // private void accumulateParents(String resource, long timeWin, long blockRequests) {
List<String> prl = ThreadContext.getArrayList(parentResourceList, String.class); // List<String> prl = ThreadContext.getArrayList(parentResourceList, String.class);
resourceRateLimitConfigService.getParentsTo(resource, prl); // resourceRateLimitConfigService.getParentsTo(resource, prl);
for (int i = 0; i < prl.size(); i++) { // for (int i = 0; i < prl.size(); i++) {
String parentResource = prl.get(i); // String parentResource = prl.get(i);
AtomicLong parentTotalBlockRequests = resourceTimeWindow2totalBlockRequestsMap.get(parentResource + timeWin); // AtomicLong parentTotalBlockRequests = resourceTimeWindow2totalBlockRequestsMap.get(parentResource + timeWin);
if (parentTotalBlockRequests != null) { // if (parentTotalBlockRequests != null) {
parentTotalBlockRequests.addAndGet(blockRequests); // parentTotalBlockRequests.addAndGet(blockRequests);
} // }
} // }
} // }
private long getRecentEndTimeSlot(FlowStat flowStat) { private long getRecentEndTimeSlot(FlowStat flowStat) {
long currentTimeSlot = flowStat.currentTimeSlotId(); long currentTimeSlot = flowStat.currentTimeSlotId();

View File

@@ -120,7 +120,9 @@ public class FlowControlFilter extends FizzWebFilter {
long currentTimeSlot = flowStat.currentTimeSlotId(); long currentTimeSlot = flowStat.currentTimeSlotId();
List<ResourceConfig> resourceConfigs = getFlowControlConfigs(app, ip, null, service, path); List<ResourceConfig> resourceConfigs = getFlowControlConfigs(app, ip, null, service, path);
IncrRequestResult result = flowStat.incrRequest(resourceConfigs, currentTimeSlot); IncrRequestResult result = flowStat.incrRequest(resourceConfigs, currentTimeSlot, (rc, rcs) -> {
return getResourceConfigItselfAndParents(rc, rcs);
});
if (result != null && !result.isSuccess()) { if (result != null && !result.isSuccess()) {
String blockedResourceId = result.getBlockedResourceId(); String blockedResourceId = result.getBlockedResourceId();
@@ -163,6 +165,49 @@ public class FlowControlFilter extends FizzWebFilter {
return chain.filter(exchange); return chain.filter(exchange);
} }
private List<ResourceConfig> getResourceConfigItselfAndParents(ResourceConfig rc, List<ResourceConfig> rcs) {
boolean check = false;
String rcId = rc.getResourceId();
String rcApp = ResourceRateLimitConfig.getApp(rcId);
String rcIp = ResourceRateLimitConfig.getIp(rcId);
List<ResourceConfig> result = new ArrayList<>();
for (int i = rcs.size() - 1; i > -1; i--) {
ResourceConfig r = rcs.get(i);
String id = r.getResourceId();
String app = ResourceRateLimitConfig.getApp(id);
String ip = ResourceRateLimitConfig.getIp(id);
String path = ResourceRateLimitConfig.getPath(id);
if (check) {
if (rcIp != null) {
if (ip != null) {
result.add(r);
} else {
if (app == null && path == null) {
result.add(r);
}
}
} else if (rcApp != null) {
if (app != null) {
result.add(r);
} else {
if (path == null) {
result.add(r);
}
}
} else {
result.add(r);
}
} else if (id.equals(rcId)) {
result.add(r);
check = true;
}
}
if (log.isDebugEnabled()) {
log.debug("getResourceConfigItselfAndParents:\n" + JacksonUtils.writeValueAsString(rc) + '\n' + JacksonUtils.writeValueAsString(result));
}
return result;
}
private List<ResourceConfig> getFlowControlConfigs(String app, String ip, String node, String service, String path) { private List<ResourceConfig> getFlowControlConfigs(String app, String ip, String node, String service, String path) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("get flow control configs by app={}, ip={}, node={}, service={}, path={}", app, ip, node, service, path); log.debug("get flow control configs by app={}, ip={}, node={}, service={}, path={}", app, ip, node, service, path);
@@ -244,9 +289,11 @@ public class FlowControlFilter extends FizzWebFilter {
String app = ResourceRateLimitConfig.getApp(prev); String app = ResourceRateLimitConfig.getApp(prev);
if (app == null) { if (app == null) {
something4(resourceConfigs, rateLimitConfig.app, null, null); something4(resourceConfigs, rateLimitConfig.app, null, null);
something4(resourceConfigs, rateLimitConfig.app, null, rateLimitConfig.service);
} else { } else {
String service = ResourceRateLimitConfig.getService(prev); String service = ResourceRateLimitConfig.getService(prev);
if (service == null) { if (service == null) {
something4(resourceConfigs, rateLimitConfig.app, null, rateLimitConfig.service);
} else { } else {
app = ResourceRateLimitConfig.getApp(prevPrev); app = ResourceRateLimitConfig.getApp(prevPrev);
if (app == null) { if (app == null) {

View File

@@ -181,80 +181,86 @@ public class ResourceRateLimitConfigService {
return resourceRateLimitConfigMap; return resourceRateLimitConfigMap;
} }
// _global, service, app, ip, ip+service // _global, service, app, app+service, ip, ip+service
public void getParentsTo(String resource, List<String> parentList) { // public void getParentsTo(String resource, List<String> parentList) {
String app = null, ip = null, node = null, service = null, path = null; // String app = null, ip = null, node = null, service = null, path = null;
ResourceRateLimitConfig c = resourceRateLimitConfigMap.get(resource); // ResourceRateLimitConfig c = resourceRateLimitConfigMap.get(resource);
if (c == null) { // if (c == null) {
node = ResourceRateLimitConfig.getNode(resource); // node = ResourceRateLimitConfig.getNode(resource);
if (node != null && node.equals(ResourceRateLimitConfig.NODE)) { // if (node != null && node.equals(ResourceRateLimitConfig.NODE)) {
} else { // } else {
service = ResourceRateLimitConfig.getService(resource); // service = ResourceRateLimitConfig.getService(resource);
app = ResourceRateLimitConfig.getApp(resource); // app = ResourceRateLimitConfig.getApp(resource);
ip = ResourceRateLimitConfig.getIp(resource); // ip = ResourceRateLimitConfig.getIp(resource);
if (service == null) { // if (service == null) { // or app ip
parentList.add(ResourceRateLimitConfig.NODE_RESOURCE); // parentList.add(ResourceRateLimitConfig.NODE_RESOURCE);
} else { // } else {
if (ip == null) { // if (app == null && ip == null) {
parentList.add(ResourceRateLimitConfig.NODE_RESOURCE); // parentList.add(ResourceRateLimitConfig.NODE_RESOURCE);
} else { // } else {
String r = ResourceRateLimitConfig.buildResourceId(null, ip, null, null, null); // String r = null;
parentList.add(r); // if (app == null) {
parentList.add(ResourceRateLimitConfig.NODE_RESOURCE); // r = ResourceRateLimitConfig.buildResourceId(null, ip, null, null, null);
} // } else {
} // r = ResourceRateLimitConfig.buildResourceId(app, null, null, null, null);
} // }
return; // parentList.add(r);
} else { // parentList.add( ResourceRateLimitConfig.buildResourceId(null, null, null, service, null) );
if (c.type == ResourceRateLimitConfig.Type.NODE) { // parentList.add(ResourceRateLimitConfig.NODE_RESOURCE);
return; // }
} // }
if (c.type == ResourceRateLimitConfig.Type.SERVICE) { // }
parentList.add(ResourceRateLimitConfig.NODE_RESOURCE); // return;
return; // } else {
} // if (c.type == ResourceRateLimitConfig.Type.NODE) {
app = c.app; // return;
ip = c.ip; // }
service = c.service; // if (c.type == ResourceRateLimitConfig.Type.SERVICE) {
path = c.path; // parentList.add(ResourceRateLimitConfig.NODE_RESOURCE);
} // return;
// }
StringBuilder b = ThreadContext.getStringBuilder(); // app = c.app;
// ip = c.ip;
if (app != null) { // service = c.service;
if (path != null) { // path = c.path;
ResourceRateLimitConfig.buildResourceIdTo(b, app, null, null, service, null); // }
checkRateLimitConfigAndAddTo(b, parentList); //
ResourceRateLimitConfig.buildResourceIdTo(b, app, null, null, null, null); // StringBuilder b = ThreadContext.getStringBuilder();
// checkRateLimitConfigAndAddTo(b, parentList); //
to(parentList, b); // if (app != null) {
} else if (service != null) { // if (path != null) {
ResourceRateLimitConfig.buildResourceIdTo(b, app, null, null, null, null); // ResourceRateLimitConfig.buildResourceIdTo(b, app, null, null, service, null);
checkRateLimitConfigAndAddTo(b, parentList); // checkRateLimitConfigAndAddTo(b, parentList);
} // ResourceRateLimitConfig.buildResourceIdTo(b, app, null, null, null, null);
} // // checkRateLimitConfigAndAddTo(b, parentList);
// to(parentList, b);
if (ip != null) { // } else if (service != null) {
if (path != null) { // ResourceRateLimitConfig.buildResourceIdTo(b, app, null, null, null, null);
ResourceRateLimitConfig.buildResourceIdTo(b, null, ip, null, service, null); // checkRateLimitConfigAndAddTo(b, parentList);
// checkRateLimitConfigAndAddTo(b, parentList); // }
to(parentList, b); // }
ResourceRateLimitConfig.buildResourceIdTo(b, null, ip, null, null, null); //
// checkRateLimitConfigAndAddTo(b, parentList); // if (ip != null) {
to(parentList, b); // if (path != null) {
} else if (service != null) { // ResourceRateLimitConfig.buildResourceIdTo(b, null, ip, null, service, null);
ResourceRateLimitConfig.buildResourceIdTo(b, null, ip, null, null, null); // // checkRateLimitConfigAndAddTo(b, parentList);
checkRateLimitConfigAndAddTo(b, parentList); // to(parentList, b);
} // ResourceRateLimitConfig.buildResourceIdTo(b, null, ip, null, null, null);
} // // checkRateLimitConfigAndAddTo(b, parentList);
// to(parentList, b);
if (path != null) { // } else if (service != null) {
ResourceRateLimitConfig.buildResourceIdTo(b, null, null, null, service, null); // ResourceRateLimitConfig.buildResourceIdTo(b, null, ip, null, null, null);
to(parentList, b); // checkRateLimitConfigAndAddTo(b, parentList);
} // }
// }
parentList.add(ResourceRateLimitConfig.NODE_RESOURCE); //
} // if (path != null) {
// ResourceRateLimitConfig.buildResourceIdTo(b, null, null, null, service, null);
// to(parentList, b);
// }
//
// parentList.add(ResourceRateLimitConfig.NODE_RESOURCE);
// }
private void to(List<String> parentList, StringBuilder b) { private void to(List<String> parentList, StringBuilder b) {
parentList.add(b.toString()); parentList.add(b.toString());