Sync develop

This commit is contained in:
hongqiaowei
2022-04-27 23:09:01 +08:00
committed by GitHub
21 changed files with 393 additions and 164 deletions

View File

@@ -4,7 +4,7 @@ English | [简体中文](./README.md)
<a href="https://www.fizzgate.com"><img src="https://raw.githubusercontent.com/wiki/wehotel/fizz-gateway-community/img/icon-color.png" width="70%"></a> <a href="https://www.fizzgate.com"><img src="https://raw.githubusercontent.com/wiki/wehotel/fizz-gateway-community/img/icon-color.png" width="70%"></a>
</p> </p>
<p> <p>
<img alt="Version" src="https://img.shields.io/badge/version-2.6.1-blue.svg?cacheSeconds=2592000" /> <img alt="Version" src="https://img.shields.io/badge/version-2.6.2-blue.svg?cacheSeconds=2592000" />
<a href="http://www.fizzgate.com/fizz-gateway-community/" target="_blank"> <a href="http://www.fizzgate.com/fizz-gateway-community/" target="_blank">
<img alt="Documentation" src="https://img.shields.io/badge/documentation-yes-brightgreen.svg" /> <img alt="Documentation" src="https://img.shields.io/badge/documentation-yes-brightgreen.svg" />
</a> </a>
@@ -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.5.2 | v2.5.2 |
| v2.6.0 | v2.6.0 | | v2.6.0 | v2.6.0 |
| v2.6.1 | v2.6.1 | | 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 Please download the corresponding management backend version according to the version of the community version

View File

@@ -3,7 +3,7 @@
<a href="https://www.fizzgate.com"><img src="https://raw.githubusercontent.com/wiki/wehotel/fizz-gateway-community/img/icon-color.png" width="70%"></a> <a href="https://www.fizzgate.com"><img src="https://raw.githubusercontent.com/wiki/wehotel/fizz-gateway-community/img/icon-color.png" width="70%"></a>
</p> </p>
<p> <p>
<img alt="Version" src="https://img.shields.io/badge/version-2.6.1-blue.svg?cacheSeconds=2592000" /> <img alt="Version" src="https://img.shields.io/badge/version-2.6.2-blue.svg?cacheSeconds=2592000" />
<a href="http://www.fizzgate.com/fizz-gateway-community/" target="_blank"> <a href="http://www.fizzgate.com/fizz-gateway-community/" target="_blank">
<img alt="Documentation" src="https://img.shields.io/badge/documentation-yes-brightgreen.svg" /> <img alt="Documentation" src="https://img.shields.io/badge/documentation-yes-brightgreen.svg" />
</a> </a>
@@ -120,6 +120,7 @@ API地址http://demo.fizzgate.com/proxy/[服务名]/[API_Path]
| v2.5.2 | v2.5.2 | | v2.5.2 | v2.5.2 |
| v2.6.0 | v2.6.0 | | v2.6.0 | v2.6.0 |
| v2.6.1 | v2.6.1 | | v2.6.1 | v2.6.1 |
| v2.6.2 | v2.6.2 |
请根据社区版的版本下载对应的管理后台版本 请根据社区版的版本下载对应的管理后台版本

View File

@@ -2,7 +2,7 @@ version: "3.6"
services: services:
fizz-mysql: fizz-mysql:
image: "fizzgate/fizz-mysql:2.6.1" image: "fizzgate/fizz-mysql:2.6.2"
container_name: fizz-mysql container_name: fizz-mysql
restart: always restart: always
hostname: fizz-mysql hostname: fizz-mysql
@@ -27,7 +27,7 @@ services:
- fizz - fizz
fizz-gateway-community: fizz-gateway-community:
image: "fizzgate/fizz-gateway-community:2.6.1" image: "fizzgate/fizz-gateway-community:2.6.2"
container_name: fizz-gateway-community container_name: fizz-gateway-community
restart: always restart: always
hostname: fizz-gateway-community hostname: fizz-gateway-community
@@ -48,7 +48,7 @@ services:
- fizz - fizz
fizz-manager-professional: fizz-manager-professional:
image: "fizzgate/fizz-manager-professional:2.6.1" image: "fizzgate/fizz-manager-professional:2.6.2"
container_name: fizz-manager-professional container_name: fizz-manager-professional
restart: always restart: always
hostname: fizz-manager-professional hostname: fizz-manager-professional

View File

@@ -12,15 +12,15 @@
<groupId>com.fizzgate</groupId> <groupId>com.fizzgate</groupId>
<artifactId>fizz-bootstrap</artifactId> <artifactId>fizz-bootstrap</artifactId>
<version>2.6.1</version> <version>2.6.2</version>
<properties> <properties>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<spring-framework.version>5.2.20.RELEASE</spring-framework.version> <spring-framework.version>5.2.21.RELEASE</spring-framework.version>
<spring-session-bom.version>Dragonfruit-SR3</spring-session-bom.version> <spring-session-bom.version>Dragonfruit-SR3</spring-session-bom.version>
<reactor-bom.version>Dysprosium-SR25</reactor-bom.version> <reactor-bom.version>Dysprosium-SR25</reactor-bom.version>
<lettuce.version>5.3.7.RELEASE</lettuce.version> <lettuce.version>5.3.7.RELEASE</lettuce.version>
<netty.version>4.1.75.Final</netty.version> <netty.version>4.1.76.Final</netty.version>
<httpcore.version>4.4.15</httpcore.version> <httpcore.version>4.4.15</httpcore.version>
<log4j2.version>2.17.2</log4j2.version> <log4j2.version>2.17.2</log4j2.version>
<slf4j.version>1.7.36</slf4j.version> <slf4j.version>1.7.36</slf4j.version>

View File

@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>fizz-gateway-community</artifactId> <artifactId>fizz-gateway-community</artifactId>
<groupId>com.fizzgate</groupId> <groupId>com.fizzgate</groupId>
<version>2.6.1</version> <version>2.6.2</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@@ -17,6 +17,11 @@
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId> <artifactId>spring-cloud-context</artifactId>

View File

@@ -101,6 +101,12 @@ public final class Consts {
public static final String PROD = "prod"; 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_SERVER = "http_server";
public static final String HTTP_CLIENT = "http_client"; public static final String HTTP_CLIENT = "http_client";
public static final String MYSQL = "mysql"; public static final String MYSQL = "mysql";

View File

@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>fizz-gateway-community</artifactId> <artifactId>fizz-gateway-community</artifactId>
<groupId>com.fizzgate</groupId> <groupId>com.fizzgate</groupId>
<version>2.6.1</version> <version>2.6.2</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -17,6 +17,7 @@
package we.controller; package we.controller;
import org.openjdk.jol.info.GraphLayout;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; 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.ApiConfigService;
import we.plugin.auth.AppService; import we.plugin.auth.AppService;
import we.plugin.auth.GatewayGroupService; import we.plugin.auth.GatewayGroupService;
import we.stats.FlowStat;
import we.stats.ResourceStat;
import we.stats.circuitbreaker.CircuitBreakManager; import we.stats.circuitbreaker.CircuitBreakManager;
import we.stats.ratelimit.ResourceRateLimitConfig;
import we.stats.ratelimit.ResourceRateLimitConfigService; import we.stats.ratelimit.ResourceRateLimitConfigService;
import we.util.Consts;
import we.util.JacksonUtils; import we.util.JacksonUtils;
import we.util.ResourceIdUtils;
import javax.annotation.Resource; 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 * @author hongqiaowei
@@ -62,6 +74,9 @@ public class CacheCheckController {
@Resource @Resource
private CircuitBreakManager circuitBreakManager; private CircuitBreakManager circuitBreakManager;
@Resource
private FlowStat flowStat;
@GetMapping("/gatewayGroups") @GetMapping("/gatewayGroups")
public Mono<String> gatewayGroups(ServerWebExchange exchange) { public Mono<String> gatewayGroups(ServerWebExchange exchange) {
return Mono.just(JacksonUtils.writeValueAsString(gatewayGroupService.gatewayGroupMap)); return Mono.just(JacksonUtils.writeValueAsString(gatewayGroupService.gatewayGroupMap));
@@ -101,4 +116,95 @@ public class CacheCheckController {
public Mono<String> circuitBreakers(ServerWebExchange exchange) { public Mono<String> circuitBreakers(ServerWebExchange exchange) {
return Mono.just(JacksonUtils.writeValueAsString(circuitBreakManager.getResource2circuitBreakerMap())); return Mono.just(JacksonUtils.writeValueAsString(circuitBreakManager.getResource2circuitBreakerMap()));
} }
@GetMapping("/resourceStats")
public Mono<String> resourceStats(ServerWebExchange exchange) {
Map<String, Object> map = new HashMap<>();
int nodeCnt = 0, serviceDefaultCnt = 0, serviceCnt = 0, servicePathCnt = 0, appDefaultCnt = 0, appCnt = 0, ipCnt = 0, hostCnt = 0;
ConcurrentMap<String, ResourceStat> resourceStats = flowStat.resourceStats;
Set<Map.Entry<String, ResourceStat>> entrySet = resourceStats.entrySet();
for (Map.Entry<String, ResourceStat> 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));
}
} }

View File

@@ -324,12 +324,13 @@ public class FlowControlFilter extends FizzWebFilter {
List<ResourceConfig> resourceConfigs = new ArrayList<>(sz); List<ResourceConfig> resourceConfigs = new ArrayList<>(sz);
StringBuilder b = ThreadContext.getStringBuilder(); 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); 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, null, ResourceIdUtils.SERVICE_DEFAULT);
checkRateLimitConfigAndAddTo(resourceConfigs, b, null, null, null, service, path, null); 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) { if (checkDegradeRule && resourceConfigs.size() == prevSize) {
CircuitBreaker cb = circuitBreakManager.getCircuitBreaker(resource); CircuitBreaker cb = circuitBreakManager.getCircuitBreaker(resource);
if (cb == null) { /*if (cb == null) {
if (defaultRateLimitConfigId != null && defaultRateLimitConfigId.equals(ResourceIdUtils.SERVICE_DEFAULT)) { if (defaultRateLimitConfigId != null && defaultRateLimitConfigId.equals(ResourceIdUtils.SERVICE_DEFAULT)) {
cb = circuitBreakManager.getCircuitBreaker(ResourceIdUtils.SERVICE_DEFAULT_RESOURCE); cb = circuitBreakManager.getCircuitBreaker(ResourceIdUtils.SERVICE_DEFAULT_RESOURCE);
if (cb == null || !cb.serviceDefaultEnable) { if (cb == null || !cb.serviceDefaultEnable) {
cb = null; cb = null;
} }
} }
} }*/
if (cb != null) { if (cb != null) {
rc = new ResourceConfig(resource, 0, 0); rc = new ResourceConfig(resource, 0, 0);
resourceConfigs.add(rc); resourceConfigs.add(rc);
@@ -452,12 +435,12 @@ public class FlowControlFilter extends FizzWebFilter {
String service = ResourceIdUtils.getService(prev); String service = ResourceIdUtils.getService(prev);
if (service == null) { if (service == null) {
something4(resourceConfigs, rateLimitConfig.app, null, rateLimitConfig.service); something4(resourceConfigs, rateLimitConfig.app, null, rateLimitConfig.service);
} else { } /*else {
app = ResourceIdUtils.getApp(prevPrev); app = ResourceIdUtils.getApp(prevPrev);
if (app == null) { if (app == null) {
something4(resourceConfigs, rateLimitConfig.app, null, null); something4(resourceConfigs, rateLimitConfig.app, null, null);
} }
} }*/
} }
} }
@@ -478,12 +461,12 @@ public class FlowControlFilter extends FizzWebFilter {
String service = ResourceIdUtils.getService(prev); String service = ResourceIdUtils.getService(prev);
if (service == null) { if (service == null) {
something4(resourceConfigs, null, rateLimitConfig.ip, rateLimitConfig.service); something4(resourceConfigs, null, rateLimitConfig.ip, rateLimitConfig.service);
} else { } /*else {
ip = ResourceIdUtils.getIp(prevPrev); ip = ResourceIdUtils.getIp(prevPrev);
if (ip == null) { if (ip == null) {
something4(resourceConfigs, null, rateLimitConfig.ip, null); something4(resourceConfigs, null, rateLimitConfig.ip, null);
} }
} }*/
} }
} }
} }

View File

@@ -439,9 +439,9 @@ public class FuncExecutor {
if (!Character.isWhitespace(argsStr.charAt(i))) { if (!Character.isWhitespace(argsStr.charAt(i))) {
if (")".equals(String.valueOf(argsStr.charAt(i)))) { if (")".equals(String.valueOf(argsStr.charAt(i)))) {
return true; return true;
} else { } /*else {
return false; return false;
} }*/
} }
} }
return false; return false;

View File

@@ -17,6 +17,7 @@
package we.fizz.input.extension.request; package we.fizz.input.extension.request;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -365,8 +366,20 @@ public class RequestInput extends RPCInput implements IInput{
// add default headers // add default headers
SystemConfig systemConfig = this.getCurrentApplicationContext().getBean(SystemConfig.class); SystemConfig systemConfig = this.getCurrentApplicationContext().getBean(SystemConfig.class);
for (String hdr : systemConfig.getProxySetHeaders()) { for (String hdr : systemConfig.getProxySetHeaders()) {
if(inputContext.getStepContext().getInputReqHeader(hdr) != null) { if(inputContext.getStepContext().getInputReqHeader(hdr) != null && !headers.containsKey(hdr)) {
headers.addIfAbsent(hdr, (String) inputContext.getStepContext().getInputReqHeader(hdr)); Object o = inputContext.getStepContext().getInputReqHeader(hdr);
if (o instanceof String) {
headers.add(hdr, (String) o);
} else if (o instanceof List){
List<Object> list = (List<Object>) o;
List<String> vals = new ArrayList<>();
for (Object item : list) {
if (item != null) {
vals.add(item.toString());
}
}
headers.addAll(hdr, vals);
}
} }
} }

View File

@@ -17,11 +17,8 @@
package we.stats; package we.stats;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@@ -55,15 +52,19 @@ public class FlowStat {
*/ */
public static long INTERVAL = 1000; public static long INTERVAL = 1000;
public boolean cleanResource = true;
public boolean createTimeSlotOnlyTraffic = true;
/** /**
* A string Resource ID as key * A string Resource ID as key
*/ */
public ConcurrentMap<String, ResourceStat> resourceStats = new ConcurrentHashMap<>(100); public ConcurrentMap<String, ResourceStat> resourceStats = new ConcurrentHashMap<>(256);
/** /**
* Retention time of statistic data * 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 ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private Lock w = rwl.writeLock(); private Lock w = rwl.writeLock();
@@ -76,6 +77,12 @@ public class FlowStat {
runScheduleJob(); runScheduleJob();
} }
public FlowStat(boolean cleanResource, boolean createTimeSlotOnlyTraffic) {
this.cleanResource = cleanResource;
this.createTimeSlotOnlyTraffic = createTimeSlotOnlyTraffic;
runScheduleJob();
}
public FlowStat(CircuitBreakManager circuitBreakManager) { public FlowStat(CircuitBreakManager circuitBreakManager) {
this.circuitBreakManager = circuitBreakManager; this.circuitBreakManager = circuitBreakManager;
runScheduleJob(); runScheduleJob();
@@ -175,7 +182,7 @@ public class FlowStat {
// check QPS // check QPS
if (maxQPS > 0) { if (maxQPS > 0) {
long total = resourceStat.getTimeSlot(curTimeSlotId).getCounter().get(); long total = resourceStat.getTimeSlot(curTimeSlotId).getCounter();
if (total >= maxQPS) { if (total >= maxQPS) {
resourceStat.incrBlockRequestToTimeSlot(curTimeSlotId); resourceStat.incrBlockRequestToTimeSlot(curTimeSlotId);
if (totalBlockFunc != null) { if (totalBlockFunc != null) {
@@ -197,7 +204,7 @@ public class FlowStat {
// increase request and concurrent request // increase request and concurrent request
for (ResourceConfig resourceConfig : resourceConfigs) { for (ResourceConfig resourceConfig : resourceConfigs) {
ResourceStat resourceStat = getResourceStat(resourceConfig.getResourceId()); ResourceStat resourceStat = getResourceStat(resourceConfig.getResourceId());
long cons = resourceStat.getConcurrentRequests().incrementAndGet(); int cons = resourceStat.getConcurrentRequests().incrementAndGet();
resourceStat.getTimeSlot(curTimeSlotId).updatePeakConcurrentReqeusts(cons); resourceStat.getTimeSlot(curTimeSlotId).updatePeakConcurrentReqeusts(cons);
resourceStat.getTimeSlot(curTimeSlotId).incr(); resourceStat.getTimeSlot(curTimeSlotId).incr();
} }
@@ -242,7 +249,7 @@ public class FlowStat {
// check QPS // check QPS
if (maxQPS > 0) { if (maxQPS > 0) {
long total = resourceStat.getTimeSlot(curTimeSlotId).getCounter().get(); long total = resourceStat.getTimeSlot(curTimeSlotId).getCounter();
if (total >= maxQPS) { if (total >= maxQPS) {
resourceStat.incrBlockRequestToTimeSlot(curTimeSlotId); resourceStat.incrBlockRequestToTimeSlot(curTimeSlotId);
if (totalBlockFunc != null) { if (totalBlockFunc != null) {
@@ -276,7 +283,7 @@ public class FlowStat {
// increase request and concurrent request // increase request and concurrent request
for (ResourceConfig resourceConfig : resourceConfigs) { for (ResourceConfig resourceConfig : resourceConfigs) {
ResourceStat resourceStat = getResourceStat(resourceConfig.getResourceId()); ResourceStat resourceStat = getResourceStat(resourceConfig.getResourceId());
long cons = resourceStat.getConcurrentRequests().incrementAndGet(); int cons = resourceStat.getConcurrentRequests().incrementAndGet();
resourceStat.getTimeSlot(curTimeSlotId).updatePeakConcurrentReqeusts(cons); resourceStat.getTimeSlot(curTimeSlotId).updatePeakConcurrentReqeusts(cons);
resourceStat.getTimeSlot(curTimeSlotId).incr(); 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 n = FlowStat.RETENTION_TIME_IN_MINUTES * 60 * 1000 / FlowStat.INTERVAL * FlowStat.INTERVAL;
long lastSlotId = stat.currentTimeSlotId() - n; long lastSlotId = stat.currentTimeSlotId() - n;
while (true) { while (true) {
// log.debug("housekeeping start");
long slotId = stat.currentTimeSlotId() - n; long slotId = stat.currentTimeSlotId() - n;
/*if (log.isDebugEnabled()) {
log.debug("{} - {} resource stats size {}", lastSlotId, slotId, stat.resourceStats.size());
}
Set<Map.Entry<String, ResourceStat>> es = stat.resourceStats.entrySet();
for (Entry<String, ResourceStat> e : es) {
String resourceId = e.getKey();
ConcurrentMap<Long, TimeSlot> timeSlots = e.getValue().getTimeSlots();
if (log.isDebugEnabled()) {
log.debug("{} - {} {} has {} timeslot", lastSlotId, slotId, resourceId, timeSlots.size());
}
}*/
for (long i = lastSlotId; i < slotId;) { for (long i = lastSlotId; i < slotId;) {
Set<Map.Entry<String, ResourceStat>> entrys = stat.resourceStats.entrySet(); Set<Map.Entry<String, ResourceStat>> entrys = stat.resourceStats.entrySet();
for (Entry<String, ResourceStat> entry : entrys) { for (Entry<String, ResourceStat> entry : entrys) {
String resourceId = entry.getKey(); String resourceId = entry.getKey();
ConcurrentMap<Long, TimeSlot> timeSlots = entry.getValue().getTimeSlots(); ConcurrentMap<Long, TimeSlot> timeSlots = entry.getValue().getTimeSlots();
// log.debug("housekeeping remove slot: resourceId={} slotId=={}", resourceId, /*if (log.isDebugEnabled()) {
// i); log.debug("{} - {} {} remove {} timeslot", lastSlotId, slotId, resourceId, i);
}*/
timeSlots.remove(i); timeSlots.remove(i);
} }
i = i + FlowStat.INTERVAL; i = i + FlowStat.INTERVAL;
} }
lastSlotId = slotId; lastSlotId = slotId;
// log.debug("housekeeping done"); // log.debug("housekeeping done");
if (cleanResource) {
long currentTimeSlot = stat.currentTimeSlotId();
long startTimeSlot = currentTimeSlot - n;
for (Entry<String, ResourceStat> 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 { try {
Thread.sleep(60 * 1000); Thread.sleep(10 * 1000);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); log.error("HouseKeepJob error", e);
} }
} }
} }
@@ -605,13 +650,18 @@ public class FlowStat {
// log.debug("PeakConcurrentJob start"); // log.debug("PeakConcurrentJob start");
Set<Map.Entry<String, ResourceStat>> entrys = stat.resourceStats.entrySet(); Set<Map.Entry<String, ResourceStat>> entrys = stat.resourceStats.entrySet();
for (Entry<String, ResourceStat> entry : entrys) { for (Entry<String, ResourceStat> entry : entrys) {
String resourceId = entry.getKey(); String resource = entry.getKey();
// log.debug("PeakConcurrentJob: resourceId={} slotId=={}", resourceId, // log.debug("PeakConcurrentJob: resourceId={} slotId=={}", resourceId,
// curTimeSlotId); // 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); CircuitBreaker cb = circuitBreakManager.getCircuitBreaker(resource);
if (cb != null) { if (cb != null) {
cb.correctState(curTimeSlotId, stat); cb.correctState(curTimeSlotId, stat);
@@ -623,7 +673,7 @@ public class FlowStat {
try { try {
Thread.sleep(1); Thread.sleep(1);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); log.error("PeakConcurrentJob error", e);
} }
} }
} }

View File

@@ -20,6 +20,7 @@ package we.stats;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -45,12 +46,13 @@ public class ResourceStat {
/** /**
* Request count of time slot, the beginning timestamp(timeId) as key * Request count of time slot, the beginning timestamp(timeId) as key
*/ */
private ConcurrentMap<Long, TimeSlot> timeSlots = new ConcurrentHashMap<>(100); private ConcurrentMap<Long, TimeSlot> timeSlots = new ConcurrentHashMap<>(256);
/** /**
* Concurrent requests * 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 rwl1 = new ReentrantReadWriteLock();
private ReentrantReadWriteLock rwl2 = new ReentrantReadWriteLock(); private ReentrantReadWriteLock rwl2 = new ReentrantReadWriteLock();
@@ -95,16 +97,16 @@ public class ResourceStat {
try { try {
boolean isExceeded = false; boolean isExceeded = false;
if (maxCon != null && maxCon.intValue() > 0) { if (maxCon != null && maxCon.intValue() > 0) {
long n = this.concurrentRequests.get(); int n = this.concurrentRequests.get();
if (n >= maxCon.longValue()) { if (n >= maxCon.longValue()) {
isExceeded = true; isExceeded = true;
this.incrBlockRequestToTimeSlot(timeSlotId); this.incrBlockRequestToTimeSlot(timeSlotId);
} else { } else {
long conns = this.concurrentRequests.incrementAndGet(); int conns = this.concurrentRequests.incrementAndGet();
this.getTimeSlot(timeSlotId).updatePeakConcurrentReqeusts(conns); this.getTimeSlot(timeSlotId).updatePeakConcurrentReqeusts(conns);
} }
} else { } else {
long conns = this.concurrentRequests.incrementAndGet(); int conns = this.concurrentRequests.incrementAndGet();
this.getTimeSlot(timeSlotId).updatePeakConcurrentReqeusts(conns); this.getTimeSlot(timeSlotId).updatePeakConcurrentReqeusts(conns);
} }
return !isExceeded; return !isExceeded;
@@ -118,7 +120,7 @@ public class ResourceStat {
* *
*/ */
public void decrConcurrentRequest(long timeSlotId) { public void decrConcurrentRequest(long timeSlotId) {
long conns = this.concurrentRequests.decrementAndGet(); int conns = this.concurrentRequests.decrementAndGet();
this.getTimeSlot(timeSlotId).updatePeakConcurrentReqeusts(conns); this.getTimeSlot(timeSlotId).updatePeakConcurrentReqeusts(conns);
} }
@@ -127,7 +129,8 @@ public class ResourceStat {
* *
*/ */
public void incrBlockRequestToTimeSlot(long timeSlotId) { 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) { 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 // time slot unit is one second
long total = this.getTimeSlot(timeSlotId).getCounter().get(); long total = this.getTimeSlot(timeSlotId).getCounter();
long max = Long.valueOf(maxRPS); long max = Long.valueOf(maxRPS);
if (total >= max) { if (total >= max) {
isExceeded = true; isExceeded = true;
@@ -179,28 +183,28 @@ public class ResourceStat {
} }
public void incrCircuitBreakNum(long timeSlot) { public void incrCircuitBreakNum(long timeSlot) {
getTimeSlot(timeSlot).getCircuitBreakNum().incrementAndGet(); getTimeSlot(timeSlot).incrCircuitBreakNum();
} }
public void decrCircuitBreakNum(long timeSlot) { // public void decrCircuitBreakNum(long timeSlot) {
getTimeSlot(timeSlot).getCircuitBreakNum().decrementAndGet(); // getTimeSlot(timeSlot).getCircuitBreakNum().decrementAndGet();
} // }
//
public void incrGradualResumeNum(long timeSlot) { // public void incrGradualResumeNum(long timeSlot) {
getTimeSlot(timeSlot).getGradualResumeNum().incrementAndGet(); // getTimeSlot(timeSlot).getGradualResumeNum().incrementAndGet();
} // }
//
public void decrGradualResumeNum(long timeSlot) { // public void decrGradualResumeNum(long timeSlot) {
getTimeSlot(timeSlot).getGradualResumeNum().decrementAndGet(); // getTimeSlot(timeSlot).getGradualResumeNum().decrementAndGet();
} // }
//
public void incrGradualRejectNum(long timeSlot) { // public void incrGradualRejectNum(long timeSlot) {
getTimeSlot(timeSlot).getGradualRejectNum().incrementAndGet(); // getTimeSlot(timeSlot).getGradualRejectNum().incrementAndGet();
} // }
//
public void decrGradualRejectNum(long timeSlot) { // public void decrGradualRejectNum(long timeSlot) {
getTimeSlot(timeSlot).getGradualRejectNum().decrementAndGet(); // getTimeSlot(timeSlot).getGradualRejectNum().decrementAndGet();
} // }
public void incr2xxStatusCount(long timeSlot) { public void incr2xxStatusCount(long timeSlot) {
getTimeSlot(timeSlot).get2xxStatusCount().incrementAndGet(); getTimeSlot(timeSlot).get2xxStatusCount().incrementAndGet();
@@ -267,13 +271,13 @@ public class ResourceStat {
peakConcurrences = timeSlot.getPeakConcurrentRequests() > peakConcurrences peakConcurrences = timeSlot.getPeakConcurrentRequests() > peakConcurrences
? timeSlot.getPeakConcurrentRequests() ? timeSlot.getPeakConcurrentRequests()
: peakConcurrences; : peakConcurrences;
peakRps = timeSlot.getCounter().get() > peakRps ? timeSlot.getCounter().get() : peakRps; peakRps = timeSlot.getCounter() > peakRps ? timeSlot.getCounter() : peakRps;
totalReqs = totalReqs + timeSlot.getCounter().get(); totalReqs = totalReqs + timeSlot.getCounter();
totalRt = totalRt + timeSlot.getTotalRt().get(); totalRt = totalRt + timeSlot.getTotalRt();
errors = errors + timeSlot.getErrors().get(); errors = errors + timeSlot.getErrors();
blockReqs = blockReqs + timeSlot.getBlockRequests().get(); blockReqs = blockReqs + timeSlot.getBlockRequests();
totalBlockReqs = totalBlockReqs + timeSlot.getTotalBlockRequests().get(); totalBlockReqs = totalBlockReqs + timeSlot.getTotalBlockRequests();
compReqs = compReqs + timeSlot.getCompReqs().get(); compReqs = compReqs + timeSlot.getCompReqs();
_2xxStatus = _2xxStatus + timeSlot.get2xxStatusCount().get(); _2xxStatus = _2xxStatus + timeSlot.get2xxStatusCount().get();
_4xxStatus = _4xxStatus + timeSlot.get4xxStatusCount().get(); _4xxStatus = _4xxStatus + timeSlot.get4xxStatusCount().get();
@@ -333,11 +337,11 @@ public class ResourceStat {
this.timeSlots = timeSlots; this.timeSlots = timeSlots;
} }
public AtomicLong getConcurrentRequests() { public AtomicInteger getConcurrentRequests() {
return concurrentRequests; return concurrentRequests;
} }
public void setConcurrentRequests(AtomicLong concurrentRequests) { public void setConcurrentRequests(AtomicInteger concurrentRequests) {
this.concurrentRequests = concurrentRequests; this.concurrentRequests = concurrentRequests;
} }
} }

View File

@@ -37,12 +37,14 @@ public class TimeSlot {
/** /**
* Request counter * Request counter
*/ */
private AtomicLong counter = new AtomicLong(); // private AtomicLong counter = new AtomicLong();
private volatile int counter = 0;
/** /**
* Error request counter * Error request counter
*/ */
private AtomicLong errors = new AtomicLong(); // private AtomicLong errors = new AtomicLong();
private volatile int errors = 0;
/** /**
* Minimum response time * Minimum response time
@@ -57,39 +59,45 @@ public class TimeSlot {
/** /**
* Total response time * Total response time
*/ */
private AtomicLong totalRt = new AtomicLong(0); // private AtomicLong totalRt = new AtomicLong(0);
private volatile int totalRt = 0;
/** /**
* Completed Request counter * Completed Request counter
*/ */
private AtomicLong compReqs = new AtomicLong(); // private AtomicLong compReqs = new AtomicLong();
private volatile int compReqs = 0;
/** /**
* Peak concurrent requests * Peak concurrent requests
*/ */
private long peakConcurrentRequests; private volatile int peakConcurrentRequests;
/** /**
* Block requests <br/> * Block requests <br/>
*/ */
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 <br/> * Total block requests of the resource and its underlying resources <br/>
*/ */
private AtomicLong totalBlockRequests = new AtomicLong(0); // private AtomicLong totalBlockRequests = new AtomicLong(0);
private volatile int totalBlockRequests = 0;
private AtomicReference<CircuitBreaker.State> circuitBreakState = new AtomicReference<>(CircuitBreaker.State.CLOSED); private AtomicReference<CircuitBreaker.State> 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); private AtomicInteger _2xxStatusCount = new AtomicInteger(0);
@@ -119,22 +127,50 @@ public class TimeSlot {
return circuitBreakState; return circuitBreakState;
} }
public AtomicLong getCircuitBreakNum() { public int getCircuitBreakNum() {
return circuitBreakNum; return circuitBreakNum;
} }
public AtomicLong getGradualResumeNum() { public void setCircuitBreakNum(int v) {
circuitBreakNum = v;
}
public void incrCircuitBreakNum() {
++circuitBreakNum;
}
public int getGradualResumeNum() {
return gradualResumeNum; return gradualResumeNum;
} }
public AtomicInteger getResumeTrafficFactor() { public int incrGradualResumeNum() {
return ++gradualResumeNum;
}
public int decrGradualResumeNum() {
return --gradualResumeNum;
}
public int getResumeTrafficFactor() {
return resumeTrafficFactor; return resumeTrafficFactor;
} }
public AtomicLong getGradualRejectNum() { public void incrResumeTrafficFactor() {
++resumeTrafficFactor;
}
public int getGradualRejectNum() {
return gradualRejectNum; return gradualRejectNum;
} }
public int incrGradualRejectNum() {
return ++gradualRejectNum;
}
public int decrGradualRejectNum() {
return --gradualRejectNum;
}
public TimeSlot(long id) { public TimeSlot(long id) {
this.id = id; this.id = id;
@@ -149,7 +185,8 @@ public class TimeSlot {
* *
*/ */
public void incr() { public void incr() {
counter.incrementAndGet(); // counter.incrementAndGet();
++counter;
} }
/** /**
@@ -159,10 +196,10 @@ public class TimeSlot {
* @param isSuccess Whether the request is success or not * @param isSuccess Whether the request is success or not
*/ */
public synchronized void addRequestRT(long rt, boolean isSuccess) { public synchronized void addRequestRT(long rt, boolean isSuccess) {
totalRt.addAndGet(rt); totalRt += rt;
compReqs.incrementAndGet(); ++compReqs;
if (!isSuccess) { if (!isSuccess) {
errors.incrementAndGet(); ++errors;
} }
min = rt < min ? rt : min; min = rt < min ? rt : min;
max = rt > max ? rt : max; max = rt > max ? rt : max;
@@ -173,7 +210,7 @@ public class TimeSlot {
* *
* @param concurrentRequests Current concurrent requests * @param concurrentRequests Current concurrent requests
*/ */
public synchronized void updatePeakConcurrentReqeusts(long concurrentRequests) { public synchronized void updatePeakConcurrentReqeusts(int concurrentRequests) {
peakConcurrentRequests = concurrentRequests > peakConcurrentRequests ? concurrentRequests peakConcurrentRequests = concurrentRequests > peakConcurrentRequests ? concurrentRequests
: peakConcurrentRequests; : peakConcurrentRequests;
} }
@@ -182,11 +219,11 @@ public class TimeSlot {
this.id = id; this.id = id;
} }
public AtomicLong getCounter() { public int getCounter() {
return counter; return counter;
} }
public void setCounter(AtomicLong counter) { public void setCounter(int counter) {
this.counter = counter; this.counter = counter;
} }
@@ -206,11 +243,11 @@ public class TimeSlot {
this.max = max; this.max = max;
} }
public AtomicLong getTotalRt() { public int getTotalRt() {
return totalRt; return totalRt;
} }
public void setTotalRt(AtomicLong totalRt) { public void setTotalRt(int totalRt) {
this.totalRt = totalRt; this.totalRt = totalRt;
} }
@@ -218,39 +255,47 @@ public class TimeSlot {
return peakConcurrentRequests; return peakConcurrentRequests;
} }
public void setPeakConcurrentRequests(long peakConcurrentRequests) { public void setPeakConcurrentRequests(int peakConcurrentRequests) {
this.peakConcurrentRequests = peakConcurrentRequests; this.peakConcurrentRequests = peakConcurrentRequests;
} }
public AtomicLong getErrors() { public int getErrors() {
return errors; return errors;
} }
public void setErrors(AtomicLong errors) { public void setErrors(int errors) {
this.errors = errors; this.errors = errors;
} }
public AtomicLong getBlockRequests() { public int getBlockRequests() {
return blockRequests; return blockRequests;
} }
public void setBlockRequests(AtomicLong blockRequests) { public void setBlockRequests(int blockRequests) {
this.blockRequests = blockRequests; this.blockRequests = blockRequests;
} }
public AtomicLong getCompReqs() { public void incrBlockRequests() {
++blockRequests;
}
public int getCompReqs() {
return compReqs; return compReqs;
} }
public void setCompReqs(AtomicLong compReqs) { public void setCompReqs(int compReqs) {
this.compReqs = compReqs; this.compReqs = compReqs;
} }
public AtomicLong getTotalBlockRequests() { public int getTotalBlockRequests() {
return totalBlockRequests; return totalBlockRequests;
} }
public void setTotalBlockRequests(AtomicLong totalBlockRequests) { public void incrTotalBlockRequests() {
++totalBlockRequests;
}
public void setTotalBlockRequests(int totalBlockRequests) {
this.totalBlockRequests = totalBlockRequests; this.totalBlockRequests = totalBlockRequests;
} }

View File

@@ -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); String resource = ResourceIdUtils.buildResourceId(null, null, null, service, path);
// correctCircuitBreakerState4error(exchange, currentTimeWindow, flowStat, resource); // correctCircuitBreakerState4error(exchange, currentTimeWindow, flowStat, resource);
CircuitBreaker cb = resource2circuitBreakerMap.get(resource); CircuitBreaker cb = resource2circuitBreakerMap.get(resource);
@@ -290,7 +290,7 @@ public class CircuitBreakManager {
} }
cb.correctCircuitBreakerStateAsError(currentTimeWindow, flowStat); cb.correctCircuitBreakerStateAsError(currentTimeWindow, flowStat);
} }
} }*/
/*public void correctCircuitBreakerState4error(ServerWebExchange exchange, long currentTimeWindow, FlowStat flowStat, String resource) { /*public void correctCircuitBreakerState4error(ServerWebExchange exchange, long currentTimeWindow, FlowStat flowStat, String resource) {
while (true) { while (true) {

View File

@@ -77,25 +77,31 @@ public class CircuitBreaker {
public boolean permit(ResourceStat resourceStat, long currentTimeWindow) { public boolean permit(ResourceStat resourceStat, long currentTimeWindow) {
TimeSlot timeSlot = resourceStat.getTimeSlot(currentTimeWindow); TimeSlot timeSlot = resourceStat.getTimeSlot(currentTimeWindow);
AtomicLong resumeCount = timeSlot.getGradualResumeNum(); // AtomicLong resumeCount = timeSlot.getGradualResumeNum();
AtomicInteger resumeTrafficFactor = timeSlot.getResumeTrafficFactor(); // AtomicInteger resumeTrafficFactor = timeSlot.getResumeTrafficFactor();
long n = resumeTrafficFactor.get(); // long n = resumeTrafficFactor.get();
if (resumeCount.incrementAndGet() <= resumeTraffic * n) { 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", 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; return true;
} }
AtomicLong rejectCount = timeSlot.getGradualRejectNum(); // AtomicLong rejectCount = timeSlot.getGradualRejectNum();
if (rejectCount.incrementAndGet() <= rejectTraffic * n) { // if (rejectCount.incrementAndGet() <= rejectTraffic * n) {
resumeCount.decrementAndGet(); if (timeSlot.incrGradualRejectNum() <= rejectTraffic * n) {
// resumeCount.decrementAndGet();
timeSlot.decrGradualResumeNum();
LOGGER.debug("{} current time window {}, reject traffic {}, resume traffic factor {}, reject count {}, reject current request", 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; return false;
} }
rejectCount.decrementAndGet(); // rejectCount.decrementAndGet();
resumeTrafficFactor.incrementAndGet(); 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", 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; 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) { if (stateRef.get() == State.CLOSED) {
long endTimeWindow = currentTimeWindow + 1000; long endTimeWindow = currentTimeWindow + 1000;
// TimeWindowStat timeWindowStat = flowStat.getTimeWindowStat(resource, endTimeWindow - monitorDuration, endTimeWindow); // 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) { public boolean transit(State current, State target, long currentTimeWindow, FlowStat flowStat) {
if (stateRef.compareAndSet(current, target)) { if (stateRef.compareAndSet(current, target)) {
stateStartTime = currentTimeWindow;
ResourceStat resourceStat = flowStat.getResourceStat(resource); ResourceStat resourceStat = flowStat.getResourceStat(resource);
AtomicLong circuitBreakNum = resourceStat.getTimeSlot(currentTimeWindow).getCircuitBreakNum(); /*AtomicLong circuitBreakNum = resourceStat.getTimeSlot(currentTimeWindow).getCircuitBreakNum();
circuitBreakNum.set(0); circuitBreakNum.set(0);*/
resourceStat.getTimeSlot(currentTimeWindow).setCircuitBreakNum(0);
resourceStat.updateCircuitBreakState(currentTimeWindow, current, target); resourceStat.updateCircuitBreakState(currentTimeWindow, current, target);
LOGGER.debug("transit {} current time window {} from {} which start at {} to {}", resource, currentTimeWindow, current, stateStartTime, target); LOGGER.debug("transit {} current time window {} from {} which start at {} to {}", resource, currentTimeWindow, current, stateStartTime, target);
stateStartTime = currentTimeWindow;
return true; return true;
} }
return false; return false;

View File

@@ -39,7 +39,7 @@ import we.util.JacksonUtils;
*/ */
public class FlowStatTests { public class FlowStatTests {
private FlowStat stat = new FlowStat(); private FlowStat stat = new FlowStat(false, false);
class FlowRuleCase { class FlowRuleCase {
public int threads = 3; public int threads = 3;

View File

@@ -68,6 +68,8 @@ public class CircuitBreakManagerTests {
@Test @Test
void permitTest() { void permitTest() {
FlowStat flowStat = new FlowStat(circuitBreakManager); FlowStat flowStat = new FlowStat(circuitBreakManager);
flowStat.cleanResource = false;
flowStat.createTimeSlotOnlyTraffic = false;
long currentTimeWindow = flowStat.currentTimeSlotId(); long currentTimeWindow = flowStat.currentTimeSlotId();
MockServerHttpRequest mockServerHttpRequest = MockServerHttpRequest.get("/xxx").build(); MockServerHttpRequest mockServerHttpRequest = MockServerHttpRequest.get("/xxx").build();
@@ -92,8 +94,8 @@ public class CircuitBreakManagerTests {
ResourceStat resourceStat = flowStat.getResourceStat(cb.resource); ResourceStat resourceStat = flowStat.getResourceStat(cb.resource);
TimeSlot timeSlot = resourceStat.getTimeSlot(currentTimeWindow); TimeSlot timeSlot = resourceStat.getTimeSlot(currentTimeWindow);
timeSlot.getCompReqs().set(200); timeSlot.setCompReqs(200);
timeSlot.getErrors().set(11); timeSlot.setErrors(11);
boolean permit = circuitBreakManager.permit(mockServerWebExchange, currentTimeWindow, flowStat, service, path); boolean permit = circuitBreakManager.permit(mockServerWebExchange, currentTimeWindow, flowStat, service, path);
Assertions.assertFalse(permit); Assertions.assertFalse(permit);
@@ -101,6 +103,6 @@ public class CircuitBreakManagerTests {
permit = circuitBreakManager.permit(mockServerWebExchange, currentTimeWindow, flowStat, service, path); permit = circuitBreakManager.permit(mockServerWebExchange, currentTimeWindow, flowStat, service, path);
Assertions.assertFalse(permit); Assertions.assertFalse(permit);
Assertions.assertEquals(CircuitBreaker.State.OPEN, timeSlot.getCircuitBreakState().get()); Assertions.assertEquals(CircuitBreaker.State.OPEN, timeSlot.getCircuitBreakState().get());
Assertions.assertEquals(2, timeSlot.getCircuitBreakNum().get()); Assertions.assertEquals(2, timeSlot.getCircuitBreakNum());
} }
} }

View File

@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>fizz-gateway-community</artifactId> <artifactId>fizz-gateway-community</artifactId>
<groupId>com.fizzgate</groupId> <groupId>com.fizzgate</groupId>
<version>2.6.1</version> <version>2.6.2</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>fizz-gateway-community</artifactId> <artifactId>fizz-gateway-community</artifactId>
<groupId>com.fizzgate</groupId> <groupId>com.fizzgate</groupId>
<version>2.6.1</version> <version>2.6.2</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

12
pom.xml
View File

@@ -6,11 +6,11 @@
<properties> <properties>
<!--<java.version>1.8</java.version>--> <!--<java.version>1.8</java.version>-->
<spring-boot.version>2.2.13.RELEASE</spring-boot.version> <spring-boot.version>2.2.13.RELEASE</spring-boot.version>
<spring-framework.version>5.2.20.RELEASE</spring-framework.version> <spring-framework.version>5.2.21.RELEASE</spring-framework.version>
<reactor-bom.version>Dysprosium-SR25</reactor-bom.version> <reactor-bom.version>Dysprosium-SR25</reactor-bom.version>
<lettuce.version>5.3.7.RELEASE</lettuce.version> <lettuce.version>5.3.7.RELEASE</lettuce.version>
<nacos.cloud.version>2.2.7.RELEASE</nacos.cloud.version> <nacos.cloud.version>2.2.7.RELEASE</nacos.cloud.version>
<netty.version>4.1.75.Final</netty.version> <netty.version>4.1.76.Final</netty.version>
<httpcore.version>4.4.15</httpcore.version> <httpcore.version>4.4.15</httpcore.version>
<log4j2.version>2.17.2</log4j2.version> <log4j2.version>2.17.2</log4j2.version>
<slf4j.version>1.7.36</slf4j.version> <slf4j.version>1.7.36</slf4j.version>
@@ -37,7 +37,7 @@
<artifactId>fizz-gateway-community</artifactId> <artifactId>fizz-gateway-community</artifactId>
<name>${project.artifactId}</name> <name>${project.artifactId}</name>
<description>fizz gateway community</description> <description>fizz gateway community</description>
<version>2.6.1</version> <version>2.6.2</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<modules> <modules>
<module>fizz-common</module> <module>fizz-common</module>
@@ -69,6 +69,12 @@
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.16</version>
</dependency>
<dependency> <dependency>
<groupId>com.lmax</groupId> <groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId> <artifactId>disruptor</artifactId>