From fa5d0eefb8223b027dec6ba1339f0e7a4546154a Mon Sep 17 00:00:00 2001 From: chuntaojun Date: Wed, 17 Nov 2021 03:15:17 +0800 Subject: [PATCH] feat: finish discovery ability in 2020.x --- .../discovery-callee-service/pom.xml | 5 + .../{bootstrap.yml => application.yml} | 1 - .../discovery-caller-service/pom.xml | 5 + .../caller/DiscoveryCallerController.java | 8 ++ .../{bootstrap.yml => application.yml} | 3 +- .../polaris-discovery-example/pom.xml | 1 + .../feign/PolarisFeignBeanPostProcessor.java | 26 ++-- ...olarisFeignBlockingLoadBalancerClient.java | 11 +- .../feign/PolarisLoadBalancerFeignClient.java | 37 ------ .../feign/PolarisFeignClientTest.java | 3 - .../pom.xml | 12 +- .../cloud/polaris/PolarisProperties.java | 6 +- ...olarisLoadBalancerClientConfiguration.java | 63 ++++++++++ .../loadbalancer/PolarisLoadbalancer.java | 46 ++++++- .../PolarisAutoServiceRegistration.java | 4 +- .../registry/PolarisServiceRegistry.java | 17 ++- .../main/resources/META-INF/spring.factories | 1 - ...RibbonServerListAutoConfigurationTest.java | 35 ------ .../polaris/ribbon/PolarisServerListTest.java | 53 --------- .../pom.xml | 1 - .../PolarisRouterAutoConfiguration.java | 112 ++++++++++++++++++ ...risRouterServiceInstanceListSupplier.java} | 20 +++- .../PolarisRouterAutoConfiguration.java | 51 -------- .../config/PolarisRouterProperties.java | 64 ---------- .../router/rule/PolarisLoadBalanceRule.java | 53 --------- .../main/resources/META-INF/spring.factories | 2 +- .../PolarisRibbonAutoConfigurationTest.java | 9 +- .../cloud/constant/LoadbalancerConstant.java} | 23 ++-- .../polaris/pojo/PolarisServiceInstance.java | 4 + .../tencent/cloud/feign/PluggableFeign.java | 13 +- .../cloud/feign/PluggableFeignContext.java | 8 +- .../PluggableFeignInvocationHandler.java | 10 +- .../scg/filter/Metadata2HeaderScgFilter.java | 2 +- 33 files changed, 324 insertions(+), 385 deletions(-) rename spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/{bootstrap.yml => application.yml} (88%) rename spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/{bootstrap.yml => application.yml} (92%) delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java create mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterAutoConfiguration.java rename spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/{PolarisRoutingLoadBalancer.java => PolarisRouterServiceInstanceListSupplier.java} (85%) delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRouterAutoConfiguration.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRouterProperties.java delete mode 100644 spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisLoadBalanceRule.java rename spring-cloud-tencent-starters/{spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRouterClientConfiguration.java => spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/constant/LoadbalancerConstant.java} (58%) 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 afdba7052..c225faf4a 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 @@ -14,6 +14,11 @@ Polaris Discovery Callee Service + + org.springframework.boot + spring-boot-starter-web + + spring-cloud-starter-tencent-polaris-discovery com.tencent.cloud diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/application.yml similarity index 88% rename from spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml rename to spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/application.yml index ea3cd0aa8..cd2e70c62 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/src/main/resources/application.yml @@ -1,5 +1,4 @@ server: - session-timeout: 1800 port: 48081 spring: application: 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 e3372c51a..5b7aac6c9 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 @@ -18,6 +18,11 @@ + + org.springframework.boot + spring-boot-starter-web + + spring-cloud-starter-tencent-polaris-discovery com.tencent.cloud diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerController.java b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerController.java index af338861f..e73565acd 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerController.java +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/java/com/tencent/cloud/polaris/discovery/service/caller/DiscoveryCallerController.java @@ -18,6 +18,8 @@ package com.tencent.cloud.polaris.discovery.service.caller; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; +import org.springframework.context.annotation.Configuration; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -37,6 +39,12 @@ public class DiscoveryCallerController { @Autowired private DiscoveryCalleeService discoveryCalleeService; + @Configuration + @LoadBalancerClient(value = "service-provider") + class DiscoveryCallerConfiguration { + + } + /** * 获取相加完的结果 * diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/application.yml similarity index 92% rename from spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml rename to spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/application.yml index 43930793e..106b5ee89 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/application.yml @@ -1,10 +1,11 @@ server: - session-timeout: 1800 port: 48080 spring: application: name: DiscoveryCallerService cloud: + loadbalancer: + configurations: default polaris: address: grpc://127.0.0.1:8091 consul: diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/pom.xml b/spring-cloud-tencent-examples/polaris-discovery-example/pom.xml index ac9e8971f..866fcd456 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/pom.xml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/pom.xml @@ -20,6 +20,7 @@ + org.springframework.boot spring-boot-starter-web diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java index 339f3a589..73052df87 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java @@ -23,11 +23,10 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; +import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; -import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory; -import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient; /** * Wrap Spring Bean and decorating proxy for Feign Client. @@ -50,16 +49,14 @@ public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFac } private Object wrapper(Object bean) { + if (isNeedWrap(bean)) { - if (bean instanceof LoadBalancerFeignClient) { - LoadBalancerFeignClient client = ((LoadBalancerFeignClient) bean); - return new PolarisLoadBalancerFeignClient(createPolarisFeignClient(client.getDelegate()), factory(), - clientFactory()); - } if (bean instanceof FeignBlockingLoadBalancerClient) { FeignBlockingLoadBalancerClient client = (FeignBlockingLoadBalancerClient) bean; return new PolarisFeignBlockingLoadBalancerClient(createPolarisFeignClient(client.getDelegate()), - factory.getBean(BlockingLoadBalancerClient.class)); + factory.getBean(BlockingLoadBalancerClient.class), + factory.getBean(LoadBalancerProperties.class), + factory.getBean(LoadBalancerClientFactory.class)); } return createPolarisFeignClient((Client) bean); } @@ -68,8 +65,7 @@ public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFac private boolean isNeedWrap(Object bean) { return bean instanceof Client && !(bean instanceof PolarisFeignClient) - && !(bean instanceof PolarisFeignBlockingLoadBalancerClient) - && !(bean instanceof PolarisLoadBalancerFeignClient); + && !(bean instanceof PolarisFeignBlockingLoadBalancerClient); } private PolarisFeignClient createPolarisFeignClient(Client delegate) { @@ -80,12 +76,4 @@ public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFac public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.factory = beanFactory; } - - CachingSpringLoadBalancerFactory factory() { - return this.factory.getBean(CachingSpringLoadBalancerFactory.class); - } - - SpringClientFactory clientFactory() { - return this.factory.getBean(SpringClientFactory.class); - } } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java index 076e269e6..113302d12 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java @@ -18,7 +18,10 @@ package com.tencent.cloud.polaris.circuitbreaker.feign; import feign.Client; +import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; +import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; +import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; /** @@ -28,9 +31,11 @@ import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalance */ public class PolarisFeignBlockingLoadBalancerClient extends FeignBlockingLoadBalancerClient { + public PolarisFeignBlockingLoadBalancerClient(Client delegate, - BlockingLoadBalancerClient loadBalancerClient) { - super(delegate, loadBalancerClient); + LoadBalancerClient loadBalancerClient, + LoadBalancerProperties properties, + LoadBalancerClientFactory loadBalancerClientFactory) { + super(delegate, loadBalancerClient, properties, loadBalancerClientFactory); } - } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java deleted file mode 100644 index 420cf27e3..000000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisLoadBalancerFeignClient.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.circuitbreaker.feign; - -import feign.Client; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory; -import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient; - -/** - * Wrap for {@link LoadBalancerFeignClient} - * - * @author Haotian Zhang - */ -public class PolarisLoadBalancerFeignClient extends LoadBalancerFeignClient { - - public PolarisLoadBalancerFeignClient(Client delegate, - CachingSpringLoadBalancerFactory lbClientFactory, - SpringClientFactory clientFactory) { - super(delegate, lbClientFactory, clientFactory); - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java index a6a15d19e..c85ac1614 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java @@ -51,9 +51,6 @@ public class PolarisFeignClientTest { if (client instanceof PolarisFeignClient) { return; } - if (client instanceof PolarisLoadBalancerFeignClient) { - return; - } if (client instanceof PolarisFeignBlockingLoadBalancerClient) { return; } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/pom.xml b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/pom.xml index d96db3d21..d0c8e8f26 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/pom.xml +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/pom.xml @@ -37,6 +37,11 @@ polaris-discovery-factory + + com.tencent.polaris + polaris-router-factory + + com.tencent.polaris polaris-test-common @@ -91,11 +96,6 @@ powermock-api-mockito2 test - - org.springframework.cloud - spring-cloud-loadbalancer - 3.0.1 - compile - + \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisProperties.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisProperties.java index be31339d4..cbeb95379 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisProperties.java +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisProperties.java @@ -69,8 +69,8 @@ public class PolarisProperties { /** * 使用spring cloud监听端口 */ - @Value("${server.port:}") - private int port; + @Value("${server.port:#{-1}}") + private int port = -1; /** * 是否开启负载均衡 @@ -78,14 +78,12 @@ public class PolarisProperties { @Value("${spring.cloud.polaris.discovery.loadbalancer.enabled:#{true}}") private Boolean loadbalancerEnabled; - /** * loadbalnce strategy */ @Value("${spring.cloud.polaris.discovery.loadbalancer.policy:#{'weightedRandom'}}") private String policy; - /** * loadbalnce strategy */ diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerClientConfiguration.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerClientConfiguration.java index ea5a82b1b..cc06aa07f 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerClientConfiguration.java +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerClientConfiguration.java @@ -17,8 +17,26 @@ package com.tencent.cloud.polaris.loadbalancer; +import com.tencent.cloud.constant.LoadbalancerConstant; +import com.tencent.cloud.polaris.PolarisProperties; +import com.tencent.polaris.router.api.core.RouterAPI; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.client.ConditionalOnBlockingDiscoveryEnabled; import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; +import org.springframework.cloud.client.ConditionalOnReactiveDiscoveryEnabled; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; +import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer; +import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; +import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.Environment; /** * @author liaochuntao @@ -27,4 +45,49 @@ import org.springframework.context.annotation.Configuration; @ConditionalOnDiscoveryEnabled public class PolarisLoadBalancerClientConfiguration { + @Bean + @ConditionalOnMissingBean + public ReactorLoadBalancer nacosLoadBalancer(Environment environment, + LoadBalancerClientFactory loadBalancerClientFactory, + PolarisProperties polarisProperties, + RouterAPI routerAPI) { + String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); + return new PolarisLoadbalancer( + name, loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), + polarisProperties, routerAPI); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnReactiveDiscoveryEnabled + @Order(LoadbalancerConstant.DISCOVERY_SERVICE_INSTANCE_SUPPLIER_ORDER) + public static class ReactiveSupportConfiguration { + + @Bean + @ConditionalOnBean(ReactiveDiscoveryClient.class) + @ConditionalOnMissingBean + @ConditionalOnProperty(value = "spring.cloud.loadbalancer.configurations", havingValue = "default", matchIfMissing = true) + public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( + ConfigurableApplicationContext context) { + return ServiceInstanceListSupplier.builder().withDiscoveryClient() + .build(context); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnBlockingDiscoveryEnabled + @Order(LoadbalancerConstant.DISCOVERY_SERVICE_INSTANCE_SUPPLIER_ORDER + 1) + public static class BlockingSupportConfiguration { + + @Bean + @ConditionalOnBean(DiscoveryClient.class) + @ConditionalOnMissingBean + @ConditionalOnProperty(value = "spring.cloud.loadbalancer.configurations", havingValue = "default", matchIfMissing = true) + public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( + ConfigurableApplicationContext context) { + return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient() + .build(context); + } + } + } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadbalancer.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadbalancer.java index 710805e4c..755ffba42 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadbalancer.java +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadbalancer.java @@ -18,8 +18,21 @@ package com.tencent.cloud.polaris.loadbalancer; +import com.tencent.cloud.metadata.context.MetadataContextHolder; import com.tencent.cloud.polaris.PolarisProperties; import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +import com.tencent.cloud.polaris.pojo.PolarisServiceInstance; +import com.tencent.polaris.api.pojo.DefaultServiceInstances; +import com.tencent.polaris.api.pojo.Instance; +import com.tencent.polaris.api.pojo.ServiceInstances; +import com.tencent.polaris.api.pojo.ServiceKey; +import com.tencent.polaris.api.rpc.Criteria; +import com.tencent.polaris.router.api.core.RouterAPI; +import com.tencent.polaris.router.api.rpc.ProcessLoadBalanceRequest; +import com.tencent.polaris.router.api.rpc.ProcessLoadBalanceResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.ObjectProvider; @@ -30,13 +43,14 @@ import org.springframework.cloud.client.loadbalancer.Request; import org.springframework.cloud.client.loadbalancer.Response; import org.springframework.cloud.loadbalancer.core.NoopServiceInstanceListSupplier; import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer; +import org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer; import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; import reactor.core.publisher.Mono; /** * @author liaochuntao */ -public class PolarisLoadbalancer implements ReactorServiceInstanceLoadBalancer { +public class PolarisLoadbalancer extends RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer { private static final Logger log = LoggerFactory.getLogger(PolarisLoadbalancer.class); @@ -46,16 +60,23 @@ public class PolarisLoadbalancer implements ReactorServiceInstanceLoadBalancer { private final PolarisProperties discoveryProperties; + private final RouterAPI routerAPI; + public PolarisLoadbalancer(String serviceId, - ObjectProvider supplierObjectProvider, - PolarisProperties discoveryProperties) { + ObjectProvider supplierObjectProvider, + PolarisProperties discoveryProperties, RouterAPI routerAPI) { + super(supplierObjectProvider, serviceId); this.serviceId = serviceId; this.supplierObjectProvider = supplierObjectProvider; this.discoveryProperties = discoveryProperties; + this.routerAPI = routerAPI; } @Override public Mono> choose(Request request) { + if (!discoveryProperties.getLoadbalancerEnabled()) { + return super.choose(request); + } ServiceInstanceListSupplier supplier = supplierObjectProvider.getIfAvailable(NoopServiceInstanceListSupplier::new); return supplier.get().next().map(this::getInstanceResponse); } @@ -66,15 +87,28 @@ public class PolarisLoadbalancer implements ReactorServiceInstanceLoadBalancer { return new EmptyResponse(); } + ProcessLoadBalanceRequest request = new ProcessLoadBalanceRequest(); + request.setDstInstances(convertToPolarisServiceInstances(serviceInstances)); + request.setLbPolicy(discoveryProperties.getPolicy()); + request.setCriteria(new Criteria()); + try { - ServiceInstance instance = NacosBalancer.getHostByRandomWeight3(serviceInstances); - return new DefaultResponse(instance); + ProcessLoadBalanceResponse response = routerAPI.processLoadBalance(request); + return new DefaultResponse(new PolarisServiceInstance(response.getTargetInstance())); } catch (Exception e) { - log.warn("NacosLoadBalancer error", e); + log.warn("PolarisLoadbalancer error", e); return new EmptyResponse(); } + } + private static ServiceInstances convertToPolarisServiceInstances(List serviceInstances) { + ServiceKey serviceKey = new ServiceKey(MetadataContextHolder.LOCAL_NAMESPACE, serviceInstances.get(0).getServiceId()); + List polarisInstances = serviceInstances + .stream() + .map(serviceInstance -> ((PolarisServiceInstance) serviceInstance).getPolarisInstance()) + .collect(Collectors.toList()); + return new DefaultServiceInstances(serviceKey, polarisInstances); } } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java index 9b33854f0..d22a3d04f 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java @@ -23,6 +23,7 @@ import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegis import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties; import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.client.serviceregistry.ServiceRegistry; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** @@ -43,9 +44,10 @@ public class PolarisAutoServiceRegistration extends AbstractAutoServiceRegistrat @Override protected PolarisRegistration getRegistration() { - if (this.registration.getPort() <= 0) { + if (this.registration.getPort() < 0 && this.getPort().get() > 0) { this.registration.setPort(this.getPort().get()); } + Assert.isTrue(this.registration.getPort() > 0, "service.port has not been set"); return this.registration; } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java index d99f30b9b..9a7c76236 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java @@ -175,16 +175,13 @@ public class PolarisServiceRegistry implements ServiceRegistry { * @param heartbeatRequest 心跳请求 */ public void heartbeat(InstanceHeartbeatRequest heartbeatRequest) { - heartbeatExecutor.scheduleWithFixedDelay(new Runnable() { - @Override - public void run() { - try { - polarisDiscoveryHandler.getProviderAPI().heartbeat(heartbeatRequest); - } catch (PolarisException e) { - log.error("polaris heartbeat[{}]", e.getCode(), e); - } catch (Exception e) { - log.error("polaris heartbeat runtime error", e); - } + heartbeatExecutor.scheduleWithFixedDelay(() -> { + try { + polarisDiscoveryHandler.getProviderAPI().heartbeat(heartbeatRequest); + } catch (PolarisException e) { + log.error("polaris heartbeat[{}]", e.getCode(), e); + } catch (Exception e) { + log.error("polaris heartbeat runtime error", e); } }, 0, ttl, TimeUnit.SECONDS); } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories index 75b02a918..26613d3af 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories @@ -1,5 +1,4 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration,\ - com.tencent.cloud.polaris.ribbon.PolarisDiscoveryRibbonAutoConfiguration,\ com.tencent.cloud.polaris.registry.PolarisServiceRegistryAutoConfiguration diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListAutoConfigurationTest.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListAutoConfigurationTest.java index 93b5c7c47..59f4568cc 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListAutoConfigurationTest.java +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListAutoConfigurationTest.java @@ -22,8 +22,6 @@ import static com.tencent.polaris.test.common.Consts.PORT; import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; import static org.assertj.core.api.Assertions.assertThat; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; import org.junit.Test; @@ -40,7 +38,6 @@ public class PolarisRibbonServerListAutoConfigurationTest { private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() .withConfiguration(AutoConfigurations.of( - PolarisRibbonClientTest.class, PolarisDiscoveryClientConfiguration.class)) .withPropertyValues("spring.application.name=" + SERVICE_PROVIDER) .withPropertyValues("server.port=" + PORT) @@ -48,36 +45,4 @@ public class PolarisRibbonServerListAutoConfigurationTest { .withPropertyValues("spring.cloud.polaris.discovery.namespace=" + NAMESPACE_TEST) .withPropertyValues("spring.cloud.polaris.discovery.token=xxxxxx"); - @Test - public void testProperties() { - this.contextRunner.run(context -> { - PolarisDiscoveryHandler discoveryHandler = context.getBean(PolarisDiscoveryHandler.class); - PolarisServerList serverList = new PolarisServerList(discoveryHandler); - IClientConfig iClientConfig = context.getBean(IClientConfig.class); - serverList.initWithNiwsConfig(iClientConfig); - - assertThat(serverList.getServiceId()).isEqualTo(SERVICE_PROVIDER); - }); - } - - @Configuration - @EnableAutoConfiguration - @EnableDiscoveryClient - static class PolarisRibbonClientTest { - - @Bean - IClientConfig iClientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.setClientName(SERVICE_PROVIDER); - return config; - } - - @Bean - @LoadBalanced - RestTemplate restTemplate() { - return new RestTemplate(); - } - - } - } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java index f42fcb68b..12f03cc6a 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisServerListTest.java @@ -24,13 +24,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; import com.tencent.cloud.polaris.context.PolarisContextConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; -import java.util.List; import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.test.mock.discovery.NamingServer; @@ -75,56 +72,6 @@ public class PolarisServerListTest { } } - /** - * Test {@link PolarisServerList#getInitialListOfServers()} with empty server list. - */ - @Test - @SuppressWarnings("unchecked") - public void test1(){ - this.contextRunner.run(context -> { - // mock - IClientConfig iClientConfig = mock(IClientConfig.class); - when(iClientConfig.getClientName()).thenReturn(SERVICE_PROVIDER); - PolarisDiscoveryHandler polarisDiscoveryHandler = context.getBean(PolarisDiscoveryHandler.class); - PolarisServerList serverList = new PolarisServerList(polarisDiscoveryHandler); - serverList.initWithNiwsConfig(iClientConfig); - - List servers = serverList.getInitialListOfServers(); - assertThat(servers).isEmpty(); - }); - } - - /** - * Test {@link PolarisServerList#getUpdatedListOfServers()} with server list of size 3. - */ - @Test - @SuppressWarnings("unchecked") - public void test2() throws Exception { - this.contextRunner.run(context -> { - // mock - IClientConfig iClientConfig = mock(IClientConfig.class); - when(iClientConfig.getClientName()).thenReturn(SERVICE_PROVIDER); - PolarisDiscoveryHandler polarisDiscoveryHandler = context.getBean(PolarisDiscoveryHandler.class); - PolarisServerList serverList = new PolarisServerList(polarisDiscoveryHandler); - serverList.initWithNiwsConfig(iClientConfig); - - - // add service with 3 instances - NamingService.InstanceParameter instanceParameter = new NamingService.InstanceParameter(); - instanceParameter.setHealthy(true); - instanceParameter.setIsolated(false); - instanceParameter.setWeight(100); - ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_PROVIDER); - namingServer.getNamingService().batchAddInstances(serviceKey, PORT, 3, instanceParameter); - - List servers = serverList.getUpdatedListOfServers(); - assertThat(servers).hasSize(3); - assertThat(servers.get(0).getPort()).isEqualTo(PORT); - assertThat(servers.get(1).getPort()).isEqualTo(PORT + 1); - assertThat(servers.get(2).getPort()).isEqualTo(PORT + 2); - }); - } - @Configuration @EnableAutoConfiguration @EnableDiscoveryClient diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/pom.xml b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/pom.xml index cbfd8ad68..91968ea7a 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/pom.xml +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/pom.xml @@ -34,7 +34,6 @@ org.springframework.cloud spring-cloud-loadbalancer - true diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterAutoConfiguration.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterAutoConfiguration.java new file mode 100644 index 000000000..01db9664f --- /dev/null +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterAutoConfiguration.java @@ -0,0 +1,112 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.router; + +import com.tencent.cloud.constant.LoadbalancerConstant; +import com.tencent.cloud.polaris.router.PolarisRouterServiceInstanceListSupplier; +import com.tencent.polaris.api.exception.PolarisException; +import com.tencent.polaris.client.api.SDKContext; +import com.tencent.polaris.factory.api.RouterAPIFactory; +import com.tencent.polaris.router.api.core.RouterAPI; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.client.ConditionalOnBlockingDiscoveryEnabled; +import org.springframework.cloud.client.ConditionalOnReactiveDiscoveryEnabled; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; +import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +/** + * Auto-configuration Ribbon for Polaris. + * + * @author Haotian Zhang + */ +@Configuration() +@EnableConfigurationProperties +@ConditionalOnProperty(value = "spring.cloud.polaris.loadbalancer.enabled", matchIfMissing = true) +public class PolarisRouterAutoConfiguration { + + @Bean(name = "polarisRoute") + @ConditionalOnMissingBean + public RouterAPI polarisRouter(SDKContext polarisContext) throws PolarisException { + return RouterAPIFactory.createRouterAPIByContext(polarisContext); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnReactiveDiscoveryEnabled + @Order(LoadbalancerConstant.ROUTER_SERVICE_INSTANCE_SUPPLIER_ORDER - 1000) + public static class ReactiveSupportConfiguration { + +// @Bean +// @ConditionalOnBean(ReactiveDiscoveryClient.class) +// @ConditionalOnMissingBean +// @ConditionalOnProperty(value = "spring.cloud.loadbalancer.configurations", havingValue = "default", matchIfMissing = true) +// public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(RouterAPI routerAPI, +// ConfigurableApplicationContext context) { +// return new PolarisRouterServiceInstanceListSupplier(ServiceInstanceListSupplier.builder().withDiscoveryClient() +// .build(context), routerAPI); +// } + + @Bean + @ConditionalOnBean(ReactiveDiscoveryClient.class) + @ConditionalOnMissingBean + @ConditionalOnProperty(value = "spring.cloud.loadbalancer.configurations", havingValue = "zone-preference", matchIfMissing = true) + public ServiceInstanceListSupplier polarisRouterDiscoveryClientServiceInstanceListSupplier(RouterAPI routerAPI, + ConfigurableApplicationContext context) { + return new PolarisRouterServiceInstanceListSupplier(ServiceInstanceListSupplier.builder().withDiscoveryClient() + .withZonePreference() + .build(context), routerAPI); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnBlockingDiscoveryEnabled + @Order(LoadbalancerConstant.ROUTER_SERVICE_INSTANCE_SUPPLIER_ORDER + 1 - 1000) + public static class BlockingSupportConfiguration { + +// @Bean +// @ConditionalOnBean(DiscoveryClient.class) +// @ConditionalOnMissingBean +// @ConditionalOnProperty(value = "spring.cloud.loadbalancer.configurations", havingValue = "default", matchIfMissing = true) +// public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( +// RouterAPI routerAPI, +// ConfigurableApplicationContext context) { +// return new PolarisRouterServiceInstanceListSupplier(ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient() +// .build(context), routerAPI); +// } + + @Bean + @ConditionalOnBean(DiscoveryClient.class) + @ConditionalOnMissingBean + @ConditionalOnProperty(value = "spring.cloud.loadbalancer.configurations", havingValue = "zone-preference", matchIfMissing = true) + public ServiceInstanceListSupplier polarisRouterDiscoveryClientServiceInstanceListSupplier(RouterAPI routerAPI, + ConfigurableApplicationContext context) { + return new PolarisRouterServiceInstanceListSupplier(ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient() + .withZonePreference().build(context), routerAPI); + } + + } + +} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRoutingLoadBalancer.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplier.java similarity index 85% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRoutingLoadBalancer.java rename to spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplier.java index 2ecec187b..a4148458a 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRoutingLoadBalancer.java +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplier.java @@ -34,19 +34,34 @@ import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.loadbalancer.Request; +import org.springframework.cloud.loadbalancer.core.DelegatingServiceInstanceListSupplier; +import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; import org.springframework.util.CollectionUtils; +import reactor.core.publisher.Flux; /** * @author Haotian Zhang */ -public class PolarisRoutingLoadBalancer { +public class PolarisRouterServiceInstanceListSupplier extends DelegatingServiceInstanceListSupplier { private final RouterAPI routerAPI; - public PolarisRoutingLoadBalancer(RouterAPI routerAPI) { + public PolarisRouterServiceInstanceListSupplier(ServiceInstanceListSupplier delegate, RouterAPI routerAPI) { + super(delegate); this.routerAPI = routerAPI; } + @Override + public Flux> get() { + return getDelegate().get().map(this::chooseInstances); + } + + @Override + public Flux> get(Request request) { + return super.get(request); + } + public List chooseInstances(List allServers) { if (CollectionUtils.isEmpty(allServers)) { return allServers; @@ -93,5 +108,4 @@ public class PolarisRoutingLoadBalancer { } return filteredInstances; } - } diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRouterAutoConfiguration.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRouterAutoConfiguration.java deleted file mode 100644 index 94d8f311b..000000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRouterAutoConfiguration.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.router.config; - -import com.tencent.polaris.api.exception.PolarisException; -import com.tencent.polaris.client.api.SDKContext; -import com.tencent.polaris.factory.api.RouterAPIFactory; -import com.tencent.polaris.router.api.core.RouterAPI; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Auto-configuration Ribbon for Polaris. - * - * @author Haotian Zhang - */ -@Configuration() -@EnableConfigurationProperties -@ConditionalOnProperty(value = "spring.cloud.polaris.loadbalancer.enabled", matchIfMissing = true) -public class PolarisRouterAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public PolarisRouterProperties polarisRibbonProperties() { - return new PolarisRouterProperties(); - } - - @Bean(name = "polarisRoute") - @ConditionalOnMissingBean - public RouterAPI polarisRouter(SDKContext polarisContext) throws PolarisException { - return RouterAPIFactory.createRouterAPIByContext(polarisContext); - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRouterProperties.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRouterProperties.java deleted file mode 100644 index 47575d105..000000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRouterProperties.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.router.config; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Haotian Zhang - */ -@ConfigurationProperties("spring.cloud.polaris.ribbon") -public class PolarisRouterProperties { - - /** - * 是否开启负载均衡 - */ - @Value("${spring.cloud.polaris.loadbalancer.enabled:#{true}}") - private Boolean loadbalancerEnabled; - - /** - * loadbalnce strategy - */ - @Value("${spring.cloud.polaris.loadbalancer.strategy:#{'weightedRandom'}}") - private String policy; - - public String getPolicy() { - return policy; - } - - public void setPolicy(String policy) { - this.policy = policy; - } - - public Boolean getLoadbalancerEnabled() { - return loadbalancerEnabled; - } - - public void setLoadbalancerEnabled(Boolean loadbalancerEnabled) { - this.loadbalancerEnabled = loadbalancerEnabled; - } - - @Override - public String toString() { - return "PolarisRibbonProperties{" + - "loadbalancerEnabled=" + loadbalancerEnabled + - ", policy='" + policy + '\'' + - '}'; - } -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisLoadBalanceRule.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisLoadBalanceRule.java deleted file mode 100644 index b39b9e170..000000000 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/rule/PolarisLoadBalanceRule.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.polaris.router.rule; - -import java.util.Arrays; - -/** - * @author Haotian Zhang - */ -public enum PolarisLoadBalanceRule { - - /** - * 加权随机 - */ - WEIGHTED_RANDOM_RULE("weighted_random"); - - /** - * 策略 - */ - String policy; - - PolarisLoadBalanceRule(String strategy) { - this.policy = strategy; - } - - public static PolarisLoadBalanceRule fromStrategy(String strategy) { - return Arrays.stream(values()).filter(t -> t.getPolicy().equals(strategy)).findAny() - .orElse(WEIGHTED_RANDOM_RULE); - } - - /** - * {@link #policy}的getter方法。 - */ - public String getPolicy() { - return policy; - } - -} diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/spring.factories index 5519d1071..8a988ebe7 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/resources/META-INF/spring.factories @@ -1,2 +1,2 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.tencent.cloud.polaris.router.config.PolarisRouterAutoConfiguration + com.tencent.cloud.polaris.router.PolarisRouterAutoConfiguration diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfigurationTest.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfigurationTest.java index 7e00e75c0..c2140bc7d 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfigurationTest.java +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/config/PolarisRibbonAutoConfigurationTest.java @@ -17,6 +17,7 @@ package com.tencent.cloud.polaris.router.config; +import com.tencent.cloud.polaris.router.PolarisRouterAutoConfiguration; import com.tencent.polaris.router.api.core.RouterAPI; import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -41,14 +42,6 @@ public class PolarisRibbonAutoConfigurationTest { .withPropertyValues("server.port=" + PORT) .withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081"); - @Test - public void testDefaultInitialization() { - this.contextRunner.run(context -> { - assertThat(context).hasSingleBean(RouterAPI.class); - assertThat(context).hasSingleBean(PolarisRouterProperties.class); - }); - } - @Configuration @EnableAutoConfiguration static class PolarisRibbonTest { diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRouterClientConfiguration.java b/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/constant/LoadbalancerConstant.java similarity index 58% rename from spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRouterClientConfiguration.java rename to spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/constant/LoadbalancerConstant.java index 43b3fee15..df5998908 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/config/PolarisRouterClientConfiguration.java +++ b/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/constant/LoadbalancerConstant.java @@ -15,19 +15,20 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.router.config; - -import com.tencent.cloud.polaris.router.PolarisRoutingLoadBalancer; -import com.tencent.cloud.polaris.router.rule.PolarisLoadBalanceRule; -import com.tencent.polaris.router.api.core.RouterAPI; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; +package com.tencent.cloud.constant; /** - * @author Haotian Zhang + * @author liaochuntao */ -@Configuration -public class PolarisRouterClientConfiguration { +public final class LoadbalancerConstant { + + private LoadbalancerConstant() {} + + public static final int DISCOVERY_SERVICE_INSTANCE_SUPPLIER_ORDER = 193827465 - 1000000; + + /** + * We need to ensure that the routing action is performed before the load balancing action can be performed + */ + public static final int ROUTER_SERVICE_INSTANCE_SUPPLIER_ORDER = DISCOVERY_SERVICE_INSTANCE_SUPPLIER_ORDER - 1000000; } diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/polaris/pojo/PolarisServiceInstance.java b/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/polaris/pojo/PolarisServiceInstance.java index 056b063fe..609491b5d 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/polaris/pojo/PolarisServiceInstance.java +++ b/spring-cloud-tencent-starters/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/polaris/pojo/PolarisServiceInstance.java @@ -48,6 +48,10 @@ public class PolarisServiceInstance implements ServiceInstance { } } + public Instance getPolarisInstance() { + return instance; + } + @Override public String getInstanceId() { return ServiceInstance.super.getInstanceId(); diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeign.java b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeign.java index d350f3be6..1ff90a6a5 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeign.java +++ b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeign.java @@ -22,13 +22,16 @@ import feign.Contract; import feign.Feign; import feign.InvocationHandlerFactory; import feign.Target; -import feign.hystrix.FallbackFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.cloud.openfeign.FeignClientFactoryBean; import org.springframework.cloud.openfeign.FeignContext; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; +import org.springframework.context.support.GenericApplicationContext; import org.springframework.util.StringUtils; import java.lang.reflect.InvocationHandler; @@ -85,7 +88,10 @@ public class PluggableFeign { super.invocationHandlerFactory(new InvocationHandlerFactory() { @Override public InvocationHandler create(Target target, Map dispatch) { - Object feignClientFactoryBean = applicationContext.getBean("&" + target.type().getName()); + GenericApplicationContext gctx = (GenericApplicationContext) Builder.this.applicationContext; + BeanDefinition def = gctx.getBeanDefinition(target.type().getName()); + + FeignClientFactoryBean feignClientFactoryBean = (FeignClientFactoryBean) def.getAttribute("feignClientsRegistrarFactoryBean"); Class fallback = (Class) ReflectionUtils.getFieldValue(feignClientFactoryBean, "fallback"); Class fallbackFactory = (Class) ReflectionUtils.getFieldValue(feignClientFactoryBean, @@ -104,8 +110,7 @@ public class PluggableFeign { if (void.class != fallback) { fallbackInstance = getFallbackInstanceFromContext(beanName, "fallback", fallback, target.type()); - return new PluggableFeignInvocationHandler(target, dispatch, - new FallbackFactory.Default<>(fallbackInstance), pluggableFeignPlugins); + return new PluggableFeignInvocationHandler(target, dispatch, (FallbackFactory) fallbackInstance, pluggableFeignPlugins); } if (void.class != fallbackFactory) { diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignContext.java b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignContext.java index 574846006..2d4593630 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignContext.java +++ b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignContext.java @@ -20,7 +20,7 @@ package com.tencent.cloud.feign; import feign.FeignException; import feign.InvocationHandlerFactory; import feign.Target; -import feign.hystrix.FallbackFactory; +import org.springframework.cloud.openfeign.FallbackFactory; import java.lang.reflect.Method; import java.util.Map; @@ -36,7 +36,7 @@ public class PluggableFeignContext { private Map dispatch; - private FallbackFactory fallbackFactory; + private FallbackFactory fallbackFactory; private Map fallbackMethodMap; @@ -66,11 +66,11 @@ public class PluggableFeignContext { this.dispatch = dispatch; } - public FallbackFactory getFallbackFactory() { + public FallbackFactory getFallbackFactory() { return fallbackFactory; } - public void setFallbackFactory(FallbackFactory fallbackFactory) { + public void setFallbackFactory(FallbackFactory fallbackFactory) { this.fallbackFactory = fallbackFactory; } diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignInvocationHandler.java b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignInvocationHandler.java index f05d4a4fb..20adde80b 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignInvocationHandler.java +++ b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeignInvocationHandler.java @@ -20,9 +20,9 @@ package com.tencent.cloud.feign; import feign.FeignException; import feign.InvocationHandlerFactory; import feign.Target; -import feign.hystrix.FallbackFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.cloud.openfeign.FallbackFactory; import org.springframework.util.CollectionUtils; import java.lang.reflect.InvocationHandler; @@ -48,7 +48,7 @@ public class PluggableFeignInvocationHandler implements InvocationHandler { private final Map dispatch; - private FallbackFactory fallbackFactory; + private FallbackFactory fallbackFactory; private Map fallbackMethodMap; @@ -59,7 +59,7 @@ public class PluggableFeignInvocationHandler implements InvocationHandler { private List exceptionPluggableFeignPlugins; PluggableFeignInvocationHandler(Target target, Map dispatch, - FallbackFactory fallbackFactory, List pluggableFeignPlugins) { + FallbackFactory fallbackFactory, List pluggableFeignPlugins) { this.target = checkNotNull(target, "target"); this.dispatch = checkNotNull(dispatch, "dispatch"); this.fallbackFactory = fallbackFactory; @@ -110,7 +110,9 @@ public class PluggableFeignInvocationHandler implements InvocationHandler { prePlugin.run(context); } - result = this.dispatch.get(method).invoke(args); + InvocationHandlerFactory.MethodHandler handler = this.dispatch.get(method); + + result = handler.invoke(args); context.setResult(result); diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/Metadata2HeaderScgFilter.java b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/Metadata2HeaderScgFilter.java index 7ac146bc7..67739b7d4 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/Metadata2HeaderScgFilter.java +++ b/spring-cloud-tencent-starters/spring-cloud-tencent-polaris-gateway/src/main/java/com/tencent/cloud/polaris/gateway/core/scg/filter/Metadata2HeaderScgFilter.java @@ -31,7 +31,7 @@ import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Map; -import static org.springframework.cloud.gateway.filter.LoadBalancerClientFilter.LOAD_BALANCER_CLIENT_FILTER_ORDER; +import static org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter.LOAD_BALANCER_CLIENT_FILTER_ORDER; /** * Scg filter used for writing metadata in HTTP request header.