From aef64061be8ca4ca56d03690f7c26ef6cb31944c Mon Sep 17 00:00:00 2001 From: jizhuozhi Date: Fri, 28 Oct 2022 01:24:04 +0800 Subject: [PATCH] feat: support autoconfigure WeightedServiceInstanceListSupplier (#1163) --- .../main/asciidoc/spring-cloud-commons.adoc | 2 +- .../LoadBalancerClientConfiguration.java | 27 +++++++++++++++++++ .../LoadBalancerClientConfigurationTests.java | 25 +++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/spring-cloud-commons.adoc b/docs/src/main/asciidoc/spring-cloud-commons.adoc index 870ef511..96722475 100644 --- a/docs/src/main/asciidoc/spring-cloud-commons.adoc +++ b/docs/src/main/asciidoc/spring-cloud-commons.adoc @@ -935,7 +935,7 @@ By default, we try to read and parse the weight from the metadata map (the key i If the weight is not specified in the metadata map, we default the weight of this instance to be 1. -You can use this sample configuration to set it up: +You can configure it either by setting the value of `spring.cloud.loadbalancer.configurations` to `weighted` or by providing your own `ServiceInstanceListSupplier` bean, for example: [[weighted-custom-loadbalancer-configuration]] [source,java,indent=0] diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java index d52a2d73..c5739cea 100644 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java +++ b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java @@ -57,6 +57,7 @@ import org.springframework.web.reactive.function.client.WebClient; * @author Tim Ysewyn * @author BaoLin Zhu * @author changjin wei(魏昌进) + * @author Zhuozhi Ji */ @Configuration(proxyBeanMethods = false) @ConditionalOnDiscoveryEnabled @@ -133,6 +134,14 @@ public class LoadBalancerClientConfiguration { .build(context); } + @Bean + @ConditionalOnBean(ReactiveDiscoveryClient.class) + @ConditionalOnMissingBean + @Conditional(WeightedConfigurationCondition.class) + public ServiceInstanceListSupplier weightedServiceInstanceListSupplier(ConfigurableApplicationContext context) { + return ServiceInstanceListSupplier.builder().withDiscoveryClient().withWeighted().build(context); + } + } @Configuration(proxyBeanMethods = false) @@ -189,6 +198,14 @@ public class LoadBalancerClientConfiguration { .build(context); } + @Bean + @ConditionalOnBean(DiscoveryClient.class) + @ConditionalOnMissingBean + @Conditional(WeightedConfigurationCondition.class) + public ServiceInstanceListSupplier weightedServiceInstanceListSupplier(ConfigurableApplicationContext context) { + return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withWeighted().build(context); + } + } @Configuration(proxyBeanMethods = false) @@ -324,4 +341,14 @@ public class LoadBalancerClientConfiguration { } + static class WeightedConfigurationCondition implements Condition { + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + return LoadBalancerEnvironmentPropertyUtils.equalToForClientOrDefault(context.getEnvironment(), + "configurations", "weighted"); + } + + } + } diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfigurationTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfigurationTests.java index 5a356cb5..f3043ca6 100644 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfigurationTests.java +++ b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfigurationTests.java @@ -33,6 +33,7 @@ import org.springframework.cloud.loadbalancer.core.HealthCheckServiceInstanceLis import org.springframework.cloud.loadbalancer.core.RequestBasedStickySessionServiceInstanceListSupplier; import org.springframework.cloud.loadbalancer.core.RetryAwareServiceInstanceListSupplier; import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; +import org.springframework.cloud.loadbalancer.core.WeightedServiceInstanceListSupplier; import org.springframework.cloud.loadbalancer.core.ZonePreferenceServiceInstanceListSupplier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -46,6 +47,7 @@ import static org.assertj.core.api.BDDAssertions.then; * Tests for {@link LoadBalancerClientConfiguration}. * * @author Olga Maciaszek-Sharma + * @author Zhuozhi Ji */ class LoadBalancerClientConfigurationTests { @@ -113,6 +115,18 @@ class LoadBalancerClientConfigurationTests { }); } + @Test + void shouldInstantiateWeightedServiceInstanceListSupplier() { + reactiveDiscoveryClientRunner.withUserConfiguration(TestConfig.class) + .withPropertyValues("spring.cloud.loadbalancer.configurations=weighted").run(context -> { + ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class); + then(supplier).isInstanceOf(WeightedServiceInstanceListSupplier.class); + ServiceInstanceListSupplier delegate = ((DelegatingServiceInstanceListSupplier) supplier) + .getDelegate(); + then(delegate).isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); + }); + } + @Test void shouldInstantiateRequestBasedStickySessionServiceInstanceListSupplierTests() { reactiveDiscoveryClientRunner.withUserConfiguration(TestConfig.class) @@ -182,6 +196,17 @@ class LoadBalancerClientConfigurationTests { }); } + @Test + void shouldInstantiateBlockingWeightedServiceInstanceListSupplier() { + blockingDiscoveryClientRunner.withUserConfiguration(RestTemplateTestConfig.class) + .withPropertyValues("spring.cloud.loadbalancer.configurations=weighted").run(context -> { + ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class); + then(supplier).isInstanceOf(WeightedServiceInstanceListSupplier.class); + then(((DelegatingServiceInstanceListSupplier) supplier).getDelegate()) + .isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); + }); + } + @Configuration protected static class TestConfig {