From 7b2f9483af792c24726446dc5538e8a031df07f0 Mon Sep 17 00:00:00 2001 From: Haotian Zhang <928016560@qq.com> Date: Tue, 21 Mar 2023 19:27:21 +0800 Subject: [PATCH 1/2] fix:optimize instance circuit beaker. (#908) --- CHANGELOG.md | 1 + .../pom.xml | 14 ++++++ .../pom.xml | 2 +- spring-cloud-tencent-dependencies/pom.xml | 2 +- .../example/ServiceBController.java | 45 +++++++++++++++++-- .../feign/EnhancedFeignClient.java | 4 +- .../feign/plugin/EnhancedFeignContext.java | 10 +++++ .../reporter/ExceptionPolarisReporter.java | 7 +-- .../feign/plugin/reporter/ReporterUtils.java | 5 ++- .../reporter/SuccessPolarisReporter.java | 7 +-- .../EnhancedRestTemplateReporter.java | 12 +++-- .../LoadBalancerClientAspectUtils.java | 1 + .../ExceptionPolarisReporterTest.java | 3 +- .../plugin/reporter/ReporterUtilsTest.java | 9 +++- .../reporter/SuccessPolarisReporterTest.java | 3 +- .../EnhancedRestTemplateReporterTest.java | 1 + 16 files changed, 105 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfcd6c00b..e5dc6f465 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,3 +3,4 @@ - [fix: fix log feign response stream close bug.](https://github.com/Tencent/spring-cloud-tencent/pull/896) - [fix:remove the secondary report.](https://github.com/Tencent/spring-cloud-tencent/pull/900) +- [fix:optimize instance circuit beaker.](https://github.com/Tencent/spring-cloud-tencent/pull/908) diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml index 6ce29236c..58a68a422 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml @@ -80,6 +80,20 @@ + + com.tencent.polaris + healthchecker-http + + + + com.tencent.polaris + healthchecker-udp + + + + com.tencent.polaris + healthchecker-tcp + diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml b/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml index 0dd4540fb..5df5c0183 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml +++ b/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml @@ -17,7 +17,7 @@ com.tencent.cloud - spring-cloud-tencent-polaris-context + spring-cloud-tencent-rpc-enhancement diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index 3e5d15f46..4c44d7418 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -73,7 +73,7 @@ 1.11.0-2020.0.5-SNAPSHOT - 1.11.1 + 1.11.2 31.0.1-jre 1.2.11 4.5.1 diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java index 384167816..21325f7e7 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java @@ -18,10 +18,14 @@ package com.tencent.cloud.polaris.ciruitbreaker.example; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** @@ -33,14 +37,47 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping("/example/service/b") public class ServiceBController { + private static final Logger LOG = LoggerFactory.getLogger(ServiceBController.class); + + private boolean ifBadGateway = true; + + private boolean ifDelay = true; + + @GetMapping("/setBadGateway") + public void setBadGateway(@RequestParam boolean param) { + if (param) { + LOG.info("info is set to return HttpStatus.BAD_GATEWAY."); + } + else { + LOG.info("info is set to return HttpStatus.OK."); + } + this.ifBadGateway = param; + } + + @GetMapping("/setDelay") + public void setDelay(@RequestParam boolean param) { + if (param) { + LOG.info("info is set to delay 100ms."); + } + else { + LOG.info("info is set to no delay."); + } + this.ifDelay = param; + } + /** * Get service information. * * @return service information */ @GetMapping("/info") - @ResponseStatus(value = HttpStatus.BAD_GATEWAY, reason = "failed for call my service") - public String info() { - return "failed for call service B2"; + public ResponseEntity info() throws InterruptedException { + if (ifBadGateway) { + return new ResponseEntity<>("failed for call my service", HttpStatus.BAD_GATEWAY); + } + if (ifDelay) { + Thread.sleep(100); + } + return new ResponseEntity<>("hello world ! I'm a service B2", HttpStatus.OK); } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java index 4bdf14eff..b01850d4d 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java @@ -40,7 +40,7 @@ public class EnhancedFeignClient implements Client { private final Client delegate; - private EnhancedFeignPluginRunner pluginRunner; + private final EnhancedFeignPluginRunner pluginRunner; public EnhancedFeignClient(Client target, EnhancedFeignPluginRunner pluginRunner) { this.delegate = checkNotNull(target, "target"); @@ -56,7 +56,9 @@ public class EnhancedFeignClient implements Client { // Run pre enhanced feign plugins. pluginRunner.run(PRE, enhancedFeignContext); try { + long startMillis = System.currentTimeMillis(); Response response = delegate.execute(request, options); + enhancedFeignContext.setDelay(System.currentTimeMillis() - startMillis); enhancedFeignContext.setResponse(response); // Run post enhanced feign plugins. diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java index e6f3be612..d1d9aded3 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java @@ -35,6 +35,8 @@ public class EnhancedFeignContext { private Exception exception; + private long delay; + public Request getRequest() { return request; } @@ -66,4 +68,12 @@ public class EnhancedFeignContext { public void setException(Exception exception) { this.exception = exception; } + + public long getDelay() { + return delay; + } + + public void setDelay(long delay) { + this.delay = delay; + } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java index a1496fa11..b46f1435c 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java @@ -72,12 +72,13 @@ public class ExceptionPolarisReporter implements EnhancedFeignPlugin { Response response = context.getResponse(); Exception exception = context.getException(); RetStatus retStatus = RetStatus.RetFail; + long delay = context.getDelay(); if (exception instanceof SocketTimeoutException) { retStatus = RetStatus.RetTimeout; } - LOG.debug("Will report result of {}. Request=[{} {}]. Response=[{}].", retStatus.name(), request.httpMethod() - .name(), request.url(), response.status()); - ServiceCallResult resultRequest = ReporterUtils.createServiceCallResult(request, retStatus); + LOG.debug("Will report result of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", retStatus.name(), request.httpMethod() + .name(), request.url(), response.status(), delay); + ServiceCallResult resultRequest = ReporterUtils.createServiceCallResult(request, response, delay, retStatus); consumerAPI.updateServiceCallResult(resultRequest); } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtils.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtils.java index 289a3d5e9..d56ecf328 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtils.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtils.java @@ -30,6 +30,7 @@ import com.tencent.polaris.api.rpc.ServiceCallResult; import com.tencent.polaris.api.utils.CollectionUtils; import feign.Request; import feign.RequestTemplate; +import feign.Response; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,7 +49,7 @@ public final class ReporterUtils { private ReporterUtils() { } - public static ServiceCallResult createServiceCallResult(final Request request, RetStatus retStatus) { + public static ServiceCallResult createServiceCallResult(final Request request, final Response response, long delay, RetStatus retStatus) { ServiceCallResult resultRequest = new ServiceCallResult(); resultRequest.setNamespace(MetadataContext.LOCAL_NAMESPACE); @@ -68,7 +69,9 @@ public final class ReporterUtils { } URI uri = URI.create(request.url()); resultRequest.setMethod(uri.getPath()); + resultRequest.setRetCode(response.status()); resultRequest.setRetStatus(retStatus); + resultRequest.setDelay(delay); String sourceNamespace = MetadataContext.LOCAL_NAMESPACE; String sourceService = MetadataContext.LOCAL_SERVICE; if (StringUtils.isNotBlank(sourceNamespace) && StringUtils.isNotBlank(sourceService)) { diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java index cc009d1b8..54a389c8c 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java @@ -69,12 +69,13 @@ public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter imple Request request = context.getRequest(); Response response = context.getResponse(); RetStatus retStatus = RetStatus.RetSuccess; + long delay = context.getDelay(); if (apply(HttpStatus.resolve(response.status()))) { retStatus = RetStatus.RetFail; } - LOG.debug("Will report result of {}. Request=[{} {}]. Response=[{}].", retStatus.name(), request.httpMethod() - .name(), request.url(), response.status()); - ServiceCallResult resultRequest = ReporterUtils.createServiceCallResult(request, retStatus); + LOG.debug("Will report result of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", retStatus.name(), request.httpMethod() + .name(), request.url(), response.status(), delay); + ServiceCallResult resultRequest = ReporterUtils.createServiceCallResult(request, response, delay, retStatus); consumerAPI.updateServiceCallResult(resultRequest); } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java index b8f842e77..4a2f9c3e5 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java @@ -117,12 +117,14 @@ public class EnhancedRestTemplateReporter extends AbstractPolarisReporterAdapter } private void reportResult(URI url, ClientHttpResponse response) { - ServiceCallResult resultRequest = createServiceCallResult(url); try { + ServiceCallResult resultRequest = createServiceCallResult(url, response); Map loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata(); String targetHost = loadBalancerContext.get("host"); String targetPort = loadBalancerContext.get("port"); + String startMillis = loadBalancerContext.get("startMillis"); + long delay = System.currentTimeMillis() - Long.parseLong(startMillis); if (StringUtils.isBlank(targetHost) || StringUtils.isBlank(targetPort)) { LOGGER.warn("Can not get target host or port from metadata context. host = {}, port = {}", targetHost, targetPort); @@ -131,6 +133,7 @@ public class EnhancedRestTemplateReporter extends AbstractPolarisReporterAdapter resultRequest.setHost(targetHost); resultRequest.setPort(Integer.parseInt(targetPort)); + resultRequest.setDelay(delay); // checking response http status code if (apply(response.getStatusCode())) { @@ -150,8 +153,8 @@ public class EnhancedRestTemplateReporter extends AbstractPolarisReporterAdapter } // processing report with consumerAPI . - LOGGER.debug("Will report result of {}. URL=[{}]. Response=[{}].", resultRequest.getRetStatus().name(), - url, response); + LOGGER.debug("Will report result of {}. Request=[{}]. Response=[{}]. Delay=[{}]ms.", resultRequest.getRetStatus() + .name(), url, response.getStatusCode().value(), delay); consumerAPI.updateServiceCallResult(resultRequest); } catch (Exception e) { @@ -193,12 +196,13 @@ public class EnhancedRestTemplateReporter extends AbstractPolarisReporterAdapter response.getHeaders().remove(HEADER_HAS_ERROR); } - private ServiceCallResult createServiceCallResult(URI uri) { + private ServiceCallResult createServiceCallResult(URI uri, ClientHttpResponse response) throws IOException { ServiceCallResult resultRequest = new ServiceCallResult(); String serviceName = uri.getHost(); resultRequest.setService(serviceName); resultRequest.setNamespace(MetadataContext.LOCAL_NAMESPACE); resultRequest.setMethod(uri.getPath()); + resultRequest.setRetCode(response.getStatusCode().value()); resultRequest.setRetStatus(RetStatus.RetSuccess); String sourceNamespace = MetadataContext.LOCAL_NAMESPACE; String sourceService = MetadataContext.LOCAL_SERVICE; diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/LoadBalancerClientAspectUtils.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/LoadBalancerClientAspectUtils.java index 1b9f11632..ff44d659c 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/LoadBalancerClientAspectUtils.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/LoadBalancerClientAspectUtils.java @@ -38,6 +38,7 @@ public final class LoadBalancerClientAspectUtils { ServiceInstance instance = (ServiceInstance) server; MetadataContextHolder.get().setLoadbalancer("host", instance.getHost()); MetadataContextHolder.get().setLoadbalancer("port", String.valueOf(instance.getPort())); + MetadataContextHolder.get().setLoadbalancer("startMillis", String.valueOf(System.currentTimeMillis())); } } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporterTest.java index 997f9b37f..9e926703a 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporterTest.java @@ -39,6 +39,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -63,7 +64,7 @@ public class ExceptionPolarisReporterTest { @BeforeAll static void beforeAll() { mockedReporterUtils = Mockito.mockStatic(ReporterUtils.class); - mockedReporterUtils.when(() -> ReporterUtils.createServiceCallResult(any(Request.class), any(RetStatus.class))) + mockedReporterUtils.when(() -> ReporterUtils.createServiceCallResult(any(Request.class), any(Response.class), anyLong(), any(RetStatus.class))) .thenReturn(mock(ServiceCallResult.class)); } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtilsTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtilsTest.java index c39dd1633..409ac5f89 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtilsTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtilsTest.java @@ -27,6 +27,7 @@ import com.tencent.polaris.api.pojo.RetStatus; import com.tencent.polaris.api.rpc.ServiceCallResult; import feign.Request; import feign.RequestTemplate; +import feign.Response; import feign.Target; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -94,7 +95,11 @@ public class ReporterUtilsTest { doReturn(requestTemplate).when(request).requestTemplate(); doReturn("http://1.1.1.1:2345/path").when(request).url(); - ServiceCallResult serviceCallResult = ReporterUtils.createServiceCallResult(request, RetStatus.RetSuccess); + // mock request + Response response = mock(Response.class); + doReturn(502).when(response).status(); + + ServiceCallResult serviceCallResult = ReporterUtils.createServiceCallResult(request, response, 10L, RetStatus.RetSuccess); assertThat(serviceCallResult.getNamespace()).isEqualTo(NAMESPACE_TEST); assertThat(serviceCallResult.getService()).isEqualTo(SERVICE_PROVIDER); assertThat(serviceCallResult.getHost()).isEqualTo("1.1.1.1"); @@ -104,5 +109,7 @@ public class ReporterUtilsTest { assertThat(serviceCallResult.getCallerService().getNamespace()).isEqualTo(NAMESPACE_TEST); assertThat(serviceCallResult.getCallerService().getService()).isEqualTo(SERVICE_PROVIDER); assertThat(serviceCallResult.getLabels()).isEqualTo("k1:v1|k2:v2"); + assertThat(serviceCallResult.getRetCode()).isEqualTo(502); + assertThat(serviceCallResult.getDelay()).isEqualTo(10L); } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporterTest.java index 2970baa8c..b82eac465 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporterTest.java @@ -39,6 +39,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -63,7 +64,7 @@ public class SuccessPolarisReporterTest { @BeforeAll static void beforeAll() { mockedReporterUtils = Mockito.mockStatic(ReporterUtils.class); - mockedReporterUtils.when(() -> ReporterUtils.createServiceCallResult(any(Request.class), any(RetStatus.class))) + mockedReporterUtils.when(() -> ReporterUtils.createServiceCallResult(any(Request.class), any(Response.class), anyLong(), any(RetStatus.class))) .thenReturn(mock(ServiceCallResult.class)); } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java index a4395b8b6..86dd010b0 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java @@ -90,6 +90,7 @@ public class EnhancedRestTemplateReporterTest { Map loadBalancerContext = new HashMap<>(); loadBalancerContext.put("host", "1.1.1.1"); loadBalancerContext.put("port", "8080"); + loadBalancerContext.put("startMillis", String.valueOf(System.currentTimeMillis())); when(metadataContext.getLoadbalancerMetadata()).thenReturn(loadBalancerContext); mockedMetadataContextHolder = Mockito.mockStatic(MetadataContextHolder.class); From 74f89552903010a3087cd1611e44b05f489e48d9 Mon Sep 17 00:00:00 2001 From: Haotian Zhang <928016560@qq.com> Date: Wed, 22 Mar 2023 19:12:52 +0800 Subject: [PATCH 2/2] fix:optimize multi service registration and discovery. (#914) --- CHANGELOG.md | 1 + pom.xml | 6 +- .../pom.xml | 12 +++ .../extend/consul/ConsulConfigModifier.java | 22 +++++ .../extend/nacos/NacosConfigModifier.java | 23 ++++- .../cloud/common/util/JacksonUtils.java | 10 --- .../pojo/PolarisServiceInstanceTest.java | 37 +++++++- .../common/util/BeanFactoryUtilsTest.java | 89 +++++++++++++++++++ .../cloud/common/util/JacksonUtilsTest.java | 3 + spring-cloud-tencent-dependencies/pom.xml | 2 +- .../discovery-callee-service/pom.xml | 12 +-- .../discovery-caller-service/pom.xml | 16 ++-- spring-cloud-tencent-polaris-context/pom.xml | 10 --- 13 files changed, 202 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5dc6f465..c26fdf2bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,3 +4,4 @@ - [fix: fix log feign response stream close bug.](https://github.com/Tencent/spring-cloud-tencent/pull/896) - [fix:remove the secondary report.](https://github.com/Tencent/spring-cloud-tencent/pull/900) - [fix:optimize instance circuit beaker.](https://github.com/Tencent/spring-cloud-tencent/pull/908) +- [fix:optimize multi service registration and discovery.](https://github.com/Tencent/spring-cloud-tencent/pull/914) diff --git a/pom.xml b/pom.xml index 7151ef15f..2a66edb35 100644 --- a/pom.xml +++ b/pom.xml @@ -88,16 +88,16 @@ - 1.11.0-2020.0.5-SNAPSHOT + 1.11.0-2020.0.6-SNAPSHOT - 5.3.21 + 5.3.26 2.4.13 - 2020.0.5 + 2020.0.6 0.8.8 diff --git a/spring-cloud-starter-tencent-polaris-discovery/pom.xml b/spring-cloud-starter-tencent-polaris-discovery/pom.xml index 417659911..62ff58198 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/pom.xml +++ b/spring-cloud-starter-tencent-polaris-discovery/pom.xml @@ -28,6 +28,18 @@ test + + com.tencent.polaris + connector-consul + test + + + + com.tencent.polaris + connector-nacos + test + + com.tencent.polaris polaris-test-mock-discovery diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulConfigModifier.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulConfigModifier.java index 70a4f703f..e9bed3e61 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulConfigModifier.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulConfigModifier.java @@ -31,6 +31,8 @@ import com.tencent.polaris.factory.config.global.ServerConnectorConfigImpl; import com.tencent.polaris.factory.config.provider.RegisterConfigImpl; import com.tencent.polaris.plugins.connector.common.constant.ConsulConstant; import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.util.CollectionUtils; @@ -38,6 +40,9 @@ import org.springframework.util.CollectionUtils; * @author lingxiao.wlx */ public class ConsulConfigModifier implements PolarisConfigModifier { + + private static final Logger LOGGER = LoggerFactory.getLogger(ConsulConfigModifier.class); + private static final String ID = "consul"; private final ConsulContextProperties consulContextProperties; @@ -49,6 +54,23 @@ public class ConsulConfigModifier implements PolarisConfigModifier { @Override public void modify(ConfigurationImpl configuration) { if (consulContextProperties != null && consulContextProperties.isEnabled()) { + // Check if Consul client Available + boolean consulAvailable = false; + try { + consulAvailable = null != Class.forName("com.ecwid.consul.v1.ConsulClient"); + } + catch (Throwable ignored) { + + } + if (!consulAvailable) { + LOGGER.error("Please import \"connector-consul\" dependency when enabling consul service registration and discovery.\n" + + "Add dependency configuration below to pom.xml:\n" + + "\n" + + "\tcom.tencent.polaris\n" + + "\tconnector-consul\n" + + ""); + throw new RuntimeException("Dependency \"connector-consul\" not found."); + } if (CollectionUtils.isEmpty(configuration.getGlobal().getServerConnectors())) { configuration.getGlobal().setServerConnectors(new ArrayList<>()); } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/nacos/NacosConfigModifier.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/nacos/NacosConfigModifier.java index ca80e5038..4f6838177 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/nacos/NacosConfigModifier.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/nacos/NacosConfigModifier.java @@ -30,6 +30,8 @@ import com.tencent.polaris.factory.config.consumer.DiscoveryConfigImpl; import com.tencent.polaris.factory.config.global.ServerConnectorConfigImpl; import com.tencent.polaris.factory.config.provider.RegisterConfigImpl; import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.util.CollectionUtils; @@ -40,7 +42,6 @@ import org.springframework.util.CollectionUtils; */ public class NacosConfigModifier implements PolarisConfigModifier { - private static final String ID = "nacos"; /** * nacos username. */ @@ -53,7 +54,8 @@ public class NacosConfigModifier implements PolarisConfigModifier { * nacos contextPath. */ public static final String CONTEXT_PATH = "contextPath"; - + private static final Logger LOGGER = LoggerFactory.getLogger(NacosConfigModifier.class); + private static final String ID = "nacos"; private final NacosContextProperties nacosContextProperties; public NacosConfigModifier(NacosContextProperties nacosContextProperties) { @@ -65,6 +67,23 @@ public class NacosConfigModifier implements PolarisConfigModifier { if (Objects.isNull(nacosContextProperties) || !nacosContextProperties.isEnabled()) { return; } + // Check if Nacos Available + boolean nacosAvailable = false; + try { + nacosAvailable = null != Class.forName("com.alibaba.nacos.api.naming.NamingService"); + } + catch (Throwable ignored) { + + } + if (!nacosAvailable) { + LOGGER.error("Please import \"connector-nacos\" dependency when enabling nacos service registration and discovery.\n" + + "Add dependency configuration below to pom.xml:\n" + + "\n" + + "\tcom.tencent.polaris\n" + + "\tconnector-nacos\n" + + ""); + throw new RuntimeException("Dependency \"connector-nacos\" not found."); + } if (CollectionUtils.isEmpty(configuration.getGlobal().getServerConnectors())) { configuration.getGlobal().setServerConnectors(new ArrayList<>()); } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java index 234807853..b4862ce05 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java @@ -111,14 +111,4 @@ public final class JacksonUtils { throw new RuntimeException("Json to map failed.", e); } } - - public static T json2JavaBean(String content, Class valueType) { - try { - return OM.readValue(content, valueType); - } - catch (Exception e) { - LOG.error("json {} to class {} failed. ", content, valueType, e); - throw new RuntimeException("json to class failed.", e); - } - } } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/pojo/PolarisServiceInstanceTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/pojo/PolarisServiceInstanceTest.java index afa2eec25..107310331 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/pojo/PolarisServiceInstanceTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/pojo/PolarisServiceInstanceTest.java @@ -17,6 +17,7 @@ package com.tencent.cloud.common.pojo; +import com.tencent.polaris.api.pojo.DefaultInstance; import com.tencent.polaris.api.pojo.Instance; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -38,7 +39,7 @@ public class PolarisServiceInstanceTest { @Test @DisplayName("test getters and setters.") - void test() { + public void test1() { Instance secureInstance = mock(Instance.class); doReturn("test-ID").when(secureInstance).getId(); doReturn(SERVICE_PROVIDER).when(secureInstance).getService(); @@ -53,6 +54,7 @@ public class PolarisServiceInstanceTest { assertThat(securePolarisServiceInstance.getPort()).isEqualTo(8080); assertThat(securePolarisServiceInstance.isSecure()).isTrue(); assertThat(securePolarisServiceInstance.getScheme()).isEqualTo("https"); + assertThat(securePolarisServiceInstance.getUri().toString()).isEqualTo("https://1.1.1.1:8080"); Instance insecureInstance = mock(Instance.class); doReturn("http").when(insecureInstance).getProtocol(); @@ -60,4 +62,37 @@ public class PolarisServiceInstanceTest { assertThat(insecurePolarisServiceInstance.isSecure()).isFalse(); assertThat(insecurePolarisServiceInstance.getScheme()).isEqualTo("http"); } + + + @Test + @DisplayName("test equals().") + public void test2() { + DefaultInstance instance1 = new DefaultInstance(); + instance1.setId("test-1"); + instance1.setProtocol("http"); + PolarisServiceInstance polarisServiceInstance1 = new PolarisServiceInstance(instance1); + + DefaultInstance instance2 = new DefaultInstance(); + instance2.setId("test-1"); + instance2.setProtocol("http"); + PolarisServiceInstance polarisServiceInstance2 = new PolarisServiceInstance(instance2); + + assertThat(polarisServiceInstance1.equals(polarisServiceInstance2)).isTrue(); + } + + @Test + @DisplayName("test hashCode().") + public void test3() { + DefaultInstance instance1 = new DefaultInstance(); + instance1.setId("test-1"); + instance1.setProtocol("http"); + PolarisServiceInstance polarisServiceInstance1 = new PolarisServiceInstance(instance1); + + DefaultInstance instance2 = new DefaultInstance(); + instance2.setId("test-1"); + instance2.setProtocol("http"); + PolarisServiceInstance polarisServiceInstance2 = new PolarisServiceInstance(instance2); + + assertThat(polarisServiceInstance1.hashCode()).isEqualTo(polarisServiceInstance2.hashCode()); + } } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/BeanFactoryUtilsTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/BeanFactoryUtilsTest.java index 9a94a32e4..e4e6001f9 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/BeanFactoryUtilsTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/BeanFactoryUtilsTest.java @@ -19,10 +19,16 @@ package com.tencent.cloud.common.util; import org.junit.jupiter.api.Test; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.core.ResolvableType; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Test for {@link BeanFactoryUtils}. @@ -41,6 +47,11 @@ public class BeanFactoryUtilsTest { assertThat(childBeanFactory.getBeansOfType(Foo.class)).isEmpty(); assertThat(BeanFactoryUtils.getBeans(childBeanFactory, Foo.class).size()).isEqualTo(1); assertThat(BeanFactoryUtils.getBeans(childBeanFactory, Bar.class)).isEmpty(); + + MockBeanFactory mockBeanFactory = new MockBeanFactory(); + assertThatThrownBy(() -> BeanFactoryUtils.getBeans(mockBeanFactory, Bar.class)) + .isExactlyInstanceOf(RuntimeException.class) + .hasMessageContaining("bean factory not support get list bean."); } static class Foo { @@ -50,4 +61,82 @@ public class BeanFactoryUtilsTest { static class Bar { } + + static class MockBeanFactory implements BeanFactory { + + @Override + public Object getBean(String s) throws BeansException { + return null; + } + + @Override + public T getBean(String s, Class aClass) throws BeansException { + return null; + } + + @Override + public Object getBean(String s, Object... objects) throws BeansException { + return null; + } + + @Override + public T getBean(Class aClass) throws BeansException { + return null; + } + + @Override + public T getBean(Class aClass, Object... objects) throws BeansException { + return null; + } + + @Override + public ObjectProvider getBeanProvider(Class aClass) { + return null; + } + + @Override + public ObjectProvider getBeanProvider(ResolvableType resolvableType) { + return null; + } + + @Override + public boolean containsBean(String s) { + return false; + } + + @Override + public boolean isSingleton(String s) throws NoSuchBeanDefinitionException { + return false; + } + + @Override + public boolean isPrototype(String s) throws NoSuchBeanDefinitionException { + return false; + } + + @Override + public boolean isTypeMatch(String s, ResolvableType resolvableType) throws NoSuchBeanDefinitionException { + return false; + } + + @Override + public boolean isTypeMatch(String s, Class aClass) throws NoSuchBeanDefinitionException { + return false; + } + + @Override + public Class getType(String s) throws NoSuchBeanDefinitionException { + return null; + } + + @Override + public Class getType(String s, boolean b) throws NoSuchBeanDefinitionException { + return null; + } + + @Override + public String[] getAliases(String s) { + return new String[0]; + } + } } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java index 962f014a3..df2b3aa7b 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java @@ -25,6 +25,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.util.StringUtils; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -43,6 +45,7 @@ public class JacksonUtilsTest { sourceMap.put("k2", "v2"); sourceMap.put("k3", "v3"); assertThat(JacksonUtils.serialize2Json(sourceMap)).isEqualTo("{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\"}"); + assertThat(StringUtils.trimAllWhitespace(JacksonUtils.serialize2Json(sourceMap, true))).isEqualTo("{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\"}"); } @Test diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index 4c44d7418..111ef0ad7 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -70,7 +70,7 @@ - 1.11.0-2020.0.5-SNAPSHOT + 1.11.0-2020.0.6-SNAPSHOT 1.11.2 diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml index f57ab7ac0..9b974df4c 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml @@ -30,14 +30,14 @@ - - + + - - - - + + + + org.springframework.cloud diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml index 1d370e7f5..aadcea9ee 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml @@ -28,15 +28,15 @@ spring-cloud-starter-tencent-polaris-discovery - - - - + + + + - - - - + + + + diff --git a/spring-cloud-tencent-polaris-context/pom.xml b/spring-cloud-tencent-polaris-context/pom.xml index 0b5ca61ea..2507beddd 100644 --- a/spring-cloud-tencent-polaris-context/pom.xml +++ b/spring-cloud-tencent-polaris-context/pom.xml @@ -75,16 +75,6 @@ - - com.tencent.polaris - connector-consul - - - - com.tencent.polaris - connector-nacos - - com.tencent.polaris connector-composite