diff --git a/README.en-us.md b/README.en-us.md index 1e3c672..cff5961 100644 --- a/README.en-us.md +++ b/README.en-us.md @@ -4,7 +4,7 @@ English | [简体中文](./README.md)

- Version + Version Documentation @@ -122,6 +122,7 @@ Starting from v1.3.0, the frontend and backend of the management backend are mer | v2.5.2 | v2.5.2 | | v2.6.0 | v2.6.0 | | v2.6.1 | v2.6.1 | +| v2.6.2 | v2.6.2 | Please download the corresponding management backend version according to the version of the community version diff --git a/README.md b/README.md index 96f4fb9..23901fb 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@

- Version + Version Documentation @@ -120,6 +120,7 @@ API地址:http://demo.fizzgate.com/proxy/[服务名]/[API_Path] | v2.5.2 | v2.5.2 | | v2.6.0 | v2.6.0 | | v2.6.1 | v2.6.1 | +| v2.6.2 | v2.6.2 | 请根据社区版的版本下载对应的管理后台版本 diff --git a/docker-compose.yml b/docker-compose.yml index 498058a..0e3c0d0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: "3.6" services: fizz-mysql: - image: "fizzgate/fizz-mysql:2.6.1" + image: "fizzgate/fizz-mysql:2.6.2" container_name: fizz-mysql restart: always hostname: fizz-mysql @@ -27,7 +27,7 @@ services: - fizz fizz-gateway-community: - image: "fizzgate/fizz-gateway-community:2.6.1" + image: "fizzgate/fizz-gateway-community:2.6.2" container_name: fizz-gateway-community restart: always hostname: fizz-gateway-community @@ -48,7 +48,7 @@ services: - fizz fizz-manager-professional: - image: "fizzgate/fizz-manager-professional:2.6.1" + image: "fizzgate/fizz-manager-professional:2.6.2" container_name: fizz-manager-professional restart: always hostname: fizz-manager-professional diff --git a/fizz-bootstrap/pom.xml b/fizz-bootstrap/pom.xml index ed36e52..cdf0738 100644 --- a/fizz-bootstrap/pom.xml +++ b/fizz-bootstrap/pom.xml @@ -12,15 +12,15 @@ com.fizzgate fizz-bootstrap - 2.6.1 + 2.6.2 1.8 - 5.2.20.RELEASE + 5.2.21.RELEASE Dragonfruit-SR3 Dysprosium-SR25 5.3.7.RELEASE - 4.1.75.Final + 4.1.76.Final 4.4.15 2.17.2 1.7.36 diff --git a/fizz-common/pom.xml b/fizz-common/pom.xml index c29ae7f..dabbe42 100644 --- a/fizz-common/pom.xml +++ b/fizz-common/pom.xml @@ -5,7 +5,7 @@ fizz-gateway-community com.fizzgate - 2.6.1 + 2.6.2 ../pom.xml 4.0.0 @@ -17,6 +17,11 @@ + + org.openjdk.jol + jol-core + + org.springframework.cloud spring-cloud-context diff --git a/fizz-common/src/main/java/we/util/Consts.java b/fizz-common/src/main/java/we/util/Consts.java index e9a1852..014a1b2 100644 --- a/fizz-common/src/main/java/we/util/Consts.java +++ b/fizz-common/src/main/java/we/util/Consts.java @@ -101,6 +101,12 @@ public final class Consts { public static final String PROD = "prod"; } + public static final class UN { + public static final int KB = 1024; + public static final int MB = 1024 * KB; + public static final int GB = 1024 * MB; + } + public static final String HTTP_SERVER = "http_server"; public static final String HTTP_CLIENT = "http_client"; public static final String MYSQL = "mysql"; diff --git a/fizz-core/pom.xml b/fizz-core/pom.xml index 8270d16..7bf45a8 100644 --- a/fizz-core/pom.xml +++ b/fizz-core/pom.xml @@ -5,7 +5,7 @@ fizz-gateway-community com.fizzgate - 2.6.1 + 2.6.2 ../pom.xml 4.0.0 diff --git a/fizz-core/src/main/java/we/controller/CacheCheckController.java b/fizz-core/src/main/java/we/controller/CacheCheckController.java index 96cf0ee..4f0aa71 100644 --- a/fizz-core/src/main/java/we/controller/CacheCheckController.java +++ b/fizz-core/src/main/java/we/controller/CacheCheckController.java @@ -17,6 +17,7 @@ package we.controller; +import org.openjdk.jol.info.GraphLayout; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -27,11 +28,22 @@ import we.plugin.auth.ApiConfig2appsService; import we.plugin.auth.ApiConfigService; import we.plugin.auth.AppService; import we.plugin.auth.GatewayGroupService; +import we.stats.FlowStat; +import we.stats.ResourceStat; import we.stats.circuitbreaker.CircuitBreakManager; +import we.stats.ratelimit.ResourceRateLimitConfig; import we.stats.ratelimit.ResourceRateLimitConfigService; +import we.util.Consts; import we.util.JacksonUtils; +import we.util.ResourceIdUtils; import javax.annotation.Resource; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; /** * @author hongqiaowei @@ -62,6 +74,9 @@ public class CacheCheckController { @Resource private CircuitBreakManager circuitBreakManager; + @Resource + private FlowStat flowStat; + @GetMapping("/gatewayGroups") public Mono gatewayGroups(ServerWebExchange exchange) { return Mono.just(JacksonUtils.writeValueAsString(gatewayGroupService.gatewayGroupMap)); @@ -101,4 +116,95 @@ public class CacheCheckController { public Mono circuitBreakers(ServerWebExchange exchange) { return Mono.just(JacksonUtils.writeValueAsString(circuitBreakManager.getResource2circuitBreakerMap())); } + + @GetMapping("/resourceStats") + public Mono resourceStats(ServerWebExchange exchange) { + Map map = new HashMap<>(); + int nodeCnt = 0, serviceDefaultCnt = 0, serviceCnt = 0, servicePathCnt = 0, appDefaultCnt = 0, appCnt = 0, ipCnt = 0, hostCnt = 0; + ConcurrentMap resourceStats = flowStat.resourceStats; + Set> entrySet = resourceStats.entrySet(); + for (Map.Entry entry : entrySet) { + String resource = entry.getKey(); + ResourceRateLimitConfig config = resourceRateLimitConfigService.getResourceRateLimitConfig(resource); + if (config == null) { + String app = ResourceIdUtils.getApp(resource); + String ip = ResourceIdUtils.getIp(resource); + String node = ResourceIdUtils.getNode(resource); + String service = ResourceIdUtils.getService(resource); + if (node == null) { + if (app != null) { + ResourceRateLimitConfig appConfig = resourceRateLimitConfigService.getResourceRateLimitConfig(ResourceIdUtils.APP_DEFAULT_RESOURCE); + if (appConfig != null && appConfig.isEnable()) { + appDefaultCnt++; + } else { + appCnt++; + } + continue; + } + if (ip != null) { + ipCnt++; + continue; + } + if (service != null) { + serviceDefaultCnt++; + } + } else { + if (node.equals(ResourceIdUtils.NODE)) { + nodeCnt++; + } else { + hostCnt++; + } + } + } else { + byte t = config.type; + if (t == ResourceRateLimitConfig.Type.NODE) { + nodeCnt++; + } else if (t == ResourceRateLimitConfig.Type.SERVICE_DEFAULT) { + serviceDefaultCnt++; + } else if (t == ResourceRateLimitConfig.Type.SERVICE) { + serviceCnt++; + } else if (t == ResourceRateLimitConfig.Type.APP_DEFAULT) { + appDefaultCnt++; + } else if (t == ResourceRateLimitConfig.Type.APP) { + appCnt++; + } else if (t == ResourceRateLimitConfig.Type.IP) { + ipCnt++; + } else if (t == ResourceRateLimitConfig.Type.API) { + servicePathCnt++; + } else { + hostCnt++; + } + } + } + + map.put("node", nodeCnt); + map.put("serviceDefault", serviceDefaultCnt); + map.put("service", serviceCnt); + map.put("appDefault", appDefaultCnt); + map.put("app", appCnt); + map.put("ip", ipCnt); + map.put("host", hostCnt); + map.put("servicePathCnt", servicePathCnt); + int totalResources = appCnt + appDefaultCnt + ipCnt + nodeCnt + hostCnt + serviceCnt + serviceDefaultCnt + servicePathCnt; + map.put("totalResources", totalResources); + + long size = GraphLayout.parseInstance(resourceStats).totalSize(); + BigDecimal bigDecimalSize = new BigDecimal(size); + String resourceStatsSize; + if (size >= Consts.UN.GB) { + float r = bigDecimalSize.divide(new BigDecimal(Consts.UN.GB), 2, RoundingMode.HALF_UP).floatValue(); + resourceStatsSize = r + " GB"; + } else if (size >= Consts.UN.MB) { + float r = bigDecimalSize.divide(new BigDecimal(Consts.UN.MB), 2, RoundingMode.HALF_UP).floatValue(); + resourceStatsSize = r + " MB"; + } else if (size >= Consts.UN.KB) { + float r = bigDecimalSize.divide(new BigDecimal(Consts.UN.KB), 2, RoundingMode.HALF_UP).floatValue(); + resourceStatsSize = r + " KB"; + } else { + resourceStatsSize = size + " B"; + } + map.put("resourceStatsSize", resourceStatsSize); + + return Mono.just(JacksonUtils.writeValueAsString(map)); + } } diff --git a/fizz-core/src/main/java/we/filter/FlowControlFilter.java b/fizz-core/src/main/java/we/filter/FlowControlFilter.java index 2f767e6..637abdf 100644 --- a/fizz-core/src/main/java/we/filter/FlowControlFilter.java +++ b/fizz-core/src/main/java/we/filter/FlowControlFilter.java @@ -324,12 +324,13 @@ public class FlowControlFilter extends FizzWebFilter { List resourceConfigs = new ArrayList<>(sz); StringBuilder b = ThreadContext.getStringBuilder(); + if (hasHost) { + // String resourceId = ResourceIdUtils.buildResourceId(app, ip, node, service, path); + String resourceId = ResourceIdUtils.buildResourceId(null, null, node, null, null); + ResourceConfig resourceConfig = new ResourceConfig(resourceId, 0, 0); + resourceConfigs.add(resourceConfig); + } checkRateLimitConfigAndAddTo(resourceConfigs, b, null, null, ResourceIdUtils.NODE, null, null, null); - if (hasHost) { - String resourceId = ResourceIdUtils.buildResourceId(app, ip, node, service, path); - ResourceConfig resourceConfig = new ResourceConfig(resourceId, 0, 0); - resourceConfigs.add(resourceConfig); - } checkRateLimitConfigAndAddTo(resourceConfigs, b, null, null, null, service, null, ResourceIdUtils.SERVICE_DEFAULT); checkRateLimitConfigAndAddTo(resourceConfigs, b, null, null, null, service, path, null); @@ -396,34 +397,16 @@ public class FlowControlFilter extends FizzWebFilter { } } - /*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); - } - } - } - }*/ - if (checkDegradeRule && resourceConfigs.size() == prevSize) { CircuitBreaker cb = circuitBreakManager.getCircuitBreaker(resource); - if (cb == null) { + /*if (cb == null) { if (defaultRateLimitConfigId != null && defaultRateLimitConfigId.equals(ResourceIdUtils.SERVICE_DEFAULT)) { cb = circuitBreakManager.getCircuitBreaker(ResourceIdUtils.SERVICE_DEFAULT_RESOURCE); if (cb == null || !cb.serviceDefaultEnable) { cb = null; } } - } + }*/ if (cb != null) { rc = new ResourceConfig(resource, 0, 0); resourceConfigs.add(rc); @@ -452,12 +435,12 @@ public class FlowControlFilter extends FizzWebFilter { String service = ResourceIdUtils.getService(prev); if (service == null) { something4(resourceConfigs, rateLimitConfig.app, null, rateLimitConfig.service); - } else { + } /*else { app = ResourceIdUtils.getApp(prevPrev); if (app == null) { something4(resourceConfigs, rateLimitConfig.app, null, null); } - } + }*/ } } @@ -478,12 +461,12 @@ public class FlowControlFilter extends FizzWebFilter { String service = ResourceIdUtils.getService(prev); if (service == null) { something4(resourceConfigs, null, rateLimitConfig.ip, rateLimitConfig.service); - } else { + } /*else { ip = ResourceIdUtils.getIp(prevPrev); if (ip == null) { something4(resourceConfigs, null, rateLimitConfig.ip, null); } - } + }*/ } } } diff --git a/fizz-core/src/main/java/we/fizz/function/FuncExecutor.java b/fizz-core/src/main/java/we/fizz/function/FuncExecutor.java index a5b76a1..037544e 100644 --- a/fizz-core/src/main/java/we/fizz/function/FuncExecutor.java +++ b/fizz-core/src/main/java/we/fizz/function/FuncExecutor.java @@ -439,9 +439,9 @@ public class FuncExecutor { if (!Character.isWhitespace(argsStr.charAt(i))) { if (")".equals(String.valueOf(argsStr.charAt(i)))) { return true; - } else { + } /*else { return false; - } + }*/ } } return false; diff --git a/fizz-core/src/main/java/we/fizz/input/extension/request/RequestInput.java b/fizz-core/src/main/java/we/fizz/input/extension/request/RequestInput.java index 1964a5d..efc50dc 100644 --- a/fizz-core/src/main/java/we/fizz/input/extension/request/RequestInput.java +++ b/fizz-core/src/main/java/we/fizz/input/extension/request/RequestInput.java @@ -17,6 +17,7 @@ package we.fizz.input.extension.request; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -365,8 +366,20 @@ public class RequestInput extends RPCInput implements IInput{ // add default headers SystemConfig systemConfig = this.getCurrentApplicationContext().getBean(SystemConfig.class); for (String hdr : systemConfig.getProxySetHeaders()) { - if(inputContext.getStepContext().getInputReqHeader(hdr) != null) { - headers.addIfAbsent(hdr, (String) inputContext.getStepContext().getInputReqHeader(hdr)); + if(inputContext.getStepContext().getInputReqHeader(hdr) != null && !headers.containsKey(hdr)) { + Object o = inputContext.getStepContext().getInputReqHeader(hdr); + if (o instanceof String) { + headers.add(hdr, (String) o); + } else if (o instanceof List){ + List list = (List) o; + List vals = new ArrayList<>(); + for (Object item : list) { + if (item != null) { + vals.add(item.toString()); + } + } + headers.addAll(hdr, vals); + } } } diff --git a/fizz-core/src/main/java/we/stats/FlowStat.java b/fizz-core/src/main/java/we/stats/FlowStat.java index 1ed724c..6cb6996 100644 --- a/fizz-core/src/main/java/we/stats/FlowStat.java +++ b/fizz-core/src/main/java/we/stats/FlowStat.java @@ -17,11 +17,8 @@ package we.stats; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutorService; @@ -55,15 +52,19 @@ public class FlowStat { */ public static long INTERVAL = 1000; + public boolean cleanResource = true; + + public boolean createTimeSlotOnlyTraffic = true; + /** * A string Resource ID as key */ - public ConcurrentMap resourceStats = new ConcurrentHashMap<>(100); + public ConcurrentMap resourceStats = new ConcurrentHashMap<>(256); /** * Retention time of statistic data */ - public static long RETENTION_TIME_IN_MINUTES = 10; + public static long RETENTION_TIME_IN_MINUTES = 5; private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); private Lock w = rwl.writeLock(); @@ -76,6 +77,12 @@ public class FlowStat { runScheduleJob(); } + public FlowStat(boolean cleanResource, boolean createTimeSlotOnlyTraffic) { + this.cleanResource = cleanResource; + this.createTimeSlotOnlyTraffic = createTimeSlotOnlyTraffic; + runScheduleJob(); + } + public FlowStat(CircuitBreakManager circuitBreakManager) { this.circuitBreakManager = circuitBreakManager; runScheduleJob(); @@ -175,7 +182,7 @@ public class FlowStat { // check QPS if (maxQPS > 0) { - long total = resourceStat.getTimeSlot(curTimeSlotId).getCounter().get(); + long total = resourceStat.getTimeSlot(curTimeSlotId).getCounter(); if (total >= maxQPS) { resourceStat.incrBlockRequestToTimeSlot(curTimeSlotId); if (totalBlockFunc != null) { @@ -197,7 +204,7 @@ public class FlowStat { // increase request and concurrent request for (ResourceConfig resourceConfig : resourceConfigs) { ResourceStat resourceStat = getResourceStat(resourceConfig.getResourceId()); - long cons = resourceStat.getConcurrentRequests().incrementAndGet(); + int cons = resourceStat.getConcurrentRequests().incrementAndGet(); resourceStat.getTimeSlot(curTimeSlotId).updatePeakConcurrentReqeusts(cons); resourceStat.getTimeSlot(curTimeSlotId).incr(); } @@ -242,7 +249,7 @@ public class FlowStat { // check QPS if (maxQPS > 0) { - long total = resourceStat.getTimeSlot(curTimeSlotId).getCounter().get(); + long total = resourceStat.getTimeSlot(curTimeSlotId).getCounter(); if (total >= maxQPS) { resourceStat.incrBlockRequestToTimeSlot(curTimeSlotId); if (totalBlockFunc != null) { @@ -276,7 +283,7 @@ public class FlowStat { // increase request and concurrent request for (ResourceConfig resourceConfig : resourceConfigs) { ResourceStat resourceStat = getResourceStat(resourceConfig.getResourceId()); - long cons = resourceStat.getConcurrentRequests().incrementAndGet(); + int cons = resourceStat.getConcurrentRequests().incrementAndGet(); resourceStat.getTimeSlot(curTimeSlotId).updatePeakConcurrentReqeusts(cons); resourceStat.getTimeSlot(curTimeSlotId).incr(); } @@ -564,25 +571,63 @@ public class FlowStat { long n = FlowStat.RETENTION_TIME_IN_MINUTES * 60 * 1000 / FlowStat.INTERVAL * FlowStat.INTERVAL; long lastSlotId = stat.currentTimeSlotId() - n; while (true) { - // log.debug("housekeeping start"); long slotId = stat.currentTimeSlotId() - n; + /*if (log.isDebugEnabled()) { + log.debug("{} - {} resource stats size {}", lastSlotId, slotId, stat.resourceStats.size()); + } + Set> es = stat.resourceStats.entrySet(); + for (Entry e : es) { + String resourceId = e.getKey(); + ConcurrentMap timeSlots = e.getValue().getTimeSlots(); + if (log.isDebugEnabled()) { + log.debug("{} - {} {} has {} timeslot", lastSlotId, slotId, resourceId, timeSlots.size()); + } + }*/ for (long i = lastSlotId; i < slotId;) { Set> entrys = stat.resourceStats.entrySet(); for (Entry entry : entrys) { String resourceId = entry.getKey(); ConcurrentMap timeSlots = entry.getValue().getTimeSlots(); - // log.debug("housekeeping remove slot: resourceId={} slotId=={}", resourceId, - // i); + /*if (log.isDebugEnabled()) { + log.debug("{} - {} {} remove {} timeslot", lastSlotId, slotId, resourceId, i); + }*/ timeSlots.remove(i); } i = i + FlowStat.INTERVAL; } lastSlotId = slotId; // log.debug("housekeeping done"); + + if (cleanResource) { + long currentTimeSlot = stat.currentTimeSlotId(); + long startTimeSlot = currentTimeSlot - n; + for (Entry entry : stat.resourceStats.entrySet()) { + String resource = entry.getKey(); + if (ResourceIdUtils.NODE_RESOURCE.equals(resource)) { + continue; + } + ResourceStat resourceStat = entry.getValue(); + boolean noTraffic = true; + long timeSlot = startTimeSlot; + for (; timeSlot < currentTimeSlot; timeSlot += FlowStat.INTERVAL) { + int reqCnt = resourceStat.getTimeSlot(timeSlot).getCounter(); + if (reqCnt > 0) { + noTraffic = false; + break; + } + } + if (noTraffic) { + stat.resourceStats.remove(resource); + log.info("HousekeepJob remove {}", resource); + } + } + } + + try { - Thread.sleep(60 * 1000); + Thread.sleep(10 * 1000); } catch (Exception e) { - e.printStackTrace(); + log.error("HouseKeepJob error", e); } } } @@ -605,13 +650,18 @@ public class FlowStat { // log.debug("PeakConcurrentJob start"); Set> entrys = stat.resourceStats.entrySet(); for (Entry entry : entrys) { - String resourceId = entry.getKey(); + String resource = entry.getKey(); // log.debug("PeakConcurrentJob: resourceId={} slotId=={}", resourceId, // curTimeSlotId); - ResourceStat resourceStat = entry.getValue(); - resourceStat.getTimeSlot(curTimeSlotId); - String resource = resourceStat.getResourceId(); + ResourceStat resourceStat = entry.getValue(); + if (createTimeSlotOnlyTraffic && resourceStat.getConcurrentRequests().get() > 0) { + resourceStat.getTimeSlot(curTimeSlotId); + } else { + resourceStat.getTimeSlot(curTimeSlotId); + } + + // String resource = resourceStat.getResourceId(); CircuitBreaker cb = circuitBreakManager.getCircuitBreaker(resource); if (cb != null) { cb.correctState(curTimeSlotId, stat); @@ -623,7 +673,7 @@ public class FlowStat { try { Thread.sleep(1); } catch (Exception e) { - e.printStackTrace(); + log.error("PeakConcurrentJob error", e); } } } diff --git a/fizz-core/src/main/java/we/stats/ResourceStat.java b/fizz-core/src/main/java/we/stats/ResourceStat.java index 0c3ea81..55ce2b7 100644 --- a/fizz-core/src/main/java/we/stats/ResourceStat.java +++ b/fizz-core/src/main/java/we/stats/ResourceStat.java @@ -20,6 +20,7 @@ package we.stats; import java.math.BigDecimal; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -45,12 +46,13 @@ public class ResourceStat { /** * Request count of time slot, the beginning timestamp(timeId) as key */ - private ConcurrentMap timeSlots = new ConcurrentHashMap<>(100); + private ConcurrentMap timeSlots = new ConcurrentHashMap<>(256); /** * Concurrent requests */ - private AtomicLong concurrentRequests = new AtomicLong(0); +// private AtomicLong concurrentRequests = new AtomicLong(0); + private AtomicInteger concurrentRequests = new AtomicInteger(0); private ReentrantReadWriteLock rwl1 = new ReentrantReadWriteLock(); private ReentrantReadWriteLock rwl2 = new ReentrantReadWriteLock(); @@ -95,16 +97,16 @@ public class ResourceStat { try { boolean isExceeded = false; if (maxCon != null && maxCon.intValue() > 0) { - long n = this.concurrentRequests.get(); + int n = this.concurrentRequests.get(); if (n >= maxCon.longValue()) { isExceeded = true; this.incrBlockRequestToTimeSlot(timeSlotId); } else { - long conns = this.concurrentRequests.incrementAndGet(); + int conns = this.concurrentRequests.incrementAndGet(); this.getTimeSlot(timeSlotId).updatePeakConcurrentReqeusts(conns); } } else { - long conns = this.concurrentRequests.incrementAndGet(); + int conns = this.concurrentRequests.incrementAndGet(); this.getTimeSlot(timeSlotId).updatePeakConcurrentReqeusts(conns); } return !isExceeded; @@ -118,7 +120,7 @@ public class ResourceStat { * */ public void decrConcurrentRequest(long timeSlotId) { - long conns = this.concurrentRequests.decrementAndGet(); + int conns = this.concurrentRequests.decrementAndGet(); this.getTimeSlot(timeSlotId).updatePeakConcurrentReqeusts(conns); } @@ -127,7 +129,8 @@ public class ResourceStat { * */ public void incrBlockRequestToTimeSlot(long timeSlotId) { - this.getTimeSlot(timeSlotId).getBlockRequests().incrementAndGet(); +// this.getTimeSlot(timeSlotId).getBlockRequests().incrementAndGet(); + this.getTimeSlot(timeSlotId).incrBlockRequests(); } /** @@ -135,7 +138,8 @@ public class ResourceStat { * */ public void incrTotalBlockRequestToTimeSlot(long timeSlotId) { - this.getTimeSlot(timeSlotId).getTotalBlockRequests().incrementAndGet(); +// this.getTimeSlot(timeSlotId).getTotalBlockRequests().incrementAndGet(); + this.getTimeSlot(timeSlotId).incrTotalBlockRequests(); } /** @@ -156,7 +160,7 @@ public class ResourceStat { // } // time slot unit is one second - long total = this.getTimeSlot(timeSlotId).getCounter().get(); + long total = this.getTimeSlot(timeSlotId).getCounter(); long max = Long.valueOf(maxRPS); if (total >= max) { isExceeded = true; @@ -179,28 +183,28 @@ public class ResourceStat { } public void incrCircuitBreakNum(long timeSlot) { - getTimeSlot(timeSlot).getCircuitBreakNum().incrementAndGet(); + getTimeSlot(timeSlot).incrCircuitBreakNum(); } - public void decrCircuitBreakNum(long timeSlot) { - getTimeSlot(timeSlot).getCircuitBreakNum().decrementAndGet(); - } - - public void incrGradualResumeNum(long timeSlot) { - getTimeSlot(timeSlot).getGradualResumeNum().incrementAndGet(); - } - - public void decrGradualResumeNum(long timeSlot) { - getTimeSlot(timeSlot).getGradualResumeNum().decrementAndGet(); - } - - public void incrGradualRejectNum(long timeSlot) { - getTimeSlot(timeSlot).getGradualRejectNum().incrementAndGet(); - } - - public void decrGradualRejectNum(long timeSlot) { - getTimeSlot(timeSlot).getGradualRejectNum().decrementAndGet(); - } +// public void decrCircuitBreakNum(long timeSlot) { +// getTimeSlot(timeSlot).getCircuitBreakNum().decrementAndGet(); +// } +// +// public void incrGradualResumeNum(long timeSlot) { +// getTimeSlot(timeSlot).getGradualResumeNum().incrementAndGet(); +// } +// +// public void decrGradualResumeNum(long timeSlot) { +// getTimeSlot(timeSlot).getGradualResumeNum().decrementAndGet(); +// } +// +// public void incrGradualRejectNum(long timeSlot) { +// getTimeSlot(timeSlot).getGradualRejectNum().incrementAndGet(); +// } +// +// public void decrGradualRejectNum(long timeSlot) { +// getTimeSlot(timeSlot).getGradualRejectNum().decrementAndGet(); +// } public void incr2xxStatusCount(long timeSlot) { getTimeSlot(timeSlot).get2xxStatusCount().incrementAndGet(); @@ -267,13 +271,13 @@ public class ResourceStat { peakConcurrences = timeSlot.getPeakConcurrentRequests() > peakConcurrences ? timeSlot.getPeakConcurrentRequests() : peakConcurrences; - peakRps = timeSlot.getCounter().get() > peakRps ? timeSlot.getCounter().get() : peakRps; - totalReqs = totalReqs + timeSlot.getCounter().get(); - totalRt = totalRt + timeSlot.getTotalRt().get(); - errors = errors + timeSlot.getErrors().get(); - blockReqs = blockReqs + timeSlot.getBlockRequests().get(); - totalBlockReqs = totalBlockReqs + timeSlot.getTotalBlockRequests().get(); - compReqs = compReqs + timeSlot.getCompReqs().get(); + peakRps = timeSlot.getCounter() > peakRps ? timeSlot.getCounter() : peakRps; + totalReqs = totalReqs + timeSlot.getCounter(); + totalRt = totalRt + timeSlot.getTotalRt(); + errors = errors + timeSlot.getErrors(); + blockReqs = blockReqs + timeSlot.getBlockRequests(); + totalBlockReqs = totalBlockReqs + timeSlot.getTotalBlockRequests(); + compReqs = compReqs + timeSlot.getCompReqs(); _2xxStatus = _2xxStatus + timeSlot.get2xxStatusCount().get(); _4xxStatus = _4xxStatus + timeSlot.get4xxStatusCount().get(); @@ -333,11 +337,11 @@ public class ResourceStat { this.timeSlots = timeSlots; } - public AtomicLong getConcurrentRequests() { + public AtomicInteger getConcurrentRequests() { return concurrentRequests; } - public void setConcurrentRequests(AtomicLong concurrentRequests) { + public void setConcurrentRequests(AtomicInteger concurrentRequests) { this.concurrentRequests = concurrentRequests; } } diff --git a/fizz-core/src/main/java/we/stats/TimeSlot.java b/fizz-core/src/main/java/we/stats/TimeSlot.java index 2b89508..fc3c53f 100644 --- a/fizz-core/src/main/java/we/stats/TimeSlot.java +++ b/fizz-core/src/main/java/we/stats/TimeSlot.java @@ -37,12 +37,14 @@ public class TimeSlot { /** * Request counter */ - private AtomicLong counter = new AtomicLong(); +// private AtomicLong counter = new AtomicLong(); + private volatile int counter = 0; /** * Error request counter */ - private AtomicLong errors = new AtomicLong(); +// private AtomicLong errors = new AtomicLong(); + private volatile int errors = 0; /** * Minimum response time @@ -57,39 +59,45 @@ public class TimeSlot { /** * Total response time */ - private AtomicLong totalRt = new AtomicLong(0); +// private AtomicLong totalRt = new AtomicLong(0); + private volatile int totalRt = 0; /** * Completed Request counter */ - private AtomicLong compReqs = new AtomicLong(); - +// private AtomicLong compReqs = new AtomicLong(); + private volatile int compReqs = 0; /** * Peak concurrent requests */ - private long peakConcurrentRequests; + private volatile int peakConcurrentRequests; /** * Block requests
*/ - private AtomicLong blockRequests = new AtomicLong(0); +// private AtomicLong blockRequests = new AtomicLong(0); + private volatile int blockRequests = 0; /** * Total block requests of the resource and its underlying resources
*/ - private AtomicLong totalBlockRequests = new AtomicLong(0); - +// private AtomicLong totalBlockRequests = new AtomicLong(0); + private volatile int totalBlockRequests = 0; private AtomicReference circuitBreakState = new AtomicReference<>(CircuitBreaker.State.CLOSED); - private AtomicLong circuitBreakNum = new AtomicLong(0); +// private AtomicLong circuitBreakNum = new AtomicLong(0); + private volatile int circuitBreakNum = 0; - private AtomicLong gradualResumeNum = new AtomicLong(0); +// private AtomicLong gradualResumeNum = new AtomicLong(0); + private volatile int gradualResumeNum = 0; - private AtomicInteger resumeTrafficFactor = new AtomicInteger(1); +// private AtomicInteger resumeTrafficFactor = new AtomicInteger(1); + private volatile int resumeTrafficFactor = 1; - private AtomicLong gradualRejectNum = new AtomicLong(0); +// private AtomicLong gradualRejectNum = new AtomicLong(0); + private volatile int gradualRejectNum = 0; private AtomicInteger _2xxStatusCount = new AtomicInteger(0); @@ -119,22 +127,50 @@ public class TimeSlot { return circuitBreakState; } - public AtomicLong getCircuitBreakNum() { + public int getCircuitBreakNum() { return circuitBreakNum; } - public AtomicLong getGradualResumeNum() { + public void setCircuitBreakNum(int v) { + circuitBreakNum = v; + } + + public void incrCircuitBreakNum() { + ++circuitBreakNum; + } + + public int getGradualResumeNum() { return gradualResumeNum; } - public AtomicInteger getResumeTrafficFactor() { + public int incrGradualResumeNum() { + return ++gradualResumeNum; + } + + public int decrGradualResumeNum() { + return --gradualResumeNum; + } + + public int getResumeTrafficFactor() { return resumeTrafficFactor; } - public AtomicLong getGradualRejectNum() { + public void incrResumeTrafficFactor() { + ++resumeTrafficFactor; + } + + public int getGradualRejectNum() { return gradualRejectNum; } + public int incrGradualRejectNum() { + return ++gradualRejectNum; + } + + public int decrGradualRejectNum() { + return --gradualRejectNum; + } + public TimeSlot(long id) { this.id = id; @@ -149,7 +185,8 @@ public class TimeSlot { * */ public void incr() { - counter.incrementAndGet(); + // counter.incrementAndGet(); + ++counter; } /** @@ -159,10 +196,10 @@ public class TimeSlot { * @param isSuccess Whether the request is success or not */ public synchronized void addRequestRT(long rt, boolean isSuccess) { - totalRt.addAndGet(rt); - compReqs.incrementAndGet(); + totalRt += rt; + ++compReqs; if (!isSuccess) { - errors.incrementAndGet(); + ++errors; } min = rt < min ? rt : min; max = rt > max ? rt : max; @@ -173,7 +210,7 @@ public class TimeSlot { * * @param concurrentRequests Current concurrent requests */ - public synchronized void updatePeakConcurrentReqeusts(long concurrentRequests) { + public synchronized void updatePeakConcurrentReqeusts(int concurrentRequests) { peakConcurrentRequests = concurrentRequests > peakConcurrentRequests ? concurrentRequests : peakConcurrentRequests; } @@ -182,11 +219,11 @@ public class TimeSlot { this.id = id; } - public AtomicLong getCounter() { + public int getCounter() { return counter; } - public void setCounter(AtomicLong counter) { + public void setCounter(int counter) { this.counter = counter; } @@ -206,11 +243,11 @@ public class TimeSlot { this.max = max; } - public AtomicLong getTotalRt() { + public int getTotalRt() { return totalRt; } - public void setTotalRt(AtomicLong totalRt) { + public void setTotalRt(int totalRt) { this.totalRt = totalRt; } @@ -218,39 +255,47 @@ public class TimeSlot { return peakConcurrentRequests; } - public void setPeakConcurrentRequests(long peakConcurrentRequests) { + public void setPeakConcurrentRequests(int peakConcurrentRequests) { this.peakConcurrentRequests = peakConcurrentRequests; } - public AtomicLong getErrors() { + public int getErrors() { return errors; } - public void setErrors(AtomicLong errors) { + public void setErrors(int errors) { this.errors = errors; } - public AtomicLong getBlockRequests() { + public int getBlockRequests() { return blockRequests; } - public void setBlockRequests(AtomicLong blockRequests) { + public void setBlockRequests(int blockRequests) { this.blockRequests = blockRequests; } - public AtomicLong getCompReqs() { + public void incrBlockRequests() { + ++blockRequests; + } + + public int getCompReqs() { return compReqs; } - public void setCompReqs(AtomicLong compReqs) { + public void setCompReqs(int compReqs) { this.compReqs = compReqs; } - public AtomicLong getTotalBlockRequests() { + public int getTotalBlockRequests() { return totalBlockRequests; } - public void setTotalBlockRequests(AtomicLong totalBlockRequests) { + public void incrTotalBlockRequests() { + ++totalBlockRequests; + } + + public void setTotalBlockRequests(int totalBlockRequests) { this.totalBlockRequests = totalBlockRequests; } diff --git a/fizz-core/src/main/java/we/stats/circuitbreaker/CircuitBreakManager.java b/fizz-core/src/main/java/we/stats/circuitbreaker/CircuitBreakManager.java index 82feaf9..9a76112 100644 --- a/fizz-core/src/main/java/we/stats/circuitbreaker/CircuitBreakManager.java +++ b/fizz-core/src/main/java/we/stats/circuitbreaker/CircuitBreakManager.java @@ -264,7 +264,7 @@ 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); // correctCircuitBreakerState4error(exchange, currentTimeWindow, flowStat, resource); CircuitBreaker cb = resource2circuitBreakerMap.get(resource); @@ -290,7 +290,7 @@ public class CircuitBreakManager { } cb.correctCircuitBreakerStateAsError(currentTimeWindow, flowStat); } - } + }*/ /*public void correctCircuitBreakerState4error(ServerWebExchange exchange, long currentTimeWindow, FlowStat flowStat, String resource) { while (true) { diff --git a/fizz-core/src/main/java/we/stats/circuitbreaker/CircuitBreaker.java b/fizz-core/src/main/java/we/stats/circuitbreaker/CircuitBreaker.java index 2b1fefd..7e6a637 100644 --- a/fizz-core/src/main/java/we/stats/circuitbreaker/CircuitBreaker.java +++ b/fizz-core/src/main/java/we/stats/circuitbreaker/CircuitBreaker.java @@ -77,25 +77,31 @@ public class CircuitBreaker { public boolean permit(ResourceStat resourceStat, long currentTimeWindow) { TimeSlot timeSlot = resourceStat.getTimeSlot(currentTimeWindow); - AtomicLong resumeCount = timeSlot.getGradualResumeNum(); - AtomicInteger resumeTrafficFactor = timeSlot.getResumeTrafficFactor(); - long n = resumeTrafficFactor.get(); - if (resumeCount.incrementAndGet() <= resumeTraffic * n) { + // AtomicLong resumeCount = timeSlot.getGradualResumeNum(); + // AtomicInteger resumeTrafficFactor = timeSlot.getResumeTrafficFactor(); + // long n = resumeTrafficFactor.get(); + long n = timeSlot.getResumeTrafficFactor(); + // if (resumeCount.incrementAndGet() <= resumeTraffic * n) { + if (timeSlot.incrGradualResumeNum() <= resumeTraffic * n) { LOGGER.debug("{} current time window {}, resume traffic {}, resume traffic factor {}, resume count {}, resume current request", - resourceStat.getResourceId(), currentTimeWindow, resumeTraffic, n, resumeCount.get()); + resourceStat.getResourceId(), currentTimeWindow, resumeTraffic, n, timeSlot.getGradualResumeNum()); return true; } - AtomicLong rejectCount = timeSlot.getGradualRejectNum(); - if (rejectCount.incrementAndGet() <= rejectTraffic * n) { - resumeCount.decrementAndGet(); + // AtomicLong rejectCount = timeSlot.getGradualRejectNum(); + // if (rejectCount.incrementAndGet() <= rejectTraffic * n) { + if (timeSlot.incrGradualRejectNum() <= rejectTraffic * n) { + // resumeCount.decrementAndGet(); + timeSlot.decrGradualResumeNum(); LOGGER.debug("{} current time window {}, reject traffic {}, resume traffic factor {}, reject count {}, reject current request", - resourceStat.getResourceId(), currentTimeWindow, rejectTraffic, n, rejectCount.get()); + resourceStat.getResourceId(), currentTimeWindow, rejectTraffic, n, timeSlot.getGradualRejectNum()); return false; } - rejectCount.decrementAndGet(); - resumeTrafficFactor.incrementAndGet(); + // rejectCount.decrementAndGet(); + timeSlot.decrGradualRejectNum(); + // resumeTrafficFactor.incrementAndGet(); + timeSlot.incrResumeTrafficFactor(); LOGGER.debug("{} current time window {}, resume traffic {}, reject traffic {}, resume traffic factor {}, resume count {}, reject count {}, resume current request", - resourceStat.getResourceId(), currentTimeWindow, resumeTraffic, rejectTraffic, n, resumeCount.get(), rejectCount.get()); + resourceStat.getResourceId(), currentTimeWindow, resumeTraffic, rejectTraffic, n, timeSlot.getGradualResumeNum(), timeSlot.getGradualRejectNum()); return true; } @@ -286,7 +292,7 @@ public class CircuitBreaker { } } - public void correctCircuitBreakerStateAsError(long currentTimeWindow, FlowStat flowStat) { + /*public void correctCircuitBreakerStateAsError(long currentTimeWindow, FlowStat flowStat) { if (stateRef.get() == State.CLOSED) { long endTimeWindow = currentTimeWindow + 1000; // TimeWindowStat timeWindowStat = flowStat.getTimeWindowStat(resource, endTimeWindow - monitorDuration, endTimeWindow); @@ -309,16 +315,17 @@ public class CircuitBreaker { } } } - } + }*/ public boolean transit(State current, State target, long currentTimeWindow, FlowStat flowStat) { if (stateRef.compareAndSet(current, target)) { - stateStartTime = currentTimeWindow; ResourceStat resourceStat = flowStat.getResourceStat(resource); - AtomicLong circuitBreakNum = resourceStat.getTimeSlot(currentTimeWindow).getCircuitBreakNum(); - circuitBreakNum.set(0); + /*AtomicLong circuitBreakNum = resourceStat.getTimeSlot(currentTimeWindow).getCircuitBreakNum(); + circuitBreakNum.set(0);*/ + resourceStat.getTimeSlot(currentTimeWindow).setCircuitBreakNum(0); resourceStat.updateCircuitBreakState(currentTimeWindow, current, target); LOGGER.debug("transit {} current time window {} from {} which start at {} to {}", resource, currentTimeWindow, current, stateStartTime, target); + stateStartTime = currentTimeWindow; return true; } return false; diff --git a/fizz-core/src/test/java/we/stats/FlowStatTests.java b/fizz-core/src/test/java/we/stats/FlowStatTests.java index 4cd07ee..238541b 100644 --- a/fizz-core/src/test/java/we/stats/FlowStatTests.java +++ b/fizz-core/src/test/java/we/stats/FlowStatTests.java @@ -39,7 +39,7 @@ import we.util.JacksonUtils; */ public class FlowStatTests { - private FlowStat stat = new FlowStat(); + private FlowStat stat = new FlowStat(false, false); class FlowRuleCase { public int threads = 3; diff --git a/fizz-core/src/test/java/we/stats/circuitbreaker/CircuitBreakManagerTests.java b/fizz-core/src/test/java/we/stats/circuitbreaker/CircuitBreakManagerTests.java index 543d4f5..4758b66 100644 --- a/fizz-core/src/test/java/we/stats/circuitbreaker/CircuitBreakManagerTests.java +++ b/fizz-core/src/test/java/we/stats/circuitbreaker/CircuitBreakManagerTests.java @@ -68,6 +68,8 @@ public class CircuitBreakManagerTests { @Test void permitTest() { FlowStat flowStat = new FlowStat(circuitBreakManager); + flowStat.cleanResource = false; + flowStat.createTimeSlotOnlyTraffic = false; long currentTimeWindow = flowStat.currentTimeSlotId(); MockServerHttpRequest mockServerHttpRequest = MockServerHttpRequest.get("/xxx").build(); @@ -92,8 +94,8 @@ public class CircuitBreakManagerTests { ResourceStat resourceStat = flowStat.getResourceStat(cb.resource); TimeSlot timeSlot = resourceStat.getTimeSlot(currentTimeWindow); - timeSlot.getCompReqs().set(200); - timeSlot.getErrors().set(11); + timeSlot.setCompReqs(200); + timeSlot.setErrors(11); boolean permit = circuitBreakManager.permit(mockServerWebExchange, currentTimeWindow, flowStat, service, path); Assertions.assertFalse(permit); @@ -101,6 +103,6 @@ public class CircuitBreakManagerTests { permit = circuitBreakManager.permit(mockServerWebExchange, currentTimeWindow, flowStat, service, path); Assertions.assertFalse(permit); Assertions.assertEquals(CircuitBreaker.State.OPEN, timeSlot.getCircuitBreakState().get()); - Assertions.assertEquals(2, timeSlot.getCircuitBreakNum().get()); + Assertions.assertEquals(2, timeSlot.getCircuitBreakNum()); } } diff --git a/fizz-plugin/pom.xml b/fizz-plugin/pom.xml index c739bf2..03dc127 100644 --- a/fizz-plugin/pom.xml +++ b/fizz-plugin/pom.xml @@ -5,7 +5,7 @@ fizz-gateway-community com.fizzgate - 2.6.1 + 2.6.2 ../pom.xml 4.0.0 diff --git a/fizz-spring-boot-starter/pom.xml b/fizz-spring-boot-starter/pom.xml index 4640af7..e3f5a22 100644 --- a/fizz-spring-boot-starter/pom.xml +++ b/fizz-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ fizz-gateway-community com.fizzgate - 2.6.1 + 2.6.2 ../pom.xml 4.0.0 diff --git a/pom.xml b/pom.xml index 6ef2c0d..f9177a0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,11 +6,11 @@ 2.2.13.RELEASE - 5.2.20.RELEASE + 5.2.21.RELEASE Dysprosium-SR25 5.3.7.RELEASE 2.2.7.RELEASE - 4.1.75.Final + 4.1.76.Final 4.4.15 2.17.2 1.7.36 @@ -37,7 +37,7 @@ fizz-gateway-community ${project.artifactId} fizz gateway community - 2.6.1 + 2.6.2 pom fizz-common @@ -69,6 +69,12 @@ + + org.openjdk.jol + jol-core + 0.16 + + com.lmax disruptor