Skip to content

Commit 401b22f

Browse files
authored
fix: 优化熔断插件实现,解决用户通配API内存占用过高问题 (#542) (#543)
* 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统一计算
1 parent a2a45ed commit 401b22f

File tree

12 files changed

+400
-225
lines changed

12 files changed

+400
-225
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Tencent is pleased to support the open source community by making Polaris available.
3+
*
4+
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
5+
*
6+
* Licensed under the BSD 3-Clause License (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* https://opensource.org/licenses/BSD-3-Clause
11+
*
12+
* Unless required by applicable law or agreed to in writing, software distributed
13+
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
14+
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
15+
* specific language governing permissions and limitations under the License.
16+
*/
17+
18+
package com.tencent.polaris.circuitbreaker.factory.test;
19+
20+
import java.io.BufferedReader;
21+
import java.io.IOException;
22+
import java.io.InputStream;
23+
import java.io.InputStreamReader;
24+
import java.nio.charset.StandardCharsets;
25+
import java.util.stream.Collectors;
26+
27+
import com.google.protobuf.util.JsonFormat;
28+
import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto;
29+
import com.tencent.polaris.specification.api.v1.fault.tolerance.FaultDetectorProto;
30+
import org.junit.Assert;
31+
32+
public class CbTestUtils {
33+
34+
public static CircuitBreakerProto.CircuitBreakerRule loadCbRule(String fileName) throws IOException {
35+
CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule
36+
.newBuilder();
37+
InputStream inputStream = CbTestUtils.class.getClassLoader().getResourceAsStream(fileName);
38+
Assert.assertNotNull(inputStream);
39+
String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
40+
.collect(Collectors.joining(""));
41+
JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder);
42+
return circuitBreakerRuleBuilder.build();
43+
}
44+
45+
public static FaultDetectorProto.FaultDetectRule loadFdRule(String fileName) throws IOException {
46+
FaultDetectorProto.FaultDetectRule.Builder builder = FaultDetectorProto.FaultDetectRule.newBuilder();
47+
InputStream inputStream = CbTestUtils.class.getClassLoader().getResourceAsStream(fileName);
48+
Assert.assertNotNull(inputStream);
49+
String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
50+
.collect(Collectors.joining(""));
51+
JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
52+
return builder.build();
53+
}
54+
}

polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test/CircuitBreakerMultiTest.java

Lines changed: 36 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,18 @@
1717

1818
package com.tencent.polaris.circuitbreaker.factory.test;
1919

20-
import java.io.BufferedReader;
2120
import java.io.IOException;
22-
import java.io.InputStream;
23-
import java.io.InputStreamReader;
24-
import java.nio.charset.StandardCharsets;
2521
import java.util.Collection;
2622
import java.util.Map;
2723
import java.util.Optional;
2824
import java.util.function.Consumer;
29-
import java.util.stream.Collectors;
3025

3126
import com.google.common.cache.Cache;
3227
import com.google.protobuf.StringValue;
33-
import com.google.protobuf.util.JsonFormat;
3428
import com.tencent.polaris.api.config.Configuration;
3529
import com.tencent.polaris.api.plugin.circuitbreaker.CircuitBreaker;
3630
import com.tencent.polaris.api.plugin.circuitbreaker.entity.Resource;
3731
import com.tencent.polaris.api.pojo.ServiceKey;
38-
import com.tencent.polaris.api.utils.StringUtils;
3932
import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
4033
import com.tencent.polaris.circuitbreak.api.FunctionalDecorator;
4134
import com.tencent.polaris.circuitbreak.api.pojo.FunctionalDecoratorRequest;
@@ -83,45 +76,24 @@ public void before() throws IOException {
8376
Assert.fail(e.getMessage());
8477
}
8578

86-
CircuitBreakerProto.CircuitBreakerRule cbRule1 = loadCbRule("circuitBreakerMethodRuleNoDetect.json");
79+
CircuitBreakerProto.CircuitBreakerRule cbRule1 = CbTestUtils.loadCbRule("circuitBreakerMethodRuleNoDetect.json");
8780
CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder()
8881
.addRules(cbRule1).setRevision(StringValue.newBuilder().setValue("0000").build()).build();
8982
namingServer.getNamingService().setCircuitBreaker(matchMethodService, circuitBreaker);
9083

9184

92-
CircuitBreakerProto.CircuitBreakerRule cbRule3 = loadCbRule("circuitBreakerMethodRule.json");
93-
CircuitBreakerProto.CircuitBreakerRule cbRule4 = loadCbRule("circuitBreakerRule.json");
85+
CircuitBreakerProto.CircuitBreakerRule cbRule3 = CbTestUtils.loadCbRule("circuitBreakerMethodRule.json");
86+
CircuitBreakerProto.CircuitBreakerRule cbRule4 = CbTestUtils.loadCbRule("circuitBreakerRule.json");
9487
circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder()
9588
.addRules(cbRule3).addRules(cbRule4).setRevision(StringValue.newBuilder().setValue("1111").build()).build();
9689
namingServer.getNamingService().setCircuitBreaker(matchMethodDetectService, circuitBreaker);
97-
FaultDetectorProto.FaultDetectRule rule1 = loadFdRule("faultDetectRule.json");
98-
FaultDetectorProto.FaultDetectRule rule2 = loadFdRule("faultDetectMethodRule.json");
90+
FaultDetectorProto.FaultDetectRule rule1 = CbTestUtils.loadFdRule("faultDetectRule.json");
91+
FaultDetectorProto.FaultDetectRule rule2 = CbTestUtils.loadFdRule("faultDetectMethodRule.json");
9992
FaultDetectorProto.FaultDetector faultDetector = FaultDetectorProto.FaultDetector.newBuilder()
10093
.addRules(rule1).addRules(rule2).setRevision("2222").build();
10194
namingServer.getNamingService().setFaultDetector(matchMethodDetectService, faultDetector);
10295
}
10396

104-
private CircuitBreakerProto.CircuitBreakerRule loadCbRule(String fileName) throws IOException {
105-
CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule
106-
.newBuilder();
107-
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(fileName);
108-
Assert.assertNotNull(inputStream);
109-
String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
110-
.collect(Collectors.joining(""));
111-
JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder);
112-
return circuitBreakerRuleBuilder.build();
113-
}
114-
115-
private FaultDetectorProto.FaultDetectRule loadFdRule(String fileName) throws IOException {
116-
FaultDetectorProto.FaultDetectRule.Builder builder = FaultDetectorProto.FaultDetectRule.newBuilder();
117-
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(fileName);
118-
Assert.assertNotNull(inputStream);
119-
String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
120-
.collect(Collectors.joining(""));
121-
JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
122-
return builder.build();
123-
}
124-
12597
@Test
12698
public void testMultipleUrlsNoRule() {
12799
Configuration configuration = TestUtils.configWithEnvAddress();
@@ -143,18 +115,13 @@ public void testMultipleUrlsNoRule() {
143115
});
144116
integerConsumer.accept(1);
145117
}
146-
try {
147-
Thread.sleep(10 * 1000);
148-
}
149-
catch (InterruptedException e) {
150-
throw new RuntimeException(e);
151-
}
152-
118+
Utils.sleepUninterrupted(10 * 1000);
153119
BaseEngine baseEngine = (BaseEngine) circuitBreakAPI;
154120
CircuitBreaker resourceBreaker = baseEngine.getSDKContext().getExtensions().getResourceBreaker();
155121
PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) resourceBreaker;
156122
Cache<Resource, Optional<ResourceCounters>> methodCache = polarisCircuitBreaker.getCountersCache()
157123
.get(CircuitBreakerProto.Level.METHOD);
124+
polarisCircuitBreaker.cleanupExpiredResources();
158125
Assert.assertEquals(0, methodCache.size());
159126
}
160127
}
@@ -178,74 +145,26 @@ public void testMultipleUrlsMethodRule() {
178145
System.out.println("invoke success" + finalI);
179146
}
180147
});
181-
try {
148+
if (i == 0) {
182149
integerConsumer.accept(1);
183-
Utils.sleepUninterrupted(1000);
184-
integerConsumer.accept(2);
185-
Utils.sleepUninterrupted(1000);
186-
}
187-
catch (Exception e) {
188-
if (!(e instanceof IllegalArgumentException)) {
189-
throw e;
150+
try {
151+
integerConsumer.accept(2);
152+
} catch (Exception e) {
153+
if (!(e instanceof IllegalArgumentException)) {
154+
throw e;
155+
}
190156
}
157+
Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(3));
158+
} else {
159+
Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(1));
191160
}
192-
Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(3));
193-
}
194-
Utils.sleepUninterrupted(20 * 1000);
195-
196-
BaseEngine baseEngine = (BaseEngine) circuitBreakAPI;
197-
CircuitBreaker resourceBreaker = baseEngine.getSDKContext().getExtensions().getResourceBreaker();
198-
PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) resourceBreaker;
199-
Cache<Resource, Optional<ResourceCounters>> methodCache = polarisCircuitBreaker.getCountersCache()
200-
.get(CircuitBreakerProto.Level.METHOD);
201-
Assert.assertEquals(0, methodCache.size());
202-
}
203-
}
204-
205-
@Test
206-
public void testFaultDetector() {
207-
Configuration configuration = TestUtils.configWithEnvAddress();
208-
ConfigurationImpl configurationImpl = (ConfigurationImpl) configuration;
209-
configurationImpl.getConsumer().getCircuitBreaker().setCountersExpireInterval(5000);
210-
try (CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configurationImpl)) {
211-
for (int i = 0; i < 50; i++) {
212-
String method = "";
213-
if (i > 0) {
214-
method = "/test1/path/" + i;
215-
}
216-
FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest(
217-
matchMethodDetectService, method);
218-
FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest);
219-
int finalI = i;
220-
Consumer<Integer> integerConsumer = decorator.decorateConsumer(num -> {
221-
if (num % 2 == 0) {
222-
throw new IllegalArgumentException("invoke failed" + finalI);
223-
}
224-
else {
225-
System.out.println("invoke success" + finalI);
226-
}
227-
});
228-
integerConsumer.accept(1);
229161
}
230162
BaseEngine baseEngine = (BaseEngine) circuitBreakAPI;
231163
CircuitBreaker resourceBreaker = baseEngine.getSDKContext().getExtensions().getResourceBreaker();
232164
PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) resourceBreaker;
233-
Map<ServiceKey, HealthCheckContainer> healthCheckCache = polarisCircuitBreaker.getHealthCheckCache();
234-
Assert.assertEquals(1, healthCheckCache.size());
235-
HealthCheckContainer healthCheckContainer = healthCheckCache.get(matchMethodDetectService);
236-
Assert.assertNotNull(healthCheckContainer);
237-
Collection<ResourceHealthChecker> healthCheckerValues = healthCheckContainer.getHealthCheckerValues();
238-
Assert.assertEquals(2, healthCheckerValues.size());
239-
for (ResourceHealthChecker resourceHealthChecker : healthCheckerValues) {
240-
if (StringUtils.equals(resourceHealthChecker.getFaultDetectRule().getId(), "fd1")) {
241-
Assert.assertEquals(1, resourceHealthChecker.getResources().size());
242-
}
243-
}
244-
Utils.sleepUninterrupted(20 * 1000);
245-
246165
Cache<Resource, Optional<ResourceCounters>> methodCache = polarisCircuitBreaker.getCountersCache()
247166
.get(CircuitBreakerProto.Level.METHOD);
248-
Assert.assertEquals(0, methodCache.size());
167+
Assert.assertEquals(1, methodCache.size());
249168
}
250169
}
251170

@@ -273,7 +192,7 @@ public void testCircuitBreakerRuleChanged() throws IOException {
273192
});
274193
integerConsumer.accept(1);
275194
}
276-
CircuitBreakerProto.CircuitBreakerRule cbRule1 = loadCbRule("circuitBreakerMethodRuleChanged.json");
195+
CircuitBreakerProto.CircuitBreakerRule cbRule1 = CbTestUtils.loadCbRule("circuitBreakerMethodRuleChanged.json");
277196
CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder()
278197
.addRules(cbRule1).setRevision(StringValue.newBuilder().setValue("444441").build()).build();
279198
namingServer.getNamingService().setCircuitBreaker(matchMethodDetectService, circuitBreaker);
@@ -304,101 +223,29 @@ public void testCircuitBreakerRuleChanged() throws IOException {
304223
System.out.println("invoke success" + finalI);
305224
}
306225
});
307-
try {
308-
integerConsumer.accept(1);
309-
} catch (Exception e) {
310-
if (!(e instanceof IllegalArgumentException)) {
311-
throw e;
226+
if (i == 0) {
227+
try {
228+
integerConsumer.accept(1);
312229
}
313-
System.out.println("invoke 1 failed" + finalI);
314-
}
315-
Utils.sleepUninterrupted(1000);
316-
try {
317-
integerConsumer.accept(2);
318-
} catch (Exception e) {
319-
if (!(e instanceof IllegalArgumentException)) {
320-
throw e;
230+
catch (Exception e) {
231+
if (!(e instanceof IllegalArgumentException)) {
232+
throw e;
233+
}
321234
}
322-
System.out.println("invoke 2 failed" + finalI);
323-
}
324-
Utils.sleepUninterrupted(1000);
325-
Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(3));
326-
}
327-
}
328-
}
329-
330-
@Test
331-
public void testFaultDetectRuleChanged() throws IOException {
332-
Configuration configuration = TestUtils.configWithEnvAddress();
333-
ConfigurationImpl configurationImpl = (ConfigurationImpl) configuration;
334-
try (CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configurationImpl)) {
335-
for (int i = 0; i < 10; i++) {
336-
String method = "";
337-
if (i < 9) {
338-
method = "/test1/path/" + i;
339-
}
340-
FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest(
341-
matchMethodDetectService, method);
342-
FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest);
343-
int finalI = i;
344-
Consumer<Integer> integerConsumer = decorator.decorateConsumer(num -> {
345-
if (num % 2 == 0) {
346-
throw new IllegalArgumentException("invoke failed" + finalI);
235+
try {
236+
integerConsumer.accept(2);
347237
}
348-
else {
349-
System.out.println("invoke success" + finalI);
238+
catch (Exception e) {
239+
if (!(e instanceof IllegalArgumentException)) {
240+
throw e;
241+
}
350242
}
351-
});
352-
integerConsumer.accept(1);
353-
}
354-
BaseEngine baseEngine = (BaseEngine) circuitBreakAPI;
355-
CircuitBreaker resourceBreaker = baseEngine.getSDKContext().getExtensions().getResourceBreaker();
356-
PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) resourceBreaker;
357-
Map<ServiceKey, HealthCheckContainer> healthCheckCache = polarisCircuitBreaker.getHealthCheckCache();
358-
Assert.assertEquals(1, healthCheckCache.size());
359-
HealthCheckContainer healthCheckContainer = healthCheckCache.get(matchMethodDetectService);
360-
Assert.assertNotNull(healthCheckContainer);
361-
Collection<ResourceHealthChecker> healthCheckerValues = healthCheckContainer.getHealthCheckerValues();
362-
Assert.assertEquals(2, healthCheckerValues.size());
363-
// for (ResourceHealthChecker resourceHealthChecker : healthCheckerValues) {
364-
// if (StringUtils.equals(resourceHealthChecker.getFaultDetectRule().getId(), "fd1")) {
365-
// Assert.assertEquals(1, resourceHealthChecker.getResources().size());
366-
// }
367-
// }
368-
FaultDetectorProto.FaultDetectRule rule1 = loadFdRule("faultDetectMethodRuleChanged.json");
369-
FaultDetectorProto.FaultDetector faultDetector = FaultDetectorProto.FaultDetector.newBuilder()
370-
.addRules(rule1).setRevision("33333").build();
371-
namingServer.getNamingService().setFaultDetector(matchMethodDetectService, faultDetector);
372-
373-
Utils.sleepUninterrupted(20 * 1000);
374-
healthCheckContainer = healthCheckCache.get(matchMethodDetectService);
375-
Assert.assertNull(healthCheckContainer);
376-
for (int i = 0; i < 3; i++) {
377-
String method = "";
378-
if (i > 0) {
379-
method = "/test1/path/" + i;
243+
Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(3));
244+
}
245+
else {
246+
Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(1));
380247
}
381-
FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest(
382-
matchMethodDetectService, method);
383-
FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest);
384-
int finalI = i;
385-
Consumer<Integer> integerConsumer = decorator.decorateConsumer(num -> {
386-
if (num % 2 == 0) {
387-
throw new IllegalArgumentException("invoke failed" + finalI);
388-
}
389-
else {
390-
System.out.println("invoke success" + finalI);
391-
}
392-
});
393-
integerConsumer.accept(1);
394248
}
395-
healthCheckContainer = healthCheckCache.get(matchMethodDetectService);
396-
Assert.assertNotNull(healthCheckContainer);
397-
healthCheckerValues = healthCheckContainer.getHealthCheckerValues();
398-
Assert.assertEquals(1, healthCheckerValues.size());
399-
// for (ResourceHealthChecker resourceHealthChecker : healthCheckerValues) {
400-
// Assert.assertEquals(2, resourceHealthChecker.getResources().size());
401-
// }
402249
}
403250
}
404251

0 commit comments

Comments
 (0)