From 5fe50861a6acfcead643b2771381b92bb8dfe290 Mon Sep 17 00:00:00 2001 From: andrew shan <45474304+andrewshan@users.noreply.github.com> Date: Sat, 10 Aug 2024 18:40:04 +0800 Subject: [PATCH 1/3] fix: use Objects.equals to compare objects (#545) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 优化熔断插件实现,解决用户通配API内存占用过高问题 (#533) * feat: support trace reporting * feat: restore version to 1.15.7-SNAPSHOT * feat: add initService to AssemblyAPI * test: add test for initService * fix: TraceReporterConfig type mistake * feat: support modify loglevel over parameter & support log in tracereporter * feat: 上报监控及调用链失败不抛异常 * fix: 校验失败打印端口号 * fix: add toString method to all configration classes * fix: 修复通配API导致counter及healthChecker膨胀的问题 * fix: 去掉统一的错误统计时长的配置,放回插件化配置中 * fix: 补齐测试用例 * fix: testcase failure * fix: test case failed by git test * fix: test case failed * fix: test case failure * fix: 健康检查变更影响范围过大问题 * fix: 解决探测规则生效多个的问题,只生效1个探测规则,并进行排序 * fix: 修复用例失败问题 * begin 1.15.9 * feat: 支持通配API统一计算 * fix: use Objects.equals to compare objects --- .../plugins/circuitbreaker/composite/PolarisCircuitBreaker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/main/java/com/tencent/polaris/plugins/circuitbreaker/composite/PolarisCircuitBreaker.java b/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/main/java/com/tencent/polaris/plugins/circuitbreaker/composite/PolarisCircuitBreaker.java index 2f7c31f60..1b2ac668a 100644 --- a/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/main/java/com/tencent/polaris/plugins/circuitbreaker/composite/PolarisCircuitBreaker.java +++ b/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/main/java/com/tencent/polaris/plugins/circuitbreaker/composite/PolarisCircuitBreaker.java @@ -113,7 +113,7 @@ public CircuitBreakerStatus checkResource(Resource resource) { Resource ruleResource = getActualResource(resource); Optional resourceCounters = getResourceCounters(ruleResource); if (null == resourceCounters) { - if (resource.getLevel() == Level.METHOD && ruleResource == resource) { + if (resource.getLevel() == Level.METHOD && Objects.equals(ruleResource, resource)) { // 可能是被淘汰了,需要重新计算RuleResource CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleDictionary.lookupCircuitBreakerRule(resource); ruleResource = computeResourceByRule(resource, circuitBreakerRule); From 310f7df16af3d8fdba5e4b0f9e10ba8984e91023 Mon Sep 17 00:00:00 2001 From: andrew shan <45474304+andrewshan@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:03:37 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=80=9A=E9=85=8D?= =?UTF-8?q?API=E5=9C=A8=E6=8E=A2=E6=B5=8B=E5=85=B3=E9=97=AD=E5=90=8E?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E5=81=9C=E6=AD=A2=E6=8E=A2=E6=B5=8B=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E7=9A=84=E9=97=AE=E9=A2=98=20(#547)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../factory/PrometheusHttpServerTest.java | 18 ++-- .../test/core/PrometheusHttpServerTest.java | 18 ++-- .../api/plugin/compose/Extensions.java | 2 + .../composite/PolarisCircuitBreaker.java | 83 ++++++++++++------- .../composite/ResourceHealthChecker.java | 2 +- .../composite/PolarisCircuitBreakerTest.java | 4 +- 6 files changed, 84 insertions(+), 43 deletions(-) diff --git a/polaris-assembly/polaris-assembly-factory/src/test/java/com/tencent/polaris/assembly/factory/PrometheusHttpServerTest.java b/polaris-assembly/polaris-assembly-factory/src/test/java/com/tencent/polaris/assembly/factory/PrometheusHttpServerTest.java index 30d1cf6bb..bccf89f6c 100644 --- a/polaris-assembly/polaris-assembly-factory/src/test/java/com/tencent/polaris/assembly/factory/PrometheusHttpServerTest.java +++ b/polaris-assembly/polaris-assembly-factory/src/test/java/com/tencent/polaris/assembly/factory/PrometheusHttpServerTest.java @@ -67,12 +67,18 @@ public void testHttpServerRandomPort() throws IOException { statReporterConfig.setPluginConfig(StatReporterConfig.DEFAULT_REPORTER_PROMETHEUS, prometheusHandlerConfig); try (SDKContext sdkContext = SDKContext.initContextByConfig(configuration)) { sdkContext.init(); - URL metricsUrl = new URL("http://127.0.0.1:28080/metrics"); - HttpURLConnection metricsConn = (HttpURLConnection) metricsUrl.openConnection(); - metricsConn.setRequestMethod("GET"); - metricsConn.connect(); - assertThat(metricsConn.getResponseCode()).isEqualTo(200); - metricsConn.disconnect(); + for (int i = 0; i < 3; i++) { + URL metricsUrl = new URL(String.format("http://127.0.0.1:%d/metrics", i)); + HttpURLConnection metricsConn = (HttpURLConnection) metricsUrl.openConnection(); + metricsConn.setRequestMethod("GET"); + try { + metricsConn.connect(); + } catch (IOException e) { + continue; + } + assertThat(metricsConn.getResponseCode()).isEqualTo(200); + metricsConn.disconnect(); + } } } diff --git a/polaris-discovery/polaris-discovery-factory/src/test/java/com/tencent/polaris/discovery/test/core/PrometheusHttpServerTest.java b/polaris-discovery/polaris-discovery-factory/src/test/java/com/tencent/polaris/discovery/test/core/PrometheusHttpServerTest.java index 5ecb42b98..b5cfffae4 100644 --- a/polaris-discovery/polaris-discovery-factory/src/test/java/com/tencent/polaris/discovery/test/core/PrometheusHttpServerTest.java +++ b/polaris-discovery/polaris-discovery-factory/src/test/java/com/tencent/polaris/discovery/test/core/PrometheusHttpServerTest.java @@ -67,12 +67,18 @@ public void testHttpServerRandomPort() throws IOException { statReporterConfig.setPluginConfig(StatReporterConfig.DEFAULT_REPORTER_PROMETHEUS, prometheusHandlerConfig); try (SDKContext sdkContext = SDKContext.initContextByConfig(configuration)) { sdkContext.init(); - URL metricsUrl = new URL("http://127.0.0.1:28080/metrics"); - HttpURLConnection metricsConn = (HttpURLConnection) metricsUrl.openConnection(); - metricsConn.setRequestMethod("GET"); - metricsConn.connect(); - assertThat(metricsConn.getResponseCode()).isEqualTo(200); - metricsConn.disconnect(); + for (int i = 0; i < 3; i++) { + URL metricsUrl = new URL(String.format("http://127.0.0.1:%d/metrics", 28080 + i)); + HttpURLConnection metricsConn = (HttpURLConnection) metricsUrl.openConnection(); + metricsConn.setRequestMethod("GET"); + try { + metricsConn.connect(); + } catch (IOException e) { + continue; + } + assertThat(metricsConn.getResponseCode()).isEqualTo(200); + metricsConn.disconnect(); + } } } diff --git a/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/compose/Extensions.java b/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/compose/Extensions.java index a8a28629c..cc141f164 100644 --- a/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/compose/Extensions.java +++ b/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/compose/Extensions.java @@ -49,6 +49,7 @@ import com.tencent.polaris.api.utils.StringUtils; import com.tencent.polaris.client.pojo.Node; import com.tencent.polaris.client.util.NamedThreadFactory; +import com.tencent.polaris.client.util.Utils; import com.tencent.polaris.logging.LoggerFactory; import com.tencent.polaris.specification.api.v1.model.ModelProto; import com.tencent.polaris.specification.api.v1.traffic.manage.RoutingProto; @@ -573,6 +574,7 @@ protected void doDestroy() { HttpServer httpServer = entry.getValue(); httpServer.stop(0); ((ExecutorService) httpServer.getExecutor()).shutdownNow(); + Utils.sleepUninterrupted(1000); } } } diff --git a/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/main/java/com/tencent/polaris/plugins/circuitbreaker/composite/PolarisCircuitBreaker.java b/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/main/java/com/tencent/polaris/plugins/circuitbreaker/composite/PolarisCircuitBreaker.java index 1b2ac668a..37e240f57 100644 --- a/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/main/java/com/tencent/polaris/plugins/circuitbreaker/composite/PolarisCircuitBreaker.java +++ b/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/main/java/com/tencent/polaris/plugins/circuitbreaker/composite/PolarisCircuitBreaker.java @@ -90,7 +90,7 @@ public class PolarisCircuitBreaker extends Destroyable implements CircuitBreaker // map the wildcard resource to rule specific resource, // eg. /path/wildcard/123 => /path/wildcard/.+ - private Cache resourceMapping; + private final Map resourceMapping = new ConcurrentHashMap<>(); private Extensions extensions; @@ -102,6 +102,8 @@ public class PolarisCircuitBreaker extends Destroyable implements CircuitBreaker private long checkPeriod; + private long resourceExpireInterval; + private CircuitBreakerRuleDictionary circuitBreakerRuleDictionary; private FaultDetectRuleDictionary faultDetectRuleDictionary; @@ -110,7 +112,7 @@ public class PolarisCircuitBreaker extends Destroyable implements CircuitBreaker @Override public CircuitBreakerStatus checkResource(Resource resource) { - Resource ruleResource = getActualResource(resource); + Resource ruleResource = getActualResource(resource, false); Optional resourceCounters = getResourceCounters(ruleResource); if (null == resourceCounters) { if (resource.getLevel() == Level.METHOD && Objects.equals(ruleResource, resource)) { @@ -118,7 +120,7 @@ public CircuitBreakerStatus checkResource(Resource resource) { CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleDictionary.lookupCircuitBreakerRule(resource); ruleResource = computeResourceByRule(resource, circuitBreakerRule); if (!Objects.equals(ruleResource, resource)) { - resourceMapping.put(resource, ruleResource); + // 这里不能放缓存,需要在report的时候统一放,否则会有探测规则无法关联resource的问题 resourceCounters = getResourceCounters(ruleResource); } } @@ -139,16 +141,19 @@ public void report(ResourceStat resourceStat) { doReport(resourceStat, true); } - public Resource getActualResource(Resource resource) { - Resource ruleResource = resourceMapping.getIfPresent(resource); - if (null == ruleResource) { - ruleResource = resource; + public Resource getActualResource(Resource resource, boolean internal) { + ResourceWrap resourceWrap = resourceMapping.get(resource); + if (null == resourceWrap) { + return resource; + } + if (!internal) { + resourceWrap.lastAccessTimeMilli = System.currentTimeMillis(); } - return ruleResource; + return resourceWrap.resource; } private ResourceCounters getOrInitResourceCounters(Resource resource) throws ExecutionException { - Resource ruleResource = getActualResource(resource); + Resource ruleResource = getActualResource(resource, false); Optional resourceCounters = getResourceCounters(ruleResource); boolean reloadFaultDetect = false; if (null == resourceCounters) { @@ -211,7 +216,7 @@ private void reloadFaultDetector(Resource resource, ResourceCounters resourceCou if (null == healthCheckContainer) { return; } - healthCheckContainer.removeResource(getActualResource(resource)); + healthCheckContainer.removeResource(resource); } else { if (null == healthCheckContainer) { @@ -268,10 +273,12 @@ private Optional initResourceCounter(Resource resource) throws Cache> resourceOptionalCache = countersCache.get(resource.getLevel()); CircuitBreakerProto.CircuitBreakerRule finalCircuitBreakerRule = circuitBreakerRule; Resource ruleResource = computeResourceByRule(resource, circuitBreakerRule); + if (!Objects.equals(ruleResource, resource)) { + resourceMapping.put(resource, new ResourceWrap(ruleResource, System.currentTimeMillis())); + } return resourceOptionalCache.get(ruleResource, new Callable>() { @Override public Optional call() { - resourceMapping.put(resource, ruleResource); if (null == finalCircuitBreakerRule) { return Optional.empty(); } @@ -303,7 +310,7 @@ private void addInstanceForFaultDetect(Resource resource) { InstanceResource instanceResource = (InstanceResource) resource; HealthCheckContainer healthCheckContainer = healthCheckCache .get(instanceResource.getService()); - if (null == healthCheckContainer) { + if (null == healthCheckContainer || instanceResource.getPort() == 0) { return; } healthCheckContainer.addInstance(instanceResource); @@ -314,7 +321,7 @@ public PluginType getType() { return PluginTypes.CIRCUIT_BREAKER.getBaseType(); } - private class CounterRemoveListener implements RemovalListener> { + private static class CounterRemoveListener implements RemovalListener> { @Override public void onRemoval(RemovalNotification> removalNotification) { @@ -323,21 +330,12 @@ public void onRemoval(RemovalNotification> return; } value.ifPresent(resourceCounters -> resourceCounters.setDestroyed(true)); - Resource resource = removalNotification.getKey(); - if (null == resource) { - return; - } - HealthCheckContainer healthCheckContainer = PolarisCircuitBreaker.this.healthCheckCache.get(resource.getService()); - if (null != healthCheckContainer) { - healthCheckContainer.removeResource(resource); - } } } @Override public void init(InitContext ctx) throws PolarisException { - long expireIntervalMilli = ctx.getConfig().getConsumer().getCircuitBreaker().getCountersExpireInterval(); - resourceMapping = CacheBuilder.newBuilder().expireAfterAccess(expireIntervalMilli, TimeUnit.MILLISECONDS).build(); + resourceExpireInterval = ctx.getConfig().getConsumer().getCircuitBreaker().getCountersExpireInterval(); countersCache.put(Level.SERVICE, CacheBuilder.newBuilder().removalListener(new CounterRemoveListener()).build()); countersCache.put(Level.METHOD, CacheBuilder.newBuilder().removalListener(new CounterRemoveListener()).build()); countersCache.put(Level.INSTANCE, CacheBuilder.newBuilder().removalListener(new CounterRemoveListener()).build()); @@ -366,7 +364,19 @@ public void run() { } public void cleanupExpiredResources() { - resourceMapping.cleanUp(); + LOG.info("[CIRCUIT_BREAKER] cleanup expire resources"); + for (Map.Entry entry : resourceMapping.entrySet()) { + Resource resource = entry.getKey(); + if (System.currentTimeMillis() - entry.getValue().lastAccessTimeMilli >= resourceExpireInterval) { + LOG.info("[CIRCUIT_BREAKER] resource {} expired, start to cleanup", resource); + resourceMapping.remove(resource); + HealthCheckContainer healthCheckContainer = healthCheckCache.get(resource.getService()); + if (null == healthCheckContainer) { + continue; + } + healthCheckContainer.removeResource(resource); + } + } for (Map.Entry>> entry : countersCache.entrySet()) { Cache> values = entry.getValue(); values.asMap().forEach(new BiConsumer>() { @@ -458,8 +468,8 @@ public void setCircuitBreakerConfig(CircuitBreakerConfig circuitBreakerConfig) { this.circuitBreakerConfig = circuitBreakerConfig; } - Cache getResourceMapping() { - return resourceMapping; + int getResourceMappingSize() { + return resourceMapping.size(); } @Override @@ -477,8 +487,13 @@ void onCircuitBreakerRuleChanged(ServiceKey serviceKey) { if (Objects.equals(resource.getService(), serviceKey)) { cacheValue.invalidate(resource); } - HealthCheckContainer healthCheckContainer = healthCheckCache.get(serviceKey); - if (null != healthCheckContainer) { + } + } + HealthCheckContainer healthCheckContainer = healthCheckCache.get(serviceKey); + if (null != healthCheckContainer) { + for (Map.Entry entry : resourceMapping.entrySet()) { + Resource resource = entry.getKey(); + if (Objects.equals(resource.getService(), serviceKey)) { LOG.info("onCircuitBreakerRuleChanged: clear resource {} from healthCheckContainer", resource); healthCheckContainer.removeResource(resource); } @@ -551,4 +566,16 @@ public HealthCheckContainer apply(ServiceKey serviceKey, HealthCheckContainer he } }); } + + private static class ResourceWrap { + // target resource, not nullable + final Resource resource; + // only record the report time + long lastAccessTimeMilli; + + ResourceWrap(Resource resource, long lastAccessTimeMilli) { + this.resource = resource; + this.lastAccessTimeMilli = lastAccessTimeMilli; + } + } } diff --git a/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/main/java/com/tencent/polaris/plugins/circuitbreaker/composite/ResourceHealthChecker.java b/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/main/java/com/tencent/polaris/plugins/circuitbreaker/composite/ResourceHealthChecker.java index 025705e7e..302a1a28b 100644 --- a/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/main/java/com/tencent/polaris/plugins/circuitbreaker/composite/ResourceHealthChecker.java +++ b/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/main/java/com/tencent/polaris/plugins/circuitbreaker/composite/ResourceHealthChecker.java @@ -190,7 +190,7 @@ private boolean doCheck(Instance instance, Protocol protocol, FaultDetectRule fa if (!matchInstanceToResource(instance, resource)) { continue; } - Resource actualResource = polarisCircuitBreaker.getActualResource(resource); + Resource actualResource = polarisCircuitBreaker.getActualResource(resource, true); if (reportedResources.contains(actualResource)) { continue; } diff --git a/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/test/java/com/tencent/polaris/plugins/circuitbreaker/composite/PolarisCircuitBreakerTest.java b/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/test/java/com/tencent/polaris/plugins/circuitbreaker/composite/PolarisCircuitBreakerTest.java index f2a0a0373..16021363f 100644 --- a/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/test/java/com/tencent/polaris/plugins/circuitbreaker/composite/PolarisCircuitBreakerTest.java +++ b/polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/test/java/com/tencent/polaris/plugins/circuitbreaker/composite/PolarisCircuitBreakerTest.java @@ -244,7 +244,7 @@ public void testCircuitBreakerMethodRules() { Assert.assertEquals(Status.OPEN, circuitBreakerStatus.getStatus()); } Assert.assertEquals(1, polarisCircuitBreaker.getCountersCache().get(Level.METHOD).size()); - Assert.assertEquals(1000, polarisCircuitBreaker.getResourceMapping().size()); + Assert.assertEquals(1000, polarisCircuitBreaker.getResourceMappingSize()); //check cleanup try { @@ -253,6 +253,6 @@ public void testCircuitBreakerMethodRules() { e.printStackTrace(); } polarisCircuitBreaker.cleanupExpiredResources(); - Assert.assertEquals(0, polarisCircuitBreaker.getResourceMapping().size()); + Assert.assertEquals(0, polarisCircuitBreaker.getResourceMappingSize()); } } From 05b42541b3684113e57768852a8ccdb1b8b8d5a5 Mon Sep 17 00:00:00 2001 From: Haotian Zhang <928016560@qq.com> Date: Mon, 12 Aug 2024 16:59:58 +0800 Subject: [PATCH 3/3] fix:fix circuit breaker junit first delay error. --- .../factory/test/CircuitBreakerMultiTest.java | 380 +++++++++--------- .../factory/test/CircuitBreakerTest.java | 32 +- .../factory/test/FaultDetectorTest.java | 226 +++++------ 3 files changed, 320 insertions(+), 318 deletions(-) diff --git a/polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test/CircuitBreakerMultiTest.java b/polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test/CircuitBreakerMultiTest.java index 792597372..bcde23643 100644 --- a/polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test/CircuitBreakerMultiTest.java +++ b/polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test/CircuitBreakerMultiTest.java @@ -17,12 +17,6 @@ package com.tencent.polaris.circuitbreaker.factory.test; -import java.io.IOException; -import java.util.Collection; -import java.util.Map; -import java.util.Optional; -import java.util.function.Consumer; - import com.google.common.cache.Cache; import com.google.protobuf.StringValue; import com.tencent.polaris.api.config.Configuration; @@ -52,208 +46,212 @@ import org.junit.Test; import org.slf4j.Logger; +import java.io.IOException; +import java.util.Collection; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; + import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.Consts.SERVICE_CIRCUIT_BREAKER; import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV; public class CircuitBreakerMultiTest { - private static final Logger LOG = LoggerFactory.getLogger(CircuitBreakerMultiTest.class); + private static final Logger LOG = LoggerFactory.getLogger(CircuitBreakerMultiTest.class); - private NamingServer namingServer; + private NamingServer namingServer; - private final ServiceKey matchMethodService = new ServiceKey("Test", "SvcCbMethod"); + private final ServiceKey matchMethodService = new ServiceKey("Test", "SvcCbMethod"); - private final ServiceKey matchMethodDetectService = new ServiceKey("Test", "SvcCbMethodDetect"); + private final ServiceKey matchMethodDetectService = new ServiceKey("Test", "SvcCbMethodDetect"); - @Before - public void before() throws IOException { - try { - namingServer = NamingServer.startNamingServer(-1); - System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } - catch (IOException e) { - Assert.fail(e.getMessage()); - } + @Before + public void before() throws IOException { + try { + namingServer = NamingServer.startNamingServer(-1); + System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); + } catch (IOException e) { + Assert.fail(e.getMessage()); + } - CircuitBreakerProto.CircuitBreakerRule cbRule1 = CbTestUtils.loadCbRule("circuitBreakerMethodRuleNoDetect.json"); - CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() - .addRules(cbRule1).setRevision(StringValue.newBuilder().setValue("0000").build()).build(); - namingServer.getNamingService().setCircuitBreaker(matchMethodService, circuitBreaker); + CircuitBreakerProto.CircuitBreakerRule cbRule1 = CbTestUtils.loadCbRule("circuitBreakerMethodRuleNoDetect.json"); + CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() + .addRules(cbRule1).setRevision(StringValue.newBuilder().setValue("0000").build()).build(); + namingServer.getNamingService().setCircuitBreaker(matchMethodService, circuitBreaker); - CircuitBreakerProto.CircuitBreakerRule cbRule3 = CbTestUtils.loadCbRule("circuitBreakerMethodRule.json"); - CircuitBreakerProto.CircuitBreakerRule cbRule4 = CbTestUtils.loadCbRule("circuitBreakerRule.json"); - circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() - .addRules(cbRule3).addRules(cbRule4).setRevision(StringValue.newBuilder().setValue("1111").build()).build(); - namingServer.getNamingService().setCircuitBreaker(matchMethodDetectService, circuitBreaker); - FaultDetectorProto.FaultDetectRule rule1 = CbTestUtils.loadFdRule("faultDetectRule.json"); - FaultDetectorProto.FaultDetectRule rule2 = CbTestUtils.loadFdRule("faultDetectMethodRule.json"); - FaultDetectorProto.FaultDetector faultDetector = FaultDetectorProto.FaultDetector.newBuilder() - .addRules(rule1).addRules(rule2).setRevision("2222").build(); - namingServer.getNamingService().setFaultDetector(matchMethodDetectService, faultDetector); - } + CircuitBreakerProto.CircuitBreakerRule cbRule3 = CbTestUtils.loadCbRule("circuitBreakerMethodRule.json"); + CircuitBreakerProto.CircuitBreakerRule cbRule4 = CbTestUtils.loadCbRule("circuitBreakerRule.json"); + circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() + .addRules(cbRule3).addRules(cbRule4).setRevision(StringValue.newBuilder().setValue("1111").build()).build(); + namingServer.getNamingService().setCircuitBreaker(matchMethodDetectService, circuitBreaker); + FaultDetectorProto.FaultDetectRule rule1 = CbTestUtils.loadFdRule("faultDetectRule.json"); + FaultDetectorProto.FaultDetectRule rule2 = CbTestUtils.loadFdRule("faultDetectMethodRule.json"); + FaultDetectorProto.FaultDetector faultDetector = FaultDetectorProto.FaultDetector.newBuilder() + .addRules(rule1).addRules(rule2).setRevision("2222").build(); + namingServer.getNamingService().setFaultDetector(matchMethodDetectService, faultDetector); + } - @Test - public void testMultipleUrlsNoRule() { - Configuration configuration = TestUtils.configWithEnvAddress(); - ConfigurationImpl configurationImpl = (ConfigurationImpl) configuration; - configurationImpl.getConsumer().getCircuitBreaker().setCountersExpireInterval(5000); - try (CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configurationImpl)) { - for (int i = 0; i < 50; i++) { - FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest( - new ServiceKey(NAMESPACE_TEST, SERVICE_CIRCUIT_BREAKER), "/test/" + i); - FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest); - int finalI = i; - Consumer integerConsumer = decorator.decorateConsumer(num -> { - if (num % 2 == 0) { - throw new IllegalArgumentException("invoke failed" + finalI); - } - else { - System.out.println("invoke success" + finalI); - } - }); - integerConsumer.accept(1); - } - Utils.sleepUninterrupted(10 * 1000); - BaseEngine baseEngine = (BaseEngine) circuitBreakAPI; - CircuitBreaker resourceBreaker = baseEngine.getSDKContext().getExtensions().getResourceBreaker(); - PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) resourceBreaker; - Cache> methodCache = polarisCircuitBreaker.getCountersCache() - .get(CircuitBreakerProto.Level.METHOD); - polarisCircuitBreaker.cleanupExpiredResources(); - Assert.assertEquals(0, methodCache.size()); - } - } + @Test + public void testMultipleUrlsNoRule() { + Configuration configuration = TestUtils.configWithEnvAddress(); + ConfigurationImpl configurationImpl = (ConfigurationImpl) configuration; + configurationImpl.getConsumer().getCircuitBreaker().setCountersExpireInterval(5000); + try (CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configurationImpl)) { + for (int i = 0; i < 50; i++) { + FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest( + new ServiceKey(NAMESPACE_TEST, SERVICE_CIRCUIT_BREAKER), "/test/" + i); + FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest); + int finalI = i; + Consumer integerConsumer = decorator.decorateConsumer(num -> { + if (num % 2 == 0) { + throw new IllegalArgumentException("invoke failed" + finalI); + } else { + System.out.println("invoke success" + finalI); + } + }); + integerConsumer.accept(1); + } + Utils.sleepUninterrupted(10 * 1000); + BaseEngine baseEngine = (BaseEngine) circuitBreakAPI; + CircuitBreaker resourceBreaker = baseEngine.getSDKContext().getExtensions().getResourceBreaker(); + PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) resourceBreaker; + Cache> methodCache = polarisCircuitBreaker.getCountersCache() + .get(CircuitBreakerProto.Level.METHOD); + polarisCircuitBreaker.cleanupExpiredResources(); + Assert.assertEquals(0, methodCache.size()); + } + } - @Test - public void testMultipleUrlsMethodRule() { - Configuration configuration = TestUtils.configWithEnvAddress(); - ConfigurationImpl configurationImpl = (ConfigurationImpl) configuration; - configurationImpl.getConsumer().getCircuitBreaker().setCountersExpireInterval(5000); - try (CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configurationImpl)) { - for (int i = 0; i < 50; i++) { - FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest( - matchMethodService, "/test1/path/" + i); - FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest); - int finalI = i; - Consumer integerConsumer = decorator.decorateConsumer(num -> { - if (num % 2 == 0) { - throw new IllegalArgumentException("invoke failed" + finalI); - } - else { - System.out.println("invoke success" + finalI); - } - }); - if (i == 0) { - integerConsumer.accept(1); - try { - integerConsumer.accept(2); - } catch (Exception e) { - if (!(e instanceof IllegalArgumentException)) { - throw e; - } - } - Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(3)); - } else { - Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(1)); - } - } - BaseEngine baseEngine = (BaseEngine) circuitBreakAPI; - CircuitBreaker resourceBreaker = baseEngine.getSDKContext().getExtensions().getResourceBreaker(); - PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) resourceBreaker; - Cache> methodCache = polarisCircuitBreaker.getCountersCache() - .get(CircuitBreakerProto.Level.METHOD); - Assert.assertEquals(1, methodCache.size()); - } - } + @Test + public void testMultipleUrlsMethodRule() { + Configuration configuration = TestUtils.configWithEnvAddress(); + ConfigurationImpl configurationImpl = (ConfigurationImpl) configuration; + configurationImpl.getConsumer().getCircuitBreaker().setCountersExpireInterval(5000); + try (CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configurationImpl)) { + for (int i = 0; i < 50; i++) { + if (i == 1) { + Utils.sleepUninterrupted(5 * 1000); + } + FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest( + matchMethodService, "/test1/path/" + i); + FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest); + int finalI = i; + Consumer integerConsumer = decorator.decorateConsumer(num -> { + if (num % 2 == 0) { + throw new IllegalArgumentException("invoke failed" + finalI); + } else { + System.out.println("invoke success" + finalI); + } + }); + if (i == 0) { + integerConsumer.accept(1); + try { + integerConsumer.accept(2); + } catch (Exception e) { + if (!(e instanceof IllegalArgumentException)) { + throw e; + } + } + Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(3)); + } else { + Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(1)); + } + } + BaseEngine baseEngine = (BaseEngine) circuitBreakAPI; + CircuitBreaker resourceBreaker = baseEngine.getSDKContext().getExtensions().getResourceBreaker(); + PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) resourceBreaker; + Cache> methodCache = polarisCircuitBreaker.getCountersCache() + .get(CircuitBreakerProto.Level.METHOD); + Assert.assertEquals(1, methodCache.size()); + } + } - @Test - public void testCircuitBreakerRuleChanged() throws IOException { - Configuration configuration = TestUtils.configWithEnvAddress(); - ConfigurationImpl configurationImpl = (ConfigurationImpl) configuration; - try (CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configurationImpl)) { - for (int i = 0; i < 50; i++) { - String method = ""; - if (i > 0) { - method = "/test1/path/" + i; - } - FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest( - matchMethodDetectService, method); - FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest); - int finalI = i; - Consumer integerConsumer = decorator.decorateConsumer(num -> { - if (num % 2 == 0) { - throw new IllegalArgumentException("invoke failed" + finalI); - } - else { - System.out.println("invoke success" + finalI); - } - }); - integerConsumer.accept(1); - } - CircuitBreakerProto.CircuitBreakerRule cbRule1 = CbTestUtils.loadCbRule("circuitBreakerMethodRuleChanged.json"); - CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() - .addRules(cbRule1).setRevision(StringValue.newBuilder().setValue("444441").build()).build(); - namingServer.getNamingService().setCircuitBreaker(matchMethodDetectService, circuitBreaker); - Utils.sleepUninterrupted(20 * 1000); - BaseEngine baseEngine = (BaseEngine) circuitBreakAPI; - CircuitBreaker resourceBreaker = baseEngine.getSDKContext().getExtensions().getResourceBreaker(); - PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) resourceBreaker; - Cache> methodCache = polarisCircuitBreaker.getCountersCache() - .get(CircuitBreakerProto.Level.METHOD); - Assert.assertEquals(0, methodCache.size()); + @Test + public void testCircuitBreakerRuleChanged() throws IOException { + Configuration configuration = TestUtils.configWithEnvAddress(); + ConfigurationImpl configurationImpl = (ConfigurationImpl) configuration; + try (CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configurationImpl)) { + for (int i = 0; i < 50; i++) { + if (i == 1) { + Utils.sleepUninterrupted(5 * 1000); + } + String method = ""; + if (i > 0) { + method = "/test1/path/" + i; + } + FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest( + matchMethodDetectService, method); + FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest); + int finalI = i; + Consumer integerConsumer = decorator.decorateConsumer(num -> { + if (num % 2 == 0) { + throw new IllegalArgumentException("invoke failed" + finalI); + } else { + System.out.println("invoke success" + finalI); + } + }); + integerConsumer.accept(1); + } + CircuitBreakerProto.CircuitBreakerRule cbRule1 = CbTestUtils.loadCbRule("circuitBreakerMethodRuleChanged.json"); + CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() + .addRules(cbRule1).setRevision(StringValue.newBuilder().setValue("444441").build()).build(); + namingServer.getNamingService().setCircuitBreaker(matchMethodDetectService, circuitBreaker); + Utils.sleepUninterrupted(20 * 1000); + BaseEngine baseEngine = (BaseEngine) circuitBreakAPI; + CircuitBreaker resourceBreaker = baseEngine.getSDKContext().getExtensions().getResourceBreaker(); + PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) resourceBreaker; + Cache> methodCache = polarisCircuitBreaker.getCountersCache() + .get(CircuitBreakerProto.Level.METHOD); + Assert.assertEquals(0, methodCache.size()); - Map healthCheckCache = polarisCircuitBreaker.getHealthCheckCache(); - HealthCheckContainer healthCheckContainer = healthCheckCache.get(matchMethodDetectService); - Assert.assertNotNull(healthCheckContainer); - Collection healthCheckerValues = healthCheckContainer.getHealthCheckerValues(); - Assert.assertEquals(2, healthCheckerValues.size()); - for (int i = 0; i < 10; i++) { - String method = "/test1/path/" + i; - FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest( - matchMethodDetectService, method); - FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest); - int finalI = i; - Consumer integerConsumer = decorator.decorateConsumer(num -> { - if (num < 3) { - throw new IllegalArgumentException("invoke failed" + finalI); - } - else { - System.out.println("invoke success" + finalI); - } - }); - if (i == 0) { - try { - integerConsumer.accept(1); - } - catch (Exception e) { - if (!(e instanceof IllegalArgumentException)) { - throw e; - } - } - try { - integerConsumer.accept(2); - } - catch (Exception e) { - if (!(e instanceof IllegalArgumentException)) { - throw e; - } - } - Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(3)); - } - else { - Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(1)); - } - } - } - } + Map healthCheckCache = polarisCircuitBreaker.getHealthCheckCache(); + HealthCheckContainer healthCheckContainer = healthCheckCache.get(matchMethodDetectService); + Assert.assertNotNull(healthCheckContainer); + Collection healthCheckerValues = healthCheckContainer.getHealthCheckerValues(); + Assert.assertEquals(2, healthCheckerValues.size()); + for (int i = 0; i < 10; i++) { + String method = "/test1/path/" + i; + FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest( + matchMethodDetectService, method); + FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest); + int finalI = i; + Consumer integerConsumer = decorator.decorateConsumer(num -> { + if (num < 3) { + throw new IllegalArgumentException("invoke failed" + finalI); + } else { + System.out.println("invoke success" + finalI); + } + }); + if (i == 0) { + try { + integerConsumer.accept(1); + } catch (Exception e) { + if (!(e instanceof IllegalArgumentException)) { + throw e; + } + } + try { + integerConsumer.accept(2); + } catch (Exception e) { + if (!(e instanceof IllegalArgumentException)) { + throw e; + } + } + Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(3)); + } else { + Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(1)); + } + } + } + } - @After - public void after() { - if (null != namingServer) { - namingServer.terminate(); - } - } + @After + public void after() { + if (null != namingServer) { + namingServer.terminate(); + } + } } diff --git a/polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test/CircuitBreakerTest.java b/polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test/CircuitBreakerTest.java index e6005059a..e045f3468 100644 --- a/polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test/CircuitBreakerTest.java +++ b/polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test/CircuitBreakerTest.java @@ -17,16 +17,6 @@ package com.tencent.polaris.circuitbreaker.factory.test; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.List; -import java.util.function.Consumer; -import java.util.stream.Collectors; - import com.google.protobuf.util.JsonFormat; import com.tencent.polaris.api.config.Configuration; import com.tencent.polaris.api.config.plugin.DefaultPlugins; @@ -56,6 +46,16 @@ import org.junit.Test; import org.slf4j.Logger; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; + import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.Consts.SERVICE_CIRCUIT_BREAKER; import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV; @@ -154,6 +154,9 @@ public void testCircuitBreakByErrorCount() { Instance instanceToLimit = instances.get(1); //report 60 fail in 500ms for (int i = 0; i < 60; ++i) { + if (i == 1) { + Utils.sleepUninterrupted(5 * 1000); + } ServiceCallResult result = instanceToResult(instanceToLimit); result.setRetCode(-1); result.setDelay(1000L); @@ -216,6 +219,9 @@ public void testCircuitBreakByErrorRate() { Instance instanceToLimit = instances.get(1); //report 60 fail in 500ms for (int i = 0; i < 60; ++i) { + if (i == 1) { + Utils.sleepUninterrupted(5 * 1000); + } ServiceCallResult result = instanceToResult(instanceToLimit); result.setDelay(1000L); if (i % 2 == 0) { @@ -268,8 +274,7 @@ public void testFunctionalDecorator() { Consumer integerConsumer = decorator.decorateConsumer(num -> { if (num % 2 == 0) { throw new IllegalArgumentException("invoke failed"); - } - else { + } else { System.out.println("invoke success"); } }); @@ -278,8 +283,7 @@ public void testFunctionalDecorator() { Utils.sleepUninterrupted(1000); integerConsumer.accept(2); Utils.sleepUninterrupted(1000); - } - catch (Exception e) { + } catch (Exception e) { if (!(e instanceof IllegalArgumentException)) { throw e; } diff --git a/polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test/FaultDetectorTest.java b/polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test/FaultDetectorTest.java index 012fe9314..f638d4bb9 100644 --- a/polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test/FaultDetectorTest.java +++ b/polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test/FaultDetectorTest.java @@ -17,11 +17,6 @@ package com.tencent.polaris.circuitbreaker.factory.test; -import java.io.IOException; -import java.util.Collection; -import java.util.Map; -import java.util.function.Consumer; - import com.google.protobuf.StringValue; import com.tencent.polaris.api.config.Configuration; import com.tencent.polaris.api.plugin.circuitbreaker.CircuitBreaker; @@ -45,116 +40,121 @@ import org.junit.Before; import org.junit.Test; +import java.io.IOException; +import java.util.Collection; +import java.util.Map; +import java.util.function.Consumer; + import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV; public class FaultDetectorTest { - private NamingServer namingServer; - - private final ServiceKey matchMethodService = new ServiceKey("Test", "SvcCbMethod"); - - private final ServiceKey matchMethodDetectService = new ServiceKey("Test", "SvcCbMethodDetect"); - - @Before - public void before() throws IOException { - try { - namingServer = NamingServer.startNamingServer(-1); - System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } - catch (IOException e) { - Assert.fail(e.getMessage()); - } - - CircuitBreakerProto.CircuitBreakerRule cbRule1 = CbTestUtils.loadCbRule("circuitBreakerMethodRuleNoDetect.json"); - CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() - .addRules(cbRule1).setRevision(StringValue.newBuilder().setValue("0000").build()).build(); - namingServer.getNamingService().setCircuitBreaker(matchMethodService, circuitBreaker); - - - CircuitBreakerProto.CircuitBreakerRule cbRule3 = CbTestUtils.loadCbRule("circuitBreakerMethodRule.json"); - CircuitBreakerProto.CircuitBreakerRule cbRule4 = CbTestUtils.loadCbRule("circuitBreakerRule.json"); - circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() - .addRules(cbRule3).addRules(cbRule4).setRevision(StringValue.newBuilder().setValue("1111").build()).build(); - namingServer.getNamingService().setCircuitBreaker(matchMethodDetectService, circuitBreaker); - FaultDetectorProto.FaultDetectRule rule1 = CbTestUtils.loadFdRule("faultDetectRule.json"); - FaultDetectorProto.FaultDetectRule rule2 = CbTestUtils.loadFdRule("faultDetectMethodRule.json"); - FaultDetectorProto.FaultDetector faultDetector = FaultDetectorProto.FaultDetector.newBuilder() - .addRules(rule1).addRules(rule2).setRevision("2222").build(); - namingServer.getNamingService().setFaultDetector(matchMethodDetectService, faultDetector); - } - - @Test - public void testFaultDetectRuleChanged() throws IOException { - Configuration configuration = TestUtils.configWithEnvAddress(); - ConfigurationImpl configurationImpl = (ConfigurationImpl) configuration; - try (CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configurationImpl)) { - for (int i = 0; i < 10; i++) { - String method = ""; - if (i < 9) { - method = "/test1/path/" + i; - } - FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest( - matchMethodDetectService, method); - FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest); - int finalI = i; - Consumer integerConsumer = decorator.decorateConsumer(num -> { - if (num % 2 == 0) { - throw new IllegalArgumentException("invoke failed" + finalI); - } - else { - System.out.println("invoke success" + finalI); - } - }); - integerConsumer.accept(1); - } - BaseEngine baseEngine = (BaseEngine) circuitBreakAPI; - CircuitBreaker resourceBreaker = baseEngine.getSDKContext().getExtensions().getResourceBreaker(); - PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) resourceBreaker; - Map healthCheckCache = polarisCircuitBreaker.getHealthCheckCache(); - Assert.assertEquals(1, healthCheckCache.size()); - HealthCheckContainer healthCheckContainer = healthCheckCache.get(matchMethodDetectService); - Assert.assertNotNull(healthCheckContainer); - Collection healthCheckerValues = healthCheckContainer.getHealthCheckerValues(); - Assert.assertEquals(2, healthCheckerValues.size()); - - FaultDetectorProto.FaultDetectRule rule1 = CbTestUtils.loadFdRule("faultDetectMethodRuleChanged.json"); - FaultDetectorProto.FaultDetector faultDetector = FaultDetectorProto.FaultDetector.newBuilder() - .addRules(rule1).setRevision("33333").build(); - namingServer.getNamingService().setFaultDetector(matchMethodDetectService, faultDetector); - - Utils.sleepUninterrupted(20 * 1000); - healthCheckContainer = healthCheckCache.get(matchMethodDetectService); - Assert.assertNull(healthCheckContainer); - for (int i = 0; i < 3; i++) { - String method = ""; - if (i > 0) { - method = "/test1/path/" + i; - } - FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest( - matchMethodDetectService, method); - FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest); - int finalI = i; - Consumer integerConsumer = decorator.decorateConsumer(num -> { - if (num % 2 == 0) { - throw new IllegalArgumentException("invoke failed" + finalI); - } - else { - System.out.println("invoke success" + finalI); - } - }); - integerConsumer.accept(1); - } - healthCheckContainer = healthCheckCache.get(matchMethodDetectService); - Assert.assertNotNull(healthCheckContainer); - healthCheckerValues = healthCheckContainer.getHealthCheckerValues(); - Assert.assertEquals(1, healthCheckerValues.size()); - } - } - - @After - public void after() { - if (null != namingServer) { - namingServer.terminate(); - } - } + private NamingServer namingServer; + + private final ServiceKey matchMethodService = new ServiceKey("Test", "SvcCbMethod"); + + private final ServiceKey matchMethodDetectService = new ServiceKey("Test", "SvcCbMethodDetect"); + + @Before + public void before() throws IOException { + try { + namingServer = NamingServer.startNamingServer(-1); + System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); + } catch (IOException e) { + Assert.fail(e.getMessage()); + } + + CircuitBreakerProto.CircuitBreakerRule cbRule1 = CbTestUtils.loadCbRule("circuitBreakerMethodRuleNoDetect.json"); + CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() + .addRules(cbRule1).setRevision(StringValue.newBuilder().setValue("0000").build()).build(); + namingServer.getNamingService().setCircuitBreaker(matchMethodService, circuitBreaker); + + + CircuitBreakerProto.CircuitBreakerRule cbRule3 = CbTestUtils.loadCbRule("circuitBreakerMethodRule.json"); + CircuitBreakerProto.CircuitBreakerRule cbRule4 = CbTestUtils.loadCbRule("circuitBreakerRule.json"); + circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder() + .addRules(cbRule3).addRules(cbRule4).setRevision(StringValue.newBuilder().setValue("1111").build()).build(); + namingServer.getNamingService().setCircuitBreaker(matchMethodDetectService, circuitBreaker); + FaultDetectorProto.FaultDetectRule rule1 = CbTestUtils.loadFdRule("faultDetectRule.json"); + FaultDetectorProto.FaultDetectRule rule2 = CbTestUtils.loadFdRule("faultDetectMethodRule.json"); + FaultDetectorProto.FaultDetector faultDetector = FaultDetectorProto.FaultDetector.newBuilder() + .addRules(rule1).addRules(rule2).setRevision("2222").build(); + namingServer.getNamingService().setFaultDetector(matchMethodDetectService, faultDetector); + } + + @Test + public void testFaultDetectRuleChanged() throws IOException { + Configuration configuration = TestUtils.configWithEnvAddress(); + ConfigurationImpl configurationImpl = (ConfigurationImpl) configuration; + try (CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configurationImpl)) { + for (int i = 0; i < 10; i++) { + if (i == 1) { + Utils.sleepUninterrupted(5 * 1000); + } + String method = ""; + if (i < 9) { + method = "/test1/path/" + i; + } + FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest( + matchMethodDetectService, method); + FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest); + int finalI = i; + Consumer integerConsumer = decorator.decorateConsumer(num -> { + if (num % 2 == 0) { + throw new IllegalArgumentException("invoke failed" + finalI); + } else { + System.out.println("invoke success" + finalI); + } + }); + integerConsumer.accept(1); + } + BaseEngine baseEngine = (BaseEngine) circuitBreakAPI; + CircuitBreaker resourceBreaker = baseEngine.getSDKContext().getExtensions().getResourceBreaker(); + PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) resourceBreaker; + Map healthCheckCache = polarisCircuitBreaker.getHealthCheckCache(); + Assert.assertEquals(1, healthCheckCache.size()); + HealthCheckContainer healthCheckContainer = healthCheckCache.get(matchMethodDetectService); + Assert.assertNotNull(healthCheckContainer); + Collection healthCheckerValues = healthCheckContainer.getHealthCheckerValues(); + Assert.assertEquals(2, healthCheckerValues.size()); + + FaultDetectorProto.FaultDetectRule rule1 = CbTestUtils.loadFdRule("faultDetectMethodRuleChanged.json"); + FaultDetectorProto.FaultDetector faultDetector = FaultDetectorProto.FaultDetector.newBuilder() + .addRules(rule1).setRevision("33333").build(); + namingServer.getNamingService().setFaultDetector(matchMethodDetectService, faultDetector); + + Utils.sleepUninterrupted(20 * 1000); + healthCheckContainer = healthCheckCache.get(matchMethodDetectService); + Assert.assertNull(healthCheckContainer); + for (int i = 0; i < 3; i++) { + String method = ""; + if (i > 0) { + method = "/test1/path/" + i; + } + FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest( + matchMethodDetectService, method); + FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest); + int finalI = i; + Consumer integerConsumer = decorator.decorateConsumer(num -> { + if (num % 2 == 0) { + throw new IllegalArgumentException("invoke failed" + finalI); + } else { + System.out.println("invoke success" + finalI); + } + }); + integerConsumer.accept(1); + } + healthCheckContainer = healthCheckCache.get(matchMethodDetectService); + Assert.assertNotNull(healthCheckContainer); + healthCheckerValues = healthCheckContainer.getHealthCheckerValues(); + Assert.assertEquals(1, healthCheckerValues.size()); + } + } + + @After + public void after() { + if (null != namingServer) { + namingServer.terminate(); + } + } }