This is an automated email from the ASF dual-hosted git repository.
wujimin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/master by this push:
new 3cb3649 [SCB-2135]provider flow control support for operation to any
client service
3cb3649 is described below
commit 3cb36498ca5732767bb93818dde11ed407e48397
Author: liubao <[email protected]>
AuthorDate: Thu Dec 3 15:45:30 2020 +0800
[SCB-2135]provider flow control support for operation to any client service
---
.../org/apache/servicecomb/core/SCBEngine.java | 3 +-
.../demo/pojo/client/TestFlowControl.java | 80 +++++++++++++
.../src/main/resources/microservice.yaml | 10 +-
.../demo/pojo/server/FlowControlClientSchema.java | 31 +++++
.../demo/pojo/server/FlowControlSchema.java | 31 +++++
.../src/main/resources/microservice.yaml | 17 ++-
.../java/org/apache/servicecomb/qps/Config.java | 30 +++--
.../qps/ConsumerQpsFlowControlHandler.java | 4 +-
.../qps/ProviderQpsFlowControlHandler.java | 11 +-
.../servicecomb/qps/QpsControllerManager.java | 115 ++++++++++--------
.../qps/strategy/FixedWindowStrategy.java | 2 +-
.../qps/strategy/LeakyBucketStrategy.java | 5 +-
.../servicecomb/qps/QpsControllerManagerTest.java | 129 +++++++++++++--------
.../qps/TestConsumerQpsFlowControlHandler.java | 5 +-
.../qps/TestProviderQpsFlowControlHandler.java | 10 +-
.../provider/pojo/PojoConsumerMetaRefresher.java | 3 +-
.../swagger/invocation/response/ResponsesMeta.java | 3 +
.../transport/highway/HighwayClient.java | 3 +-
.../rest/client/http/RestClientInvocation.java | 3 +-
19 files changed, 355 insertions(+), 140 deletions(-)
diff --git a/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java
b/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java
index edf7645..44a912e 100644
--- a/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java
+++ b/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java
@@ -62,6 +62,7 @@ import
org.apache.servicecomb.registry.consumer.MicroserviceVersions;
import org.apache.servicecomb.registry.definition.MicroserviceNameParser;
import org.apache.servicecomb.registry.swagger.SwaggerLoader;
import org.apache.servicecomb.swagger.engine.SwaggerEnvironment;
+import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -498,7 +499,7 @@ public class SCBEngine {
String message =
"The request is rejected. Cannot process the request due to STATUS =
" + currentStatus;
LOGGER.warn(message);
- throw new InvocationException(Status.SERVICE_UNAVAILABLE, message);
+ throw new InvocationException(Status.SERVICE_UNAVAILABLE, new
CommonExceptionData(message));
}
}
diff --git
a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/TestFlowControl.java
b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/TestFlowControl.java
new file mode 100644
index 0000000..abcd772
--- /dev/null
+++
b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/TestFlowControl.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.pojo.client;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Function;
+
+import org.apache.servicecomb.demo.CategorizedTestCase;
+import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.provider.pojo.RpcReference;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.springframework.stereotype.Component;
+
+@Component
+public class TestFlowControl implements CategorizedTestCase {
+ interface Client {
+ int foo(int num);
+
+ int bar(int num);
+ }
+
+ @RpcReference(microserviceName = "pojo", schemaId = "FlowControlSchema")
+ Client client1;
+
+ @RpcReference(microserviceName = "pojo", schemaId =
"FlowControlClientSchema")
+ Client client2;
+
+ @Override
+ public void testAllTransport() throws Exception {
+ testFlowControl((num) -> client1.foo(num), true);
+ testFlowControl((num) -> client1.bar(num), false);
+ testFlowControl((num) -> client2.foo(num), true);
+ testFlowControl((num) -> client2.bar(num), false);
+ }
+
+ private void testFlowControl(Function<Integer, Integer> function, boolean
expected) throws InterruptedException {
+ AtomicBoolean failed = new AtomicBoolean(false);
+ CountDownLatch countDownLatch = new CountDownLatch(10);
+ for (int i = 0; i < 10; i++) {
+ new Thread() {
+ public void run() {
+ for (int i = 0; i < 10; i++) {
+ try {
+ int result = function.apply(10);
+ if (result != 10) {
+ TestMgr.failed("", new Exception("not expected"));
+ }
+ } catch (InvocationException e) {
+ TestMgr.check(e.getStatusCode(), 429);
+ TestMgr.check(e.getMessage(),
+ "InvocationException: code=429;msg=CommonExceptionData
[message=rejected by qps flowcontrol]");
+ failed.set(true);
+ break;
+ }
+ }
+ countDownLatch.countDown();
+ }
+ }.start();
+ }
+ countDownLatch.await(10, TimeUnit.SECONDS);
+ TestMgr.check(expected, failed.get());
+ }
+}
diff --git a/demo/demo-pojo/pojo-client/src/main/resources/microservice.yaml
b/demo/demo-pojo/pojo-client/src/main/resources/microservice.yaml
index ad15db8..0b561ff 100644
--- a/demo/demo-pojo/pojo-client/src/main/resources/microservice.yaml
+++ b/demo/demo-pojo/pojo-client/src/main/resources/microservice.yaml
@@ -42,4 +42,12 @@ servicecomb:
name: Random
metrics:
window_time: 12000
- publisher.defaultLog.enabled: false # when in testing , can turn on
\ No newline at end of file
+ publisher.defaultLog.enabled: false # when in testing , can turn on
+ flowcontrol:
+ Consumer:
+ qps:
+ limit:
+ pojo:
+ FlowControlClientSchema:
+ foo: 3
+ bar: 3000
\ No newline at end of file
diff --git
a/demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/FlowControlClientSchema.java
b/demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/FlowControlClientSchema.java
new file mode 100644
index 0000000..d94bcba
--- /dev/null
+++
b/demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/FlowControlClientSchema.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.pojo.server;
+
+import org.apache.servicecomb.provider.pojo.RpcSchema;
+
+@RpcSchema(schemaId = "FlowControlClientSchema")
+public class FlowControlClientSchema {
+ public int foo(int num) {
+ return num;
+ }
+
+ public int bar(int num) {
+ return num;
+ }
+}
diff --git
a/demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/FlowControlSchema.java
b/demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/FlowControlSchema.java
new file mode 100644
index 0000000..ba2c293
--- /dev/null
+++
b/demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/FlowControlSchema.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.pojo.server;
+
+import org.apache.servicecomb.provider.pojo.RpcSchema;
+
+@RpcSchema(schemaId = "FlowControlSchema")
+public class FlowControlSchema {
+ public int foo(int num) {
+ return num;
+ }
+
+ public int bar(int num) {
+ return num;
+ }
+}
diff --git a/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml
b/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml
index 8ae2db4..b38218e 100644
--- a/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml
+++ b/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml
@@ -30,9 +30,16 @@ servicecomb:
useAlpnEnabled: false
highway:
address: 0.0.0.0:7070
- #executors:
- #default: test
- #Provider:
- #server: test
- #server.wrapParam: test
+ handler:
+ chain:
+ Provider:
+ default: qps-flowcontrol-provider
+ flowcontrol:
+ Provider:
+ qps:
+ limit:
+ ANY:
+ FlowControlSchema:
+ foo: 3
+ bar: 3000
diff --git
a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/Config.java
b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/Config.java
index ea8e4a1..8078428 100644
---
a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/Config.java
+++
b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/Config.java
@@ -26,7 +26,9 @@ import com.netflix.config.DynamicPropertyFactory;
public final class Config {
private static final Logger LOGGER = LoggerFactory.getLogger(Config.class);
- public static final String STRATEGY_KEY_PREFIX =
"servicecomb.flowcontrol.strategy";
+ public static final String STRATEGY_KEY = "servicecomb.flowcontrol.strategy";
+
+ public static final String ANY_SERVICE = "ANY";
public static final String CONSUMER_BUCKET_KEY_PREFIX =
"servicecomb.flowcontrol.Consumer.qps.bucket.";
@@ -35,6 +37,9 @@ public final class Config {
public static final String PROVIDER_BUCKET_KEY_GLOBAL =
"servicecomb.flowcontrol.Provider.qps.global.bucket";
+ public static final String CONSUMER_BUCKET_KEY_GLOBAL =
+ "servicecomb.flowcontrol.Consumer.qps.global.bucket";
+
public static final String CONSUMER_LIMIT_KEY_PREFIX =
"servicecomb.flowcontrol.Consumer.qps.limit.";
public static final String PROVIDER_LIMIT_KEY_PREFIX =
"servicecomb.flowcontrol.Provider.qps.limit.";
@@ -42,35 +47,38 @@ public final class Config {
public static final String PROVIDER_LIMIT_KEY_GLOBAL =
"servicecomb.flowcontrol.Provider.qps.global.limit";
+ public static final String CONSUMER_LIMIT_KEY_GLOBAL =
+ "servicecomb.flowcontrol.Consumer.qps.global.limit";
+
public static final String CONSUMER_ENABLED =
"servicecomb.flowcontrol.Consumer.qps.enabled";
public static final String PROVIDER_ENABLED =
"servicecomb.flowcontrol.Provider.qps.enabled";
public static Config INSTANCE = new Config();
- private final DynamicBooleanProperty consumerEanbled =
+ private final DynamicBooleanProperty consumerEnabled =
DynamicPropertyFactory.getInstance().getBooleanProperty(CONSUMER_ENABLED, true);
- private final DynamicBooleanProperty providerEanbled =
+ private final DynamicBooleanProperty providerEnabled =
DynamicPropertyFactory.getInstance().getBooleanProperty(PROVIDER_ENABLED, true);
public Config() {
- consumerEanbled.addCallback(() -> {
- boolean newValue = consumerEanbled.get();
- LOGGER.info("{} changed from {} to {}", CONSUMER_ENABLED,
consumerEanbled, newValue);
+ consumerEnabled.addCallback(() -> {
+ boolean newValue = consumerEnabled.get();
+ LOGGER.info("{} changed from {} to {}", CONSUMER_ENABLED,
consumerEnabled, newValue);
});
- providerEanbled.addCallback(() -> {
- boolean newValue = providerEanbled.get();
- LOGGER.info("{} changed from {} to {}", PROVIDER_ENABLED,
providerEanbled, newValue);
+ providerEnabled.addCallback(() -> {
+ boolean newValue = providerEnabled.get();
+ LOGGER.info("{} changed from {} to {}", PROVIDER_ENABLED,
providerEnabled, newValue);
});
}
public boolean isConsumerEnabled() {
- return consumerEanbled.get();
+ return consumerEnabled.get();
}
public boolean isProviderEnabled() {
- return providerEanbled.get();
+ return providerEnabled.get();
}
}
diff --git
a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ConsumerQpsFlowControlHandler.java
b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ConsumerQpsFlowControlHandler.java
index 0972433..1d81311 100644
---
a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ConsumerQpsFlowControlHandler.java
+++
b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ConsumerQpsFlowControlHandler.java
@@ -28,9 +28,7 @@ import
org.apache.servicecomb.swagger.invocation.exception.InvocationException;
* Support 3 levels of microservice/schema/operation.
*/
public class ConsumerQpsFlowControlHandler implements Handler {
- static final QpsControllerManager qpsControllerMgr = new
QpsControllerManager()
- .setLimitKeyPrefix(Config.CONSUMER_LIMIT_KEY_PREFIX)
- .setBucketKeyPrefix(Config.CONSUMER_BUCKET_KEY_PREFIX);
+ private final QpsControllerManager qpsControllerMgr = new
QpsControllerManager(false);
@Override
public void handle(Invocation invocation, AsyncResponse asyncResp) throws
Exception {
diff --git
a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ProviderQpsFlowControlHandler.java
b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ProviderQpsFlowControlHandler.java
index c5e4445..0abdd47 100644
---
a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ProviderQpsFlowControlHandler.java
+++
b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ProviderQpsFlowControlHandler.java
@@ -23,13 +23,9 @@ import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.swagger.invocation.AsyncResponse;
import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
-import org.springframework.util.StringUtils;
public class ProviderQpsFlowControlHandler implements Handler {
- static final QpsControllerManager qpsControllerMgr = new
QpsControllerManager()
- .setLimitKeyPrefix(Config.PROVIDER_LIMIT_KEY_PREFIX)
- .setBucketKeyPrefix(Config.PROVIDER_BUCKET_KEY_PREFIX)
- .setGlobalQpsStrategy(Config.PROVIDER_LIMIT_KEY_GLOBAL,
Config.PROVIDER_BUCKET_KEY_GLOBAL);
+ private final QpsControllerManager qpsControllerMgr = new
QpsControllerManager(true);
@Override
public void handle(Invocation invocation, AsyncResponse asyncResp) throws
Exception {
@@ -47,10 +43,7 @@ public class ProviderQpsFlowControlHandler implements
Handler {
}
String microserviceName = invocation.getContext(Const.SRC_MICROSERVICE);
- QpsStrategy qpsStrategy =
- StringUtils.isEmpty(microserviceName)
- ? qpsControllerMgr.getGlobalQpsStrategy()
- : qpsControllerMgr.getOrCreate(microserviceName, invocation);
+ QpsStrategy qpsStrategy = qpsControllerMgr.getOrCreate(microserviceName,
invocation);
isLimitNewRequest(qpsStrategy, asyncResp);
}
diff --git
a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/QpsControllerManager.java
b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/QpsControllerManager.java
index a287ca2..57d1c96 100644
---
a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/QpsControllerManager.java
+++
b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/QpsControllerManager.java
@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import org.apache.commons.lang3.StringUtils;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
import
org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;
@@ -31,41 +32,85 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.netflix.config.DynamicProperty;
-import org.apache.commons.lang3.StringUtils;
public class QpsControllerManager {
private static final Logger LOGGER =
LoggerFactory.getLogger(QpsControllerManager.class);
+ public static final String SEPARATOR = ".";
+
/**
* Describe the relationship between configuration and qpsController.
*/
- protected final Map<String, AbstractQpsStrategy> configQpsControllerMap =
new ConcurrentHashMapEx<>();
+ private final Map<String, AbstractQpsStrategy> configQpsControllerMap = new
ConcurrentHashMapEx<>();
/**
* Describe the relationship between qualifiedKey(format is
"microservice.schema.operation") and qpsController.
*/
- protected final Map<String, AbstractQpsStrategy> qualifiedNameControllerMap
= new ConcurrentHashMapEx<>();
+ private final Map<String, AbstractQpsStrategy> qualifiedNameControllerMap =
new ConcurrentHashMapEx<>();
- protected AbstractQpsStrategy globalQpsStrategy;
+ private AbstractQpsStrategy globalQpsStrategy;
- public static final String SEPARATOR = ".";
+ private final String limitKeyPrefix;
- private String limitKeyPrefix;
+ private final String bucketKeyPrefix;
- private String bucketKeyPrefix;
+ private final String globalLimitKey;
+
+ private final String globalBucketKey;
+
+ public QpsControllerManager(boolean isProvider) {
+ if (isProvider) {
+ limitKeyPrefix = Config.PROVIDER_LIMIT_KEY_PREFIX;
+ bucketKeyPrefix = Config.PROVIDER_BUCKET_KEY_PREFIX;
+ globalLimitKey = Config.PROVIDER_LIMIT_KEY_GLOBAL;
+ globalBucketKey = Config.PROVIDER_BUCKET_KEY_GLOBAL;
+ } else {
+ limitKeyPrefix = Config.CONSUMER_LIMIT_KEY_PREFIX;
+ bucketKeyPrefix = Config.CONSUMER_BUCKET_KEY_PREFIX;
+ globalLimitKey = Config.CONSUMER_LIMIT_KEY_GLOBAL;
+ globalBucketKey = Config.CONSUMER_BUCKET_KEY_GLOBAL;
+ }
+
+ initGlobalQpsController();
+ }
public QpsStrategy getOrCreate(String microserviceName, Invocation
invocation) {
+ final String name = validatedName(microserviceName);
return qualifiedNameControllerMap
.computeIfAbsent(
- microserviceName + SEPARATOR +
invocation.getOperationMeta().getSchemaQualifiedName(),
- key -> create(key, microserviceName, invocation));
+ name + SEPARATOR +
invocation.getOperationMeta().getSchemaQualifiedName(),
+ key -> create(key, name, invocation));
+ }
+
+ private String validatedName(String microserviceName) {
+ String name = microserviceName;
+ if (StringUtils.isEmpty(microserviceName)) {
+ name = Config.ANY_SERVICE;
+ }
+ return name;
}
/**
* Create relevant qpsLimit dynamicProperty and watch the configuration
change.
* Search and return a valid qpsController.
*/
- protected AbstractQpsStrategy create(String qualifiedNameKey, String
microserviceName,
+ private AbstractQpsStrategy create(String qualifiedNameKey, String
microserviceName,
+ Invocation invocation) {
+ createForService(qualifiedNameKey, microserviceName, invocation);
+ String qualifiedAnyServiceName = Config.ANY_SERVICE +
qualifiedNameKey.substring(microserviceName.length());
+ createForService(qualifiedAnyServiceName, Config.ANY_SERVICE, invocation);
+
+ AbstractQpsStrategy strategy = searchQpsController(qualifiedNameKey);
+ if (strategy == null) {
+ strategy = searchQpsController(qualifiedAnyServiceName);
+ }
+ if (strategy == null) {
+ return globalQpsStrategy;
+ }
+ return strategy;
+ }
+
+ private void createForService(String qualifiedNameKey, String
microserviceName,
Invocation invocation) {
// create "microservice"
createQpsControllerIfNotExist(microserviceName);
@@ -74,8 +119,6 @@ public class QpsControllerManager {
qualifiedNameKey.substring(0, microserviceName.length() +
invocation.getSchemaId().length() + 1));
// create "microservice.schema.operation"
createQpsControllerIfNotExist(qualifiedNameKey);
-
- return searchQpsController(qualifiedNameKey);
}
/**
@@ -88,7 +131,7 @@ public class QpsControllerManager {
* @param qualifiedNameKey qualifiedNameKey in {@link
#qualifiedNameControllerMap}
* @return a qps controller, lower level controllers with valid qpsLimit
have priority.
*/
- protected AbstractQpsStrategy searchQpsController(String qualifiedNameKey) {
+ private AbstractQpsStrategy searchQpsController(String qualifiedNameKey) {
AbstractQpsStrategy qpsStrategy =
configQpsControllerMap.get(qualifiedNameKey);
if (isValidQpsController(qpsStrategy)) {
return qpsStrategy;
@@ -108,13 +151,7 @@ public class QpsControllerManager {
return qpsStrategy;
}
- if (null != globalQpsStrategy) {
- return globalQpsStrategy;
- }
-
- // if null is returned, maybe the operation qps controller is not
initiated correctly.
- // getOrCreateQpsController() should be invoked before.
- return qpsStrategy;
+ return null;
}
private boolean keyMatch(String configKey, Entry<String,
AbstractQpsStrategy> controllerEntry) {
@@ -127,15 +164,14 @@ public class QpsControllerManager {
}
private void createQpsControllerIfNotExist(String configKey) {
- if (configQpsControllerMap.keySet().contains(configKey)) {
+ if (configQpsControllerMap.containsKey(configKey)) {
return;
}
LOGGER.info("Create qpsController, configKey = [{}]", configKey);
DynamicProperty limitProperty = DynamicProperty.getInstance(limitKeyPrefix
+ configKey);
DynamicProperty bucketProperty =
DynamicProperty.getInstance(bucketKeyPrefix + configKey);
- DynamicProperty strategyProperty = DynamicProperty
- .getInstance(Config.STRATEGY_KEY_PREFIX);
+ DynamicProperty strategyProperty =
DynamicProperty.getInstance(Config.STRATEGY_KEY);
AbstractQpsStrategy qpsStrategy = chooseStrategy(configKey,
limitProperty.getLong(),
bucketProperty.getLong(), strategyProperty.getString());
@@ -175,41 +211,30 @@ public class QpsControllerManager {
}
}
- public QpsControllerManager setLimitKeyPrefix(String limitKeyPrefix) {
- this.limitKeyPrefix = limitKeyPrefix;
- return this;
- }
-
- public QpsControllerManager setBucketKeyPrefix(String bucketKeyPrefix) {
- this.bucketKeyPrefix = bucketKeyPrefix;
- return this;
- }
-
- public QpsControllerManager setGlobalQpsStrategy(String globalLimitKey,
String globalBucketKey) {
+ private void initGlobalQpsController() {
DynamicProperty globalLimitProperty =
DynamicProperty.getInstance(globalLimitKey);
DynamicProperty globalBucketProperty =
DynamicProperty.getInstance(globalBucketKey);
DynamicProperty globalStrategyProperty = DynamicProperty
- .getInstance(Config.STRATEGY_KEY_PREFIX);
- globalQpsStrategy = chooseStrategy(globalLimitKey,
globalLimitProperty.getLong(),
+ .getInstance(Config.STRATEGY_KEY);
+ globalQpsStrategy = chooseStrategy(globalLimitKey,
globalLimitProperty.getLong((long) Integer.MAX_VALUE),
globalBucketProperty.getLong(), globalStrategyProperty.getString());
globalStrategyProperty.addCallback(() -> {
- globalQpsStrategy = chooseStrategy(globalLimitKey,
globalLimitProperty.getLong(),
+ globalQpsStrategy = chooseStrategy(globalLimitKey,
globalLimitProperty.getLong((long) Integer.MAX_VALUE),
globalBucketProperty.getLong(), globalStrategyProperty.getString());
LOGGER.info("Global flow control strategy update, value = [{}]",
globalStrategyProperty.getString());
});
globalLimitProperty.addCallback(() -> {
- globalQpsStrategy.setQpsLimit(globalLimitProperty.getLong());
- LOGGER.info("Global qps limit update, value = [{}]",
globalLimitProperty.getInteger());
+ globalQpsStrategy.setQpsLimit(globalLimitProperty.getLong((long)
Integer.MAX_VALUE));
+ LOGGER.info("Global qps limit update, value = [{}]",
globalLimitProperty.getLong());
});
globalBucketProperty.addCallback(() -> {
globalQpsStrategy.setBucketLimit(globalBucketProperty.getLong());
- LOGGER.info("Global bucket limit update, value = [{}]",
globalBucketProperty.getInteger());
+ LOGGER.info("Global bucket limit update, value = [{}]",
globalBucketProperty.getLong());
});
- return this;
}
- private AbstractQpsStrategy chooseStrategy(String globalConfigKey, Long
limit, Long bucket,
+ private AbstractQpsStrategy chooseStrategy(String configKey, Long limit,
Long bucket,
String strategyName) {
if (StringUtils.isEmpty(strategyName)) {
strategyName = "FixedWindow";
@@ -227,13 +252,9 @@ public class QpsControllerManager {
throw new ServiceCombException(
"the qps strategy name " + strategyName + " is not exist , please
check.");
}
- strategy.setKey(globalConfigKey);
+ strategy.setKey(configKey);
strategy.setQpsLimit(limit);
strategy.setBucketLimit(bucket);
return strategy;
}
-
- public QpsStrategy getGlobalQpsStrategy() {
- return globalQpsStrategy;
- }
}
diff --git
a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/strategy/FixedWindowStrategy.java
b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/strategy/FixedWindowStrategy.java
index 3c5fe63..f91f87f 100644
---
a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/strategy/FixedWindowStrategy.java
+++
b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/strategy/FixedWindowStrategy.java
@@ -36,7 +36,7 @@ public class FixedWindowStrategy extends AbstractQpsStrategy {
// return true means new request need to be rejected
public boolean isLimitNewRequest() {
if (this.getQpsLimit() == null) {
- this.setQpsLimit(Long.MAX_VALUE);
+ throw new IllegalStateException("should not happen");
}
long newCount = requestCount.incrementAndGet();
long msNow = System.currentTimeMillis();
diff --git
a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/strategy/LeakyBucketStrategy.java
b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/strategy/LeakyBucketStrategy.java
index d6a65ee..d65d43b 100644
---
a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/strategy/LeakyBucketStrategy.java
+++
b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/strategy/LeakyBucketStrategy.java
@@ -39,11 +39,10 @@ public class LeakyBucketStrategy extends
AbstractQpsStrategy {
@Override
public boolean isLimitNewRequest() {
if (this.getQpsLimit() == null) {
- this.setQpsLimit(Long.MAX_VALUE);
+ throw new IllegalStateException("should not happen");
}
if (this.getBucketLimit() == null) {
- this.setBucketLimit(
- this.getQpsLimit() <= Long.MAX_VALUE / 2 ? this.getQpsLimit() * 2 :
this.getQpsLimit());
+ this.setBucketLimit(Math.max(2 * this.getQpsLimit(), Integer.MAX_VALUE));
}
long nowTime = System.currentTimeMillis();
//get the num of te period time
diff --git
a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/QpsControllerManagerTest.java
b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/QpsControllerManagerTest.java
index 6089eac..990b44d 100644
---
a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/QpsControllerManagerTest.java
+++
b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/QpsControllerManagerTest.java
@@ -17,8 +17,6 @@
package org.apache.servicecomb.qps;
-import java.util.Map;
-
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.core.definition.SchemaMeta;
@@ -30,7 +28,6 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
-import mockit.Deencapsulation;
import mockit.Expectations;
import mockit.Mocked;
@@ -58,21 +55,21 @@ public class QpsControllerManagerTest {
result = "server.test";
}
};
- QpsControllerManager testQpsControllerManager = new QpsControllerManager()
- .setLimitKeyPrefix(Config.CONSUMER_LIMIT_KEY_PREFIX);
- initTestQpsControllerManager(testQpsControllerManager, invocation,
operationMeta);
+ QpsControllerManager testQpsControllerManager = new
QpsControllerManager(false);
+ initTestQpsControllerManager(false, testQpsControllerManager, invocation,
operationMeta);
// pojo
- setConfigWithDefaultPrefix("pojo", 100);
+ setConfigWithDefaultPrefix(false, "pojo", 100);
QpsStrategy qpsStrategy = testQpsControllerManager.getOrCreate("pojo",
invocation);
Assert.assertEquals("pojo", ((AbstractQpsStrategy) qpsStrategy).getKey());
Assert.assertTrue(100 == ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit());
qpsStrategy = testQpsControllerManager.getOrCreate("pojo2", invocation);
- Assert.assertEquals("pojo2", ((AbstractQpsStrategy) qpsStrategy).getKey());
- Assert.assertNull(((AbstractQpsStrategy) qpsStrategy).getQpsLimit());
+ Assert.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ Assert.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit().intValue());
+
qpsStrategy = testQpsControllerManager.getOrCreate("poj", invocation);
- Assert.assertEquals("poj", ((AbstractQpsStrategy) qpsStrategy).getKey());
- Assert.assertNull(((AbstractQpsStrategy) qpsStrategy).getQpsLimit());
+ Assert.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ Assert.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit().intValue());
ArchaiusUtils.setProperty("servicecomb.flowcontrol.Consumer.qps.limit.poj.server",
10000);
qpsStrategy = testQpsControllerManager.getOrCreate("poj", invocation);
@@ -84,7 +81,7 @@ public class QpsControllerManagerTest {
Assert.assertEquals("poj.server.test", ((AbstractQpsStrategy)
qpsStrategy).getKey());
Assert.assertEquals(((AbstractQpsStrategy) qpsStrategy).getQpsLimit(),
(Long) 20000L);
- testGetOrCreateCommon(testQpsControllerManager, invocation, operationMeta);
+ testGetOrCreateCommon(false, testQpsControllerManager, invocation,
operationMeta);
}
@Test
@@ -100,9 +97,7 @@ public class QpsControllerManagerTest {
}
};
- QpsControllerManager testQpsControllerManager = new QpsControllerManager()
- .setGlobalQpsStrategy(Config.PROVIDER_LIMIT_KEY_GLOBAL,
Config.PROVIDER_BUCKET_KEY_GLOBAL)
- .setLimitKeyPrefix(Config.CONSUMER_LIMIT_KEY_PREFIX);
+ QpsControllerManager testQpsControllerManager = new
QpsControllerManager(true);
// global
setConfig(Config.PROVIDER_LIMIT_KEY_GLOBAL, 50);
@@ -117,7 +112,7 @@ public class QpsControllerManagerTest {
Assert.assertTrue(50 == ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());
// pojo
- setConfigWithDefaultPrefix("pojo", 100);
+ setConfigWithDefaultPrefix(true, "pojo", 100);
qpsStrategy = testQpsControllerManager.getOrCreate("pojo", invocation);
Assert.assertEquals("pojo", ((AbstractQpsStrategy) qpsStrategy).getKey());
Assert.assertTrue(100 == ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit());
@@ -128,7 +123,7 @@ public class QpsControllerManagerTest {
Assert.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
Assert.assertTrue(50 == ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());
- testGetOrCreateCommon(testQpsControllerManager, invocation, operationMeta);
+ testGetOrCreateCommon(true, testQpsControllerManager, invocation,
operationMeta);
}
@Test
@@ -143,10 +138,11 @@ public class QpsControllerManagerTest {
result = "schema.opr";
}
};
- QpsControllerManager qpsControllerManager = new QpsControllerManager();
+ QpsControllerManager qpsControllerManager = new QpsControllerManager(true);
QpsStrategy qpsStrategy = qpsControllerManager.getOrCreate("service",
invocation);
- Assert.assertEquals("service", ((AbstractQpsStrategy)
qpsStrategy).getKey());
- Assert.assertNull(((AbstractQpsStrategy) qpsStrategy).getQpsLimit());
+ Assert.assertEquals("servicecomb.flowcontrol.Provider.qps.global.limit",
+ ((AbstractQpsStrategy) qpsStrategy).getKey());
+ Assert.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit().intValue());
new Expectations() {
{
@@ -159,8 +155,9 @@ public class QpsControllerManagerTest {
}
};
qpsStrategy = qpsControllerManager.getOrCreate("test_service", invocation);
- Assert.assertEquals("test_service", ((AbstractQpsStrategy)
qpsStrategy).getKey());
- Assert.assertNull(((AbstractQpsStrategy) qpsStrategy).getQpsLimit());
+ Assert.assertEquals("servicecomb.flowcontrol.Provider.qps.global.limit",
+ ((AbstractQpsStrategy) qpsStrategy).getKey());
+ Assert.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit().intValue());
new Expectations() {
{
@@ -173,8 +170,9 @@ public class QpsControllerManagerTest {
}
};
qpsStrategy = qpsControllerManager.getOrCreate("test-service", invocation);
- Assert.assertEquals("test-service", ((AbstractQpsStrategy)
qpsStrategy).getKey());
- Assert.assertNull(((AbstractQpsStrategy) qpsStrategy).getQpsLimit());
+ Assert.assertEquals("servicecomb.flowcontrol.Provider.qps.global.limit",
+ ((AbstractQpsStrategy) qpsStrategy).getKey());
+ Assert.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit().intValue());
new Expectations() {
{
@@ -187,8 +185,9 @@ public class QpsControllerManagerTest {
}
};
qpsStrategy = qpsControllerManager.getOrCreate("svc", invocation);
- Assert.assertEquals("svc", ((AbstractQpsStrategy) qpsStrategy).getKey());
- Assert.assertNull(((AbstractQpsStrategy) qpsStrategy).getQpsLimit());
+ Assert.assertEquals("servicecomb.flowcontrol.Provider.qps.global.limit",
+ ((AbstractQpsStrategy) qpsStrategy).getKey());
+ Assert.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit().intValue());
new Expectations() {
{
@@ -201,11 +200,13 @@ public class QpsControllerManagerTest {
}
};
qpsStrategy = qpsControllerManager.getOrCreate("svc", invocation);
- Assert.assertEquals("svc", ((AbstractQpsStrategy) qpsStrategy).getKey());
- Assert.assertNull(((AbstractQpsStrategy) qpsStrategy).getQpsLimit());
+ Assert.assertEquals("servicecomb.flowcontrol.Provider.qps.global.limit",
+ ((AbstractQpsStrategy) qpsStrategy).getKey());
+ Assert.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit().intValue());
}
- private void testGetOrCreateCommon(QpsControllerManager
testQpsControllerManager, Invocation invocation,
+ private void testGetOrCreateCommon(boolean isProvider, QpsControllerManager
testQpsControllerManager,
+ Invocation invocation,
OperationMeta operationMeta) {
new Expectations() {
{
@@ -215,7 +216,7 @@ public class QpsControllerManagerTest {
result = "server.test";
}
};
- setConfigWithDefaultPrefix("pojo.server", 200);
+ setConfigWithDefaultPrefix(isProvider, "pojo.server", 200);
QpsStrategy qpsStrategy = testQpsControllerManager.getOrCreate("pojo",
invocation);
Assert.assertEquals("pojo.server", ((AbstractQpsStrategy)
qpsStrategy).getKey());
Assert.assertTrue(200 == ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit());
@@ -251,7 +252,7 @@ public class QpsControllerManagerTest {
result = "server.test";
}
};
- setConfigWithDefaultPrefix("pojo.server.test", 300);
+ setConfigWithDefaultPrefix(isProvider, "pojo.server.test", 300);
qpsStrategy = testQpsControllerManager.getOrCreate("pojo", invocation);
Assert.assertEquals("pojo.server.test", ((AbstractQpsStrategy)
qpsStrategy).getKey());
Assert.assertTrue(300 == ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit());
@@ -283,7 +284,8 @@ public class QpsControllerManagerTest {
/**
* Init testQpsControllerManager to test search function.
*/
- private void initTestQpsControllerManager(QpsControllerManager
testQpsControllerManager, Invocation invocation,
+ private void initTestQpsControllerManager(boolean isProvider,
QpsControllerManager testQpsControllerManager,
+ Invocation invocation,
OperationMeta operationMeta) {
// pojo.server.test
new Expectations() {
@@ -297,8 +299,12 @@ public class QpsControllerManagerTest {
}
};
QpsStrategy qpsStrategy = testQpsControllerManager.getOrCreate("pojo",
invocation);
- Assert.assertEquals("pojo", ((AbstractQpsStrategy) qpsStrategy).getKey());
- Assert.assertNull(((AbstractQpsStrategy) qpsStrategy).getQpsLimit());
+ if (isProvider) {
+ Assert.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ } else {
+ Assert.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ }
+ Assert.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit().intValue());
// pojo.server.test2
new Expectations() {
@@ -312,6 +318,12 @@ public class QpsControllerManagerTest {
}
};
testQpsControllerManager.getOrCreate("pojo", invocation);
+ if (isProvider) {
+ Assert.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ } else {
+ Assert.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ }
+ Assert.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit().intValue());
// pojo.server.tes
new Expectations() {
@@ -325,6 +337,12 @@ public class QpsControllerManagerTest {
}
};
testQpsControllerManager.getOrCreate("pojo", invocation);
+ if (isProvider) {
+ Assert.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ } else {
+ Assert.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ }
+ Assert.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit().intValue());
// pojo.server2.test
new Expectations() {
@@ -338,6 +356,12 @@ public class QpsControllerManagerTest {
}
};
testQpsControllerManager.getOrCreate("pojo", invocation);
+ if (isProvider) {
+ Assert.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ } else {
+ Assert.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ }
+ Assert.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit().intValue());
// pojo.serve.test
new Expectations() {
@@ -351,6 +375,12 @@ public class QpsControllerManagerTest {
}
};
testQpsControllerManager.getOrCreate("pojo", invocation);
+ if (isProvider) {
+ Assert.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ } else {
+ Assert.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ }
+ Assert.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit().intValue());
// pojo2.server.test
new Expectations() {
@@ -364,8 +394,12 @@ public class QpsControllerManagerTest {
}
};
qpsStrategy = testQpsControllerManager.getOrCreate("pojo2", invocation);
- Assert.assertEquals("pojo2", ((AbstractQpsStrategy) qpsStrategy).getKey());
- Assert.assertNull(((AbstractQpsStrategy) qpsStrategy).getQpsLimit());
+ if (isProvider) {
+ Assert.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ } else {
+ Assert.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ }
+ Assert.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit().intValue());
// poj.server.test
new Expectations() {
@@ -379,8 +413,12 @@ public class QpsControllerManagerTest {
}
};
qpsStrategy = testQpsControllerManager.getOrCreate("poj", invocation);
- Assert.assertEquals("poj", ((AbstractQpsStrategy) qpsStrategy).getKey());
- Assert.assertNull(((AbstractQpsStrategy) qpsStrategy).getQpsLimit());
+ if (isProvider) {
+ Assert.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ } else {
+ Assert.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL,
((AbstractQpsStrategy) qpsStrategy).getKey());
+ }
+ Assert.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy)
qpsStrategy).getQpsLimit().intValue());
}
@Test
@@ -426,17 +464,12 @@ public class QpsControllerManagerTest {
ArchaiusUtils.setProperty(key, value);
}
- public static void setConfigWithDefaultPrefix(String key, int value) {
+ private static void setConfigWithDefaultPrefix(boolean isProvider, String
key, int value) {
String configKey = Config.CONSUMER_LIMIT_KEY_PREFIX + key;
- ArchaiusUtils.setProperty(configKey, value);
- }
+ if (isProvider) {
+ configKey = Config.PROVIDER_LIMIT_KEY_PREFIX + key;
+ }
- public static void clearState(QpsControllerManager qpsControllerManager) {
- Map<String, QpsStrategy> objMap = Deencapsulation
- .getField(qpsControllerManager, "qualifiedNameControllerMap");
- objMap.clear();
- Map<String, QpsStrategy> configQpsControllerMap = Deencapsulation
- .getField(qpsControllerManager, "configQpsControllerMap");
- configQpsControllerMap.clear();
+ ArchaiusUtils.setProperty(configKey, value);
}
}
diff --git
a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestConsumerQpsFlowControlHandler.java
b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestConsumerQpsFlowControlHandler.java
index 1cda2cf..5aef2dd 100644
---
a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestConsumerQpsFlowControlHandler.java
+++
b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestConsumerQpsFlowControlHandler.java
@@ -44,7 +44,7 @@ import mockit.MockUp;
public class TestConsumerQpsFlowControlHandler {
- ConsumerQpsFlowControlHandler handler = new ConsumerQpsFlowControlHandler();
+ ConsumerQpsFlowControlHandler handler;
Invocation invocation = Mockito.mock(Invocation.class);
@@ -58,14 +58,13 @@ public class TestConsumerQpsFlowControlHandler {
@Before
public void setUP() {
ArchaiusUtils.resetConfig();
-
QpsControllerManagerTest.clearState(ConsumerQpsFlowControlHandler.qpsControllerMgr);
+ handler = new ConsumerQpsFlowControlHandler();
}
@After
public void afterTest() {
ArchaiusUtils.resetConfig();
-
QpsControllerManagerTest.clearState(ConsumerQpsFlowControlHandler.qpsControllerMgr);
}
@Test
diff --git
a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestProviderQpsFlowControlHandler.java
b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestProviderQpsFlowControlHandler.java
index 39cc1b9..dfbecfd 100644
---
a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestProviderQpsFlowControlHandler.java
+++
b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestProviderQpsFlowControlHandler.java
@@ -45,7 +45,7 @@ import mockit.Mock;
import mockit.MockUp;
public class TestProviderQpsFlowControlHandler {
- ProviderQpsFlowControlHandler handler = new ProviderQpsFlowControlHandler();
+ ProviderQpsFlowControlHandler handler;
Invocation invocation = Mockito.mock(Invocation.class);
@@ -57,14 +57,13 @@ public class TestProviderQpsFlowControlHandler {
@Before
public void setUP() {
ArchaiusUtils.resetConfig();
-
QpsControllerManagerTest.clearState(ProviderQpsFlowControlHandler.qpsControllerMgr);
+ handler = new ProviderQpsFlowControlHandler();
ArchaiusUtils.setProperty(Config.PROVIDER_LIMIT_KEY_PREFIX + "test", 1);
}
@After
public void afterTest() {
ArchaiusUtils.resetConfig();
-
QpsControllerManagerTest.clearState(ProviderQpsFlowControlHandler.qpsControllerMgr);
}
@Test
@@ -111,11 +110,12 @@ public class TestProviderQpsFlowControlHandler {
@Test
public void testHandleOnSourceMicroserviceNameIsNull() throws Exception {
Mockito.when(invocation.getContext(Const.SRC_MICROSERVICE)).thenReturn(null);
+ OperationMeta operationMeta =
QpsControllerManagerTest.getMockOperationMeta("pojo", "server", "opr");
+ Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);
+ Mockito.when(invocation.getSchemaId()).thenReturn("server");
// only when handler index <= 0, the qps logic works
Mockito.when(invocation.getHandlerIndex()).thenReturn(0);
ArchaiusUtils.setProperty("servicecomb.flowcontrol.Provider.qps.global.limit",
1);
- ProviderQpsFlowControlHandler.qpsControllerMgr
- .setGlobalQpsStrategy(Config.PROVIDER_LIMIT_KEY_GLOBAL,
Config.PROVIDER_BUCKET_KEY_GLOBAL);
handler.handle(invocation, asyncResp);
handler.handle(invocation, asyncResp);
diff --git
a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/PojoConsumerMetaRefresher.java
b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/PojoConsumerMetaRefresher.java
index e137761..ef31036 100644
---
a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/PojoConsumerMetaRefresher.java
+++
b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/PojoConsumerMetaRefresher.java
@@ -25,6 +25,7 @@ import org.apache.servicecomb.core.definition.SchemaMeta;
import
org.apache.servicecomb.core.provider.consumer.MicroserviceReferenceConfig;
import org.apache.servicecomb.provider.pojo.definition.PojoConsumerMeta;
import org.apache.servicecomb.swagger.engine.SwaggerConsumer;
+import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -64,7 +65,7 @@ public class PojoConsumerMetaRefresher {
String message =
"The request is rejected. Cannot process the request due to
SCBEngine not ready.";
LOGGER.warn(message);
- throw new InvocationException(Status.SERVICE_UNAVAILABLE, message);
+ throw new InvocationException(Status.SERVICE_UNAVAILABLE, new
CommonExceptionData(message));
}
this.scbEngine = SCBEngine.getInstance();
diff --git
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java
index 0067945..a72b260 100644
---
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java
+++
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java
@@ -97,6 +97,9 @@ public class ResponsesMeta {
responseMap.putIfAbsent(ExceptionFactory.CONSUMER_INNER_STATUS_CODE,
COMMON_EXCEPTION_JAVA_TYPE);
responseMap.putIfAbsent(ExceptionFactory.PRODUCER_INNER_STATUS_CODE,
COMMON_EXCEPTION_JAVA_TYPE);
+ responseMap.putIfAbsent(Status.TOO_MANY_REQUESTS.getStatusCode(),
COMMON_EXCEPTION_JAVA_TYPE);
+ responseMap.putIfAbsent(Status.REQUEST_TIMEOUT.getStatusCode(),
COMMON_EXCEPTION_JAVA_TYPE);
+ responseMap.putIfAbsent(Status.SERVICE_UNAVAILABLE.getStatusCode(),
COMMON_EXCEPTION_JAVA_TYPE);
if (defaultResponse == null) {
// swagger中没有定义default,加上default专用于处理exception
diff --git
a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClient.java
b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClient.java
index b80cd43..f54663a 100644
---
a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClient.java
+++
b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClient.java
@@ -35,6 +35,7 @@ import
org.apache.servicecomb.foundation.vertx.client.ClientVerticle;
import org.apache.servicecomb.foundation.vertx.client.tcp.TcpClientConfig;
import org.apache.servicecomb.swagger.invocation.AsyncResponse;
import org.apache.servicecomb.swagger.invocation.Response;
+import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -117,7 +118,7 @@ public class HighwayClient {
if (ar.cause() instanceof TimeoutException) {
// give an accurate cause for timeout exception
asyncResp.consumerFail(new
InvocationException(Status.REQUEST_TIMEOUT,
- String.format("Request Timeout. Details: %s",
ar.cause().getMessage())));
+ new CommonExceptionData(String.format("Request Timeout.
Details: %s", ar.cause().getMessage()))));
return;
}
asyncResp.consumerFail(ar.cause());
diff --git
a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/RestClientInvocation.java
b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/RestClientInvocation.java
index 18f6f58..251b27e 100644
---
a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/RestClientInvocation.java
+++
b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/RestClientInvocation.java
@@ -45,6 +45,7 @@ import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultHttpSocketM
import org.apache.servicecomb.registry.definition.DefinitionConst;
import org.apache.servicecomb.swagger.invocation.AsyncResponse;
import org.apache.servicecomb.swagger.invocation.Response;
+import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -284,7 +285,7 @@ public class RestClientInvocation {
if (e instanceof TimeoutException) {
// give an accurate cause for timeout exception
asyncResp.consumerFail(new InvocationException(Status.REQUEST_TIMEOUT,
- String.format("Request Timeout. Details: %s", e.getMessage())));
+ new CommonExceptionData(String.format("Request Timeout. Details:
%s", e.getMessage()))));
return;
}
asyncResp.fail(invocation.getInvocationType(), e);