Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/main/asciidoc/_configprops.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
|spring.cloud.loadbalancer.ribbon.enabled | true | Causes `RibbonLoadBalancerClient` to be used by default.
|spring.cloud.refresh.enabled | true | Enables autoconfiguration for the refresh scope and associated features.
|spring.cloud.refresh.extra-refreshable | true | Additional class names for beans to post process into refresh scope.
|spring.cloud.refresh.never-refreshable | true | Comma separated list of class names for beans to never be refreshed or rebound.
|spring.cloud.service-registry.auto-registration.enabled | true | Whether service auto-registration is enabled. Defaults to true.
|spring.cloud.service-registry.auto-registration.fail-fast | false | Whether startup fails if there is no AutoServiceRegistration. Defaults to false.
|spring.cloud.service-registry.auto-registration.register-management | true | Whether to register the management as a service. Defaults to true.
Expand Down
44 changes: 12 additions & 32 deletions docs/src/main/asciidoc/spring-cloud-commons.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -916,22 +916,12 @@ You could use this sample configuration to set it up:
public class CustomLoadBalancerConfiguration {

@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ReactiveDiscoveryClient discoveryClient, Environment environment,
LoadBalancerZoneConfig zoneConfig,
ApplicationContext context) {
DiscoveryClientServiceInstanceListSupplier firstDelegate = new DiscoveryClientServiceInstanceListSupplier(
discoveryClient, environment);
ZonePreferenceServiceInstanceListSupplier delegate = new ZonePreferenceServiceInstanceListSupplier(firstDelegate,
zoneConfig);
ObjectProvider<LoadBalancerCacheManager> cacheManagerProvider = context
.getBeanProvider(LoadBalancerCacheManager.class);
if (cacheManagerProvider.getIfAvailable() != null) {
return new CachingServiceInstanceListSupplier(delegate,
cacheManagerProvider.getIfAvailable());
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ReactiveDiscoveryClient discoveryClient, Environment environment,
LoadBalancerZoneConfig zoneConfig,
ApplicationContext context) {
return cachedOrDelegate(context, zonedWithDelegate(discoveryClientBased (discoveryClient, environment), zoneConfig));
}
return delegate;
}
}
----

Expand Down Expand Up @@ -974,24 +964,12 @@ You could use this sample configuration to set it up:
public class CustomLoadBalancerConfiguration {

@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ReactiveDiscoveryClient discoveryClient, Environment environment,
LoadBalancerProperties loadBalancerProperties,
ApplicationContext context,
InstanceHealthChecker healthChecker) {
DiscoveryClientServiceInstanceListSupplier firstDelegate = new DiscoveryClientServiceInstanceListSupplier(
discoveryClient, environment);
HealthCheckServiceInstanceListSupplier delegate = new HealthCheckServiceInstanceListSupplier(firstDelegate,
loadBalancerProperties, healthChecker);
ObjectProvider<LoadBalancerCacheManager> cacheManagerProvider = context
.getBeanProvider(LoadBalancerCacheManager.class);
if (cacheManagerProvider.getIfAvailable() != null) {
return new CachingServiceInstanceListSupplier(delegate,
cacheManagerProvider.getIfAvailable());
}
return delegate;
}
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ReactiveDiscoveryClient discoveryClient, Environment environment,
ApplicationContext context, LoadBalancerProperties.HealthCheck healthCheck, WebClient webClient) {
return cachedOrDelegate(context, healthCheckBased(discoveryClientBased (discoveryClient, environment), healthCheck, webClient));
}
}
----

[[spring-cloud-loadbalancer-starter]]
Expand Down Expand Up @@ -1050,6 +1028,8 @@ public class MyConfiguration {
}
}
----

TIP:: In order to make working on your own LoadBalancer configuration easier, we have added some utility methods in `ServiceInstanceListSuppliers` and `LoadBalancers` classes.
====

== Spring Cloud Circuit Breaker
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@
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.annotation.configutil.LoadBalancers;
import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheManager;
import org.springframework.cloud.loadbalancer.core.CachingServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.CachingServiceInstanceSupplier;
import org.springframework.cloud.loadbalancer.core.DiscoveryClientServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.DiscoveryClientServiceInstanceSupplier;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
Expand All @@ -41,6 +39,9 @@
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;

import static org.springframework.cloud.loadbalancer.annotation.configutil.ServiceInstanceListSuppliers.cachedOrDelegate;
import static org.springframework.cloud.loadbalancer.annotation.configutil.ServiceInstanceListSuppliers.discoveryClientBased;

/**
* @author Spencer Gibb
* @author Olga Maciaszek-Sharma
Expand All @@ -57,9 +58,7 @@ public class LoadBalancerClientConfiguration {
public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(
Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name,
ServiceInstanceListSupplier.class), name);
return LoadBalancers.roundRobin(loadBalancerClientFactory, environment);
}

@Configuration(proxyBeanMethods = false)
Expand All @@ -73,15 +72,7 @@ public static class ReactiveSupportConfiguration {
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ReactiveDiscoveryClient discoveryClient, Environment env,
ApplicationContext context) {
DiscoveryClientServiceInstanceListSupplier delegate = new DiscoveryClientServiceInstanceListSupplier(
discoveryClient, env);
ObjectProvider<LoadBalancerCacheManager> cacheManagerProvider = context
.getBeanProvider(LoadBalancerCacheManager.class);
if (cacheManagerProvider.getIfAvailable() != null) {
return new CachingServiceInstanceListSupplier(delegate,
cacheManagerProvider.getIfAvailable());
}
return delegate;
return cachedOrDelegate(context, discoveryClientBased(discoveryClient, env));
}

@Bean
Expand Down Expand Up @@ -114,15 +105,7 @@ public static class BlockingSupportConfiguration {
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
DiscoveryClient discoveryClient, Environment env,
ApplicationContext context) {
DiscoveryClientServiceInstanceListSupplier delegate = new DiscoveryClientServiceInstanceListSupplier(
discoveryClient, env);
ObjectProvider<LoadBalancerCacheManager> cacheManagerProvider = context
.getBeanProvider(LoadBalancerCacheManager.class);
if (cacheManagerProvider.getIfAvailable() != null) {
return new CachingServiceInstanceListSupplier(delegate,
cacheManagerProvider.getIfAvailable());
}
return delegate;
return cachedOrDelegate(context, discoveryClientBased(discoveryClient, env));
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* 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 org.springframework.cloud.loadbalancer.annotation.configutil;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.core.env.Environment;

/**
* Utility class containing helper methods for setting up {@link ReactorLoadBalancer}
* configuration in a more concise way.
*
* @author Olga Maciaszek-Sharma
* @since 2.2.3
*/
public final class LoadBalancers {

private LoadBalancers() {
throw new IllegalStateException("Can't instantiate a utility class");
}

public static ReactorLoadBalancer<ServiceInstance> roundRobin(
ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider,
String serviceId) {
return new RoundRobinLoadBalancer(serviceInstanceListSupplierProvider, serviceId);
}

public static ReactorLoadBalancer<ServiceInstance> roundRobin(
ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider,
Environment environment) {
return new RoundRobinLoadBalancer(serviceInstanceListSupplierProvider,
environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME));
}

public static ReactorLoadBalancer<ServiceInstance> roundRobin(
LoadBalancerClientFactory loadBalancerClientFactory, String serviceId) {
return roundRobin(
serviceInstanceListSupplierProvider(loadBalancerClientFactory, serviceId),
serviceId);
}

public static ReactorLoadBalancer<ServiceInstance> roundRobin(
LoadBalancerClientFactory loadBalancerClientFactory,
Environment environment) {
String serviceId = environment
.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RoundRobinLoadBalancer(
serviceInstanceListSupplierProvider(loadBalancerClientFactory, serviceId),
serviceId);
}

private static ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider(
LoadBalancerClientFactory loadBalancerClientFactory, String serviceId) {
return loadBalancerClientFactory.getLazyProvider(serviceId,
ServiceInstanceListSupplier.class);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* 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 org.springframework.cloud.loadbalancer.annotation.configutil;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerProperties;
import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheManager;
import org.springframework.cloud.loadbalancer.config.LoadBalancerZoneConfig;
import org.springframework.cloud.loadbalancer.core.CachingServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.DiscoveryClientServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.HealthCheckServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.ZonePreferenceServiceInstanceListSupplier;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.web.reactive.function.client.WebClient;

/**
* Utility class containing helper methods for setting up
* {@link ServiceInstanceListSupplier} configuration in a more concise way.
*
* @author Olga Maciaszek-Sharma
* @since 2.2.3
*/
public final class ServiceInstanceListSuppliers {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one feels like a true builder is needed, since you will start with discovery client, then add zone preference or health chech and cache later.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that each of these objects has only 2 fields and they are always required. I've started doing a builder approach here: master...lb-config-builders , but then we would still either be passing all the arguments in constructor or having to call all the builder methods one after another. I could add some methods like withDiscoveryClientDelegate(discoveryClient, environment), but am not sure that it would be easier to use than those utility methods. Or where you thinking about implementing it yet another way? wdyt?


private ServiceInstanceListSuppliers() {
throw new IllegalStateException("Can't instantiate a utility class");
}

public static ServiceInstanceListSupplier cachedOrDelegate(
ObjectProvider<LoadBalancerCacheManager> cacheManagerProvider,
ServiceInstanceListSupplier delegate) {
if (cacheManagerProvider.getIfAvailable() != null) {
return new CachingServiceInstanceListSupplier(delegate,
cacheManagerProvider.getIfAvailable());
}
return delegate;
}

public static ServiceInstanceListSupplier cachedOrDelegate(ApplicationContext context,
ServiceInstanceListSupplier delegate) {
return cachedOrDelegate(context.getBeanProvider(LoadBalancerCacheManager.class),
delegate);
}

public static ServiceInstanceListSupplier discoveryClientBased(
ReactiveDiscoveryClient discoveryClient, Environment environment) {
return new DiscoveryClientServiceInstanceListSupplier(discoveryClient,
environment);
}

public static ServiceInstanceListSupplier discoveryClientBased(
DiscoveryClient discoveryClient, Environment environment) {
return new DiscoveryClientServiceInstanceListSupplier(discoveryClient,
environment);
}

public static ServiceInstanceListSupplier zonePreferenceBased(
ServiceInstanceListSupplier delegate, LoadBalancerZoneConfig zoneConfig) {
return new ZonePreferenceServiceInstanceListSupplier(delegate, zoneConfig);
}

public static ServiceInstanceListSupplier healthCheckBased(
ServiceInstanceListSupplier delegate,
LoadBalancerProperties.HealthCheck healthCheck, WebClient webClient) {
return new HealthCheckServiceInstanceListSupplier(delegate, healthCheck,
webClient);
}

}