[SCB-2742]change IsolationDiscoveryFilter enabled by false
diff --git a/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/EdgeServiceGovernanceService.java b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/EdgeServiceGovernanceService.java
new file mode 100644
index 0000000..f694cac
--- /dev/null
+++ b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/EdgeServiceGovernanceService.java
@@ -0,0 +1,76 @@
+/*
+ * 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.edge.business;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+@RestSchema(schemaId = "EdgeServiceGovernanceService")
+@RequestMapping(path = "/business/v2")
+public class EdgeServiceGovernanceService {
+ private static final Logger LOGGER = LoggerFactory.getLogger(EdgeServiceGovernanceService.class);
+
+ private Map<String, Integer> retryTimes = new HashMap<>();
+
+ private AtomicInteger instanceIsolationIndex = new AtomicInteger();
+
+ @GetMapping("/testEdgeServiceRetry")
+ @ApiResponses({
+ @ApiResponse(code = 200, response = String.class, message = ""),
+ @ApiResponse(code = 502, response = String.class, message = "")})
+ public String testEdgeServiceRetry(@RequestParam(name = "invocationID") String invocationID) {
+ LOGGER.info("invoke service: {}", invocationID);
+ retryTimes.putIfAbsent(invocationID, 0);
+ retryTimes.put(invocationID, retryTimes.get(invocationID) + 1);
+
+ int retry = retryTimes.get(invocationID);
+
+ if (retry == 3) {
+ return "try times: " + retry;
+ }
+ throw new InvocationException(502, "retry", "retry");
+ }
+
+ @GetMapping("/testEdgeServiceInstanceIsolation")
+ @ApiResponses({
+ @ApiResponse(code = 200, response = String.class, message = ""),
+ @ApiResponse(code = 502, response = String.class, message = "")})
+ public String testEdgeServiceInstanceIsolation(@RequestParam(name = "name") String name) {
+ if (instanceIsolationIndex.getAndIncrement() % 3 != 0) {
+ throw new InvocationException(502, "InstanceIsolation", "InstanceIsolation");
+ }
+ return name;
+ }
+
+ @GetMapping("/testEdgeServiceInstanceBulkhead")
+ public String testEdgeServiceInstanceBulkhead(@RequestParam(name = "name") String name) {
+ return name;
+ }
+}
diff --git a/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/ConsumerMain.java b/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/ConsumerMain.java
index 8feeaeb..8079578 100644
--- a/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/ConsumerMain.java
+++ b/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/ConsumerMain.java
@@ -17,6 +17,8 @@
package org.apache.servicecomb.demo.edge.consumer;
+import org.apache.servicecomb.demo.CategorizedTestCaseRunner;
+import org.apache.servicecomb.demo.TestMgr;
import org.apache.servicecomb.demo.edge.model.ChannelRequestBase;
import org.apache.servicecomb.foundation.common.utils.BeanUtils;
import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
@@ -39,5 +41,17 @@
new Consumer().run("http");
System.out.println("All test case finished.");
+
+ runCategorizedTest();
+
+ TestMgr.summary();
+ if (!TestMgr.errors().isEmpty()) {
+ throw new IllegalStateException("tests failed");
+ }
+ }
+
+ private static void runCategorizedTest() throws Exception {
+ CategorizedTestCaseRunner
+ .runCategorizedTestCase("edge");
}
}
diff --git a/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/EdgeServiceGovernanceTest.java b/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/EdgeServiceGovernanceTest.java
new file mode 100644
index 0000000..ed9b6d1
--- /dev/null
+++ b/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/EdgeServiceGovernanceTest.java
@@ -0,0 +1,156 @@
+/*
+ * 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.edge.consumer;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.servicecomb.demo.CategorizedTestCase;
+import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
+import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
+import org.apache.servicecomb.registry.DiscoveryManager;
+import org.apache.servicecomb.registry.RegistrationManager;
+import org.apache.servicecomb.registry.api.registry.Microservice;
+import org.apache.servicecomb.registry.api.registry.MicroserviceInstance;
+import org.apache.servicecomb.registry.definition.DefinitionConst;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.HttpServerErrorException;
+import org.springframework.web.client.RestTemplate;
+
+@Component
+public class EdgeServiceGovernanceTest implements CategorizedTestCase {
+ RestTemplate template = RestTemplateBuilder.create();
+
+ String edgePrefix;
+
+ @Override
+ public void testRestTransport() throws Exception {
+ prepareEdge("url");
+ // edge service do not support retry
+// testEdgeServiceRetry();
+
+ testEdgeServiceInstanceIsolation();
+ testEdgeServiceInstanceBulkhead();
+ }
+
+ private void testEdgeServiceInstanceBulkhead() throws Exception {
+ String url = edgePrefix + "/business/v2/testEdgeServiceInstanceBulkhead";
+
+ CountDownLatch latch = new CountDownLatch(100);
+ AtomicBoolean expectedFailed503 = new AtomicBoolean(false);
+ AtomicBoolean notExpectedFailed = new AtomicBoolean(false);
+
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ String name = "t-" + i + "-" + j;
+ new Thread(name) {
+ public void run() {
+ try {
+ String result = template.getForObject(url + "?name={1}", String.class, "hello");
+ if (!"\"hello\"".equals(result)) {
+ notExpectedFailed.set(true);
+ }
+ } catch (Exception e) {
+ if (!(e instanceof HttpServerErrorException)) {
+ notExpectedFailed.set(true);
+ } else {
+ if (((HttpServerErrorException) e).getStatusCode().value() == 503) {
+ expectedFailed503.set(true);
+ }
+ }
+ }
+ latch.countDown();
+ }
+ }.start();
+ }
+ Thread.sleep(100);
+ }
+
+ latch.await(20, TimeUnit.SECONDS);
+ TestMgr.check(true, expectedFailed503.get());
+ TestMgr.check(false, notExpectedFailed.get());
+ }
+
+ private void testEdgeServiceInstanceIsolation() throws Exception {
+ String url = edgePrefix + "/business/v2/testEdgeServiceInstanceIsolation";
+
+ CountDownLatch latch = new CountDownLatch(100);
+ AtomicBoolean expectedFailed502 = new AtomicBoolean(false);
+ AtomicBoolean expectedFailed503 = new AtomicBoolean(false);
+ AtomicBoolean notExpectedFailed = new AtomicBoolean(false);
+
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ String name = "t-" + i + "-" + j;
+ new Thread(name) {
+ public void run() {
+ try {
+ String result = template.getForObject(url + "?name={1}", String.class, "hello");
+ if (!"\"hello\"".equals(result)) {
+ notExpectedFailed.set(true);
+ }
+ } catch (Exception e) {
+ if (!(e instanceof HttpServerErrorException)) {
+ notExpectedFailed.set(true);
+ } else {
+ if (((HttpServerErrorException) e).getStatusCode().value() == 503) {
+ expectedFailed503.set(true);
+ }
+ if (((HttpServerErrorException) e).getStatusCode().value() == 502) {
+ expectedFailed502.set(true);
+ }
+ }
+ }
+ latch.countDown();
+ }
+ }.start();
+ }
+ Thread.sleep(100);
+ }
+
+ latch.await(20, TimeUnit.SECONDS);
+ TestMgr.check(true, expectedFailed502.get());
+ TestMgr.check(true, expectedFailed503.get());
+ TestMgr.check(false, notExpectedFailed.get());
+ }
+
+// private void testEdgeServiceRetry() {
+// String url = edgePrefix + "/business/v2/testEdgeServiceRetry";
+// String invocationID = UUID.randomUUID().toString();
+// String result = template.getForObject(url + "?invocationID={1}", String.class, invocationID);
+// TestMgr.check(result, "try times: 3");
+// }
+
+ private URIEndpointObject prepareEdge(String prefix) {
+ Microservice microservice = RegistrationManager.INSTANCE.getMicroservice();
+ MicroserviceInstance microserviceInstance = (MicroserviceInstance) DiscoveryManager.INSTANCE
+ .getAppManager()
+ .getOrCreateMicroserviceVersionRule(microservice.getAppId(), "edge", DefinitionConst.VERSION_RULE_ALL)
+ .getVersionedCache()
+ .mapData()
+ .values()
+ .stream()
+ .findFirst()
+ .get();
+ URIEndpointObject edgeAddress = new URIEndpointObject(microserviceInstance.getEndpoints().get(0));
+ edgePrefix = String.format("http://%s:%d/%s", edgeAddress.getHostOrIp(), edgeAddress.getPort(), prefix);
+ return edgeAddress;
+ }
+}
diff --git a/demo/demo-edge/edge-service/pom.xml b/demo/demo-edge/edge-service/pom.xml
index 4c322c8..59f27e7 100644
--- a/demo/demo-edge/edge-service/pom.xml
+++ b/demo/demo-edge/edge-service/pom.xml
@@ -27,7 +27,7 @@
<name>Java Chassis::Demo::Edge::Service</name>
<properties>
- <demo.main>org.apache.servicecomb.demo.edge.service.EdgeMain</demo.main>
+ <demo.main>org.apache.servicecomb.demo.edge.EdgeMain</demo.main>
</properties>
<dependencies>
@@ -41,6 +41,10 @@
</dependency>
<dependency>
<groupId>org.apache.servicecomb</groupId>
+ <artifactId>handler-governance</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
<artifactId>provider-pojo</artifactId>
</dependency>
</dependencies>
diff --git a/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/EdgeMain.java b/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/EdgeMain.java
similarity index 95%
rename from demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/EdgeMain.java
rename to demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/EdgeMain.java
index 1c5aebb..15165ec 100644
--- a/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/EdgeMain.java
+++ b/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/EdgeMain.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.servicecomb.demo.edge.service;
+package org.apache.servicecomb.demo.edge;
import org.apache.servicecomb.foundation.common.utils.BeanUtils;
import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
diff --git a/demo/demo-edge/edge-service/src/main/resources/microservice.yaml b/demo/demo-edge/edge-service/src/main/resources/microservice.yaml
index 1813c3f..4b2e12b 100644
--- a/demo/demo-edge/edge-service/src/main/resources/microservice.yaml
+++ b/demo/demo-edge/edge-service/src/main/resources/microservice.yaml
@@ -39,9 +39,9 @@
handler:
chain:
Consumer:
- default: auth,loadbalance
+ default: auth,loadbalance,instance-isolation-consumer,instance-bulkhead-consumer
service:
- auth: loadbalance
+ auth: loadbalance,instance-isolation-consumer,instance-bulkhead-consumer
http:
dispatcher:
edge:
@@ -80,4 +80,38 @@
prefixSegmentCount: 1
path: "/http/business/v1/dec.*"
microserviceName: business
- versionRule: 1.1.0
\ No newline at end of file
+ versionRule: 1.1.0
+
+# 服务治理配置
+ matchGroup:
+ testEdgeServiceRetry: |
+ matches:
+ - apiPath:
+ exact: "/business/v2/testEdgeServiceRetry"
+ testEdgeServiceInstanceIsolation: |
+ matches:
+ - apiPath:
+ exact: "/business/v2/testEdgeServiceInstanceIsolation"
+ testEdgeServiceInstanceBulkhead: |
+ matches:
+ - apiPath:
+ exact: "/business/v2/testEdgeServiceInstanceBulkhead"
+# retry not supported now
+# retry:
+# testEdgeServiceRetry: |
+# maxAttempts: 2
+# retryOnSame: 0
+ instanceIsolation:
+ testEdgeServiceInstanceIsolation: |
+ minimumNumberOfCalls: 10
+ slidingWindowSize: 20
+ slidingWindowType: COUNT_BASED
+ failureRateThreshold: 50
+ slowCallRateThreshold: 100
+ slowCallDurationThreshold: 3000
+ waitDurationInOpenState: 10000
+ permittedNumberOfCallsInHalfOpenState: 10
+ instanceBulkhead:
+ testEdgeServiceInstanceBulkhead: |
+ maxConcurrentCalls: 1
+ maxWaitDuration: 1
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filterext/IsolationDiscoveryFilter.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filterext/IsolationDiscoveryFilter.java
index 2def423..bbbda45 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filterext/IsolationDiscoveryFilter.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filterext/IsolationDiscoveryFilter.java
@@ -75,7 +75,7 @@
@Override
public boolean enabled() {
return DynamicPropertyFactory.getInstance()
- .getBooleanProperty(ISOLATION_FILTER_ENABLED, true)
+ .getBooleanProperty(ISOLATION_FILTER_ENABLED, false)
.get();
}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
index 56cd93f..e2a353d 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
@@ -73,6 +73,7 @@
public static void beforeClass() {
ConfigUtil.installDynamicConfig();
ArchaiusUtils.setProperty("servicecomb.loadbalance.userDefinedEndpoint.enabled", "true");
+ ArchaiusUtils.setProperty("servicecomb.loadbalance.filter.isolation.enabled", "true");
scbEngine = SCBBootstrap.createSCBEngineForTest().run();
}