Fix circuit breaker config update bug

This commit is contained in:
hongqiaowei
2022-01-27 18:10:24 +08:00
parent b548cd1e47
commit 05f696e187
3 changed files with 42 additions and 30 deletions

View File

@@ -99,6 +99,6 @@ public class CacheCheckController {
@GetMapping("/circuitBreakers") @GetMapping("/circuitBreakers")
public Mono<String> circuitBreakers(ServerWebExchange exchange) { public Mono<String> circuitBreakers(ServerWebExchange exchange) {
return Mono.just(JacksonUtils.writeValueAsString(circuitBreakManager.getCircuitBreakerMap())); return Mono.just(JacksonUtils.writeValueAsString(circuitBreakManager.getResource2circuitBreakerMap()));
} }
} }

View File

@@ -47,9 +47,11 @@ public class CircuitBreakManager {
// private Map<String/*child resource*/, String/*parent resource*/> parentResourceMap = new HashMap<>(128); // private Map<String/*child resource*/, String/*parent resource*/> parentResourceMap = new HashMap<>(128);
private final Map<String/*resource*/, CircuitBreaker> circuitBreakerMap = new HashMap<>(64); private final Map<Long, CircuitBreaker> circuitBreakerMap = new HashMap<>(64);
private final Set<String> circuitBreakersFromServiceDefault = new HashSet<>(64); private final Map<String, CircuitBreaker> resource2circuitBreakerMap = new HashMap<>(64);
private final Set<String> circuitBreakersFromServiceDefault = new HashSet<>(64);
@Resource(name = AggregateRedisConfig.AGGREGATE_REACTIVE_REDIS_TEMPLATE) @Resource(name = AggregateRedisConfig.AGGREGATE_REACTIVE_REDIS_TEMPLATE)
private ReactiveStringRedisTemplate rt; private ReactiveStringRedisTemplate rt;
@@ -81,7 +83,8 @@ public class CircuitBreakManager {
for (Map.Entry<Object, Object> e : es) { for (Map.Entry<Object, Object> e : es) {
json = (String) e.getValue(); json = (String) e.getValue();
CircuitBreaker cb = JacksonUtils.readValue(json, CircuitBreaker.class); CircuitBreaker cb = JacksonUtils.readValue(json, CircuitBreaker.class);
circuitBreakerMap.put(cb.resource, cb); circuitBreakerMap.put(cb.id, cb);
resource2circuitBreakerMap.put(cb.resource, cb);
// updateParentResourceMap(cb); // updateParentResourceMap(cb);
LOGGER.info("init circuit breaker {}", cb); LOGGER.info("init circuit breaker {}", cb);
} }
@@ -132,10 +135,17 @@ public class CircuitBreakManager {
try { try {
CircuitBreaker cb = JacksonUtils.readValue(message, CircuitBreaker.class); CircuitBreaker cb = JacksonUtils.readValue(message, CircuitBreaker.class);
if (cb.isDeleted) { if (cb.isDeleted) {
circuitBreakerMap.remove(cb.resource); circuitBreakerMap.remove(cb.id);
resource2circuitBreakerMap.remove(cb.resource);
LOGGER.info("remove circuit breaker: {}", cb); LOGGER.info("remove circuit breaker: {}", cb);
} else { } else {
circuitBreakerMap.put(cb.resource, cb); CircuitBreaker prev = circuitBreakerMap.get(cb.id);
if (prev != null) {
resource2circuitBreakerMap.remove(prev.resource);
}
circuitBreakerMap.put(cb.id, cb);
resource2circuitBreakerMap.put(cb.resource, cb);
circuitBreakersFromServiceDefault.remove(cb.resource);
LOGGER.info("update circuit breaker: {}", cb); LOGGER.info("update circuit breaker: {}", cb);
} }
// updateParentResourceMap(cb); // updateParentResourceMap(cb);
@@ -143,7 +153,7 @@ public class CircuitBreakManager {
if (cb.type == CircuitBreaker.Type.SERVICE_DEFAULT) { if (cb.type == CircuitBreaker.Type.SERVICE_DEFAULT) {
if (cb.isDeleted || !cb.serviceDefaultEnable) { if (cb.isDeleted || !cb.serviceDefaultEnable) {
for (String resource : circuitBreakersFromServiceDefault) { for (String resource : circuitBreakersFromServiceDefault) {
circuitBreakerMap.remove(resource); resource2circuitBreakerMap.remove(resource);
} }
circuitBreakersFromServiceDefault.clear(); circuitBreakersFromServiceDefault.clear();
} }
@@ -185,12 +195,12 @@ public class CircuitBreakManager {
public boolean permit(ServerWebExchange exchange, long currentTimeWindow, FlowStat flowStat, String service, String path) { public boolean permit(ServerWebExchange exchange, long currentTimeWindow, FlowStat flowStat, String service, String path) {
String resource = ResourceIdUtils.buildResourceId(null, null, null, service, path); String resource = ResourceIdUtils.buildResourceId(null, null, null, service, path);
// return permit(exchange, currentTimeWindow, flowStat, resource); // return permit(exchange, currentTimeWindow, flowStat, resource);
CircuitBreaker cb = circuitBreakerMap.get(resource); CircuitBreaker cb = resource2circuitBreakerMap.get(resource);
if (cb == null) { if (cb == null) {
resource = ResourceIdUtils.buildResourceId(null, null, null, service, null); resource = ResourceIdUtils.buildResourceId(null, null, null, service, null);
cb = circuitBreakerMap.get(resource); cb = resource2circuitBreakerMap.get(resource);
if (cb == null) { if (cb == null) {
cb = circuitBreakerMap.get(ResourceIdUtils.SERVICE_DEFAULT_RESOURCE); cb = resource2circuitBreakerMap.get(ResourceIdUtils.SERVICE_DEFAULT_RESOURCE);
if (cb != null && cb.serviceDefaultEnable) { if (cb != null && cb.serviceDefaultEnable) {
cb = buildCircuitBreakerFromServiceDefault(service, resource); cb = buildCircuitBreakerFromServiceDefault(service, resource);
} else { } else {
@@ -211,27 +221,29 @@ public class CircuitBreakManager {
} }
private CircuitBreaker buildCircuitBreakerFromServiceDefault(String service, String resource) { private CircuitBreaker buildCircuitBreakerFromServiceDefault(String service, String resource) {
CircuitBreaker serviceDefaultCircuitBreaker = circuitBreakerMap.get(ResourceIdUtils.SERVICE_DEFAULT_RESOURCE); CircuitBreaker serviceDefaultCircuitBreaker = resource2circuitBreakerMap.get(ResourceIdUtils.SERVICE_DEFAULT_RESOURCE);
CircuitBreaker cb = new CircuitBreaker(); CircuitBreaker cb = new CircuitBreaker();
cb.type = CircuitBreaker.Type.SERVICE; cb.type = CircuitBreaker.Type.SERVICE;
cb.service = service; cb.service = service;
cb.serviceDefaultEnable = true; cb.serviceDefaultEnable = true;
cb.resource = resource; cb.resource = resource;
cb.breakStrategy = serviceDefaultCircuitBreaker.breakStrategy; cb.breakStrategy = serviceDefaultCircuitBreaker.breakStrategy;
cb.errorRatioThreshold = serviceDefaultCircuitBreaker.errorRatioThreshold; cb.errorRatioThreshold = serviceDefaultCircuitBreaker.errorRatioThreshold;
cb.totalErrorThreshold = serviceDefaultCircuitBreaker.totalErrorThreshold; cb.totalErrorThreshold = serviceDefaultCircuitBreaker.totalErrorThreshold;
cb.minRequests = serviceDefaultCircuitBreaker.minRequests; cb.minRequests = serviceDefaultCircuitBreaker.minRequests;
cb.monitorDuration = serviceDefaultCircuitBreaker.monitorDuration; cb.monitorDuration = serviceDefaultCircuitBreaker.monitorDuration;
cb.breakDuration = serviceDefaultCircuitBreaker.breakDuration; cb.breakDuration = serviceDefaultCircuitBreaker.breakDuration;
cb.resumeStrategy = serviceDefaultCircuitBreaker.resumeStrategy; cb.resumeStrategy = serviceDefaultCircuitBreaker.resumeStrategy;
if (cb.resumeStrategy == CircuitBreaker.ResumeStrategy.GRADUAL) { if (cb.resumeStrategy == CircuitBreaker.ResumeStrategy.GRADUAL) {
cb.resumeDuration = serviceDefaultCircuitBreaker.resumeDuration; cb.resumeDuration = serviceDefaultCircuitBreaker.resumeDuration;
cb.initGradualResumeTimeWindowContext(); cb.initGradualResumeTimeWindowContext();
} }
cb.stateStartTime = serviceDefaultCircuitBreaker.stateStartTime; cb.responseContentType = serviceDefaultCircuitBreaker.responseContentType;
cb.responseContent = serviceDefaultCircuitBreaker.responseContent;
cb.stateStartTime = serviceDefaultCircuitBreaker.stateStartTime;
circuitBreakerMap.put(resource, cb); resource2circuitBreakerMap.put(resource, cb);
circuitBreakersFromServiceDefault.add(resource); circuitBreakersFromServiceDefault.add(resource);
return cb; return cb;
@@ -255,12 +267,12 @@ public class CircuitBreakManager {
public void correctCircuitBreakerStateAsError(ServerWebExchange exchange, long currentTimeWindow, FlowStat flowStat, String service, String path) { public void correctCircuitBreakerStateAsError(ServerWebExchange exchange, long currentTimeWindow, FlowStat flowStat, String service, String path) {
String resource = ResourceIdUtils.buildResourceId(null, null, null, service, path); String resource = ResourceIdUtils.buildResourceId(null, null, null, service, path);
// correctCircuitBreakerState4error(exchange, currentTimeWindow, flowStat, resource); // correctCircuitBreakerState4error(exchange, currentTimeWindow, flowStat, resource);
CircuitBreaker cb = circuitBreakerMap.get(resource); CircuitBreaker cb = resource2circuitBreakerMap.get(resource);
if (cb == null) { if (cb == null) {
resource = ResourceIdUtils.buildResourceId(null, null, null, service, null); resource = ResourceIdUtils.buildResourceId(null, null, null, service, null);
cb = circuitBreakerMap.get(resource); cb = resource2circuitBreakerMap.get(resource);
if (cb == null) { if (cb == null) {
cb = circuitBreakerMap.get(ResourceIdUtils.SERVICE_DEFAULT_RESOURCE); cb = resource2circuitBreakerMap.get(ResourceIdUtils.SERVICE_DEFAULT_RESOURCE);
if (cb != null && cb.serviceDefaultEnable) { if (cb != null && cb.serviceDefaultEnable) {
cb = buildCircuitBreakerFromServiceDefault(service, resource); cb = buildCircuitBreakerFromServiceDefault(service, resource);
} else { } else {
@@ -297,11 +309,11 @@ public class CircuitBreakManager {
}*/ }*/
public CircuitBreaker getCircuitBreaker(String resource) { public CircuitBreaker getCircuitBreaker(String resource) {
return circuitBreakerMap.get(resource); return resource2circuitBreakerMap.get(resource);
} }
public Map<String, CircuitBreaker> getCircuitBreakerMap() { public Map<String, CircuitBreaker> getResource2circuitBreakerMap() {
return circuitBreakerMap; return resource2circuitBreakerMap;
} }
/*public Map<String, String> getParentResourceMap() { /*public Map<String, String> getParentResourceMap() {

View File

@@ -87,7 +87,7 @@ public class CircuitBreakManagerTests {
cb.breakDuration = 5 * 1000; cb.breakDuration = 5 * 1000;
cb.resumeStrategy = CircuitBreaker.ResumeStrategy.IMMEDIATE; cb.resumeStrategy = CircuitBreaker.ResumeStrategy.IMMEDIATE;
cb.stateStartTime = currentTimeWindow; cb.stateStartTime = currentTimeWindow;
Map<String, CircuitBreaker> circuitBreakerMap = circuitBreakManager.getCircuitBreakerMap(); Map<String, CircuitBreaker> circuitBreakerMap = circuitBreakManager.getResource2circuitBreakerMap();
circuitBreakerMap.put(cb.resource, cb); circuitBreakerMap.put(cb.resource, cb);
ResourceStat resourceStat = flowStat.getResourceStat(cb.resource); ResourceStat resourceStat = flowStat.getResourceStat(cb.resource);