Skip to content

Lb configuration builders #751

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 5, 2020
Merged
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
47 changes: 16 additions & 31 deletions docs/src/main/asciidoc/spring-cloud-commons.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -917,22 +917,14 @@ 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());
}
return delegate;
}
ConfigurableApplicationContext context) {
return ServiceInstanceListSuppliers.builder()
.withDiscoveryClient()
.withZonePreference()
.withCaching()
.build(context);
}
}
----

=== Instance Health-Check for LoadBalancer
Expand Down Expand Up @@ -966,25 +958,18 @@ 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;
}
ConfigurableApplicationContext context) {
return ServiceInstanceListSuppliers.builder()
.withDiscoveryClient()
.withHealthChecks()
.withCaching()
.build(context);
}
}
----

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

[[spring-cloud-loadbalancer-starter]]
=== Spring Cloud LoadBalancer Starter

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
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.ServiceInstanceListSuppliers;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
Expand Down Expand Up @@ -71,17 +71,9 @@ public static class ReactiveSupportConfiguration {
@ConditionalOnBean(ReactiveDiscoveryClient.class)
@ConditionalOnMissingBean
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;
ConfigurableApplicationContext context) {
return ServiceInstanceListSuppliers.builder().withDiscoveryClient()
.withCaching().build(context);
}

@Bean
Expand Down Expand Up @@ -112,17 +104,9 @@ public static class BlockingSupportConfiguration {
@ConditionalOnBean(DiscoveryClient.class)
@ConditionalOnMissingBean
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;
ConfigurableApplicationContext context) {
return ServiceInstanceListSuppliers.builder().withBlockingDiscoveryClient()
.withCaching().build(context);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
* @author Olga Maciaszek-Sharma
* @since 2.2.0
*/
public class CachingServiceInstanceListSupplier implements ServiceInstanceListSupplier {
public class CachingServiceInstanceListSupplier
extends DelegatingServiceInstanceListSupplier {

private static final Log log = LogFactory
.getLog(CachingServiceInstanceListSupplier.class);
Expand All @@ -48,14 +49,12 @@ public class CachingServiceInstanceListSupplier implements ServiceInstanceListSu
public static final String SERVICE_INSTANCE_CACHE_NAME = CachingServiceInstanceListSupplier.class
.getSimpleName() + "Cache";

private final ServiceInstanceListSupplier delegate;

private final Flux<List<ServiceInstance>> serviceInstances;

@SuppressWarnings("unchecked")
public CachingServiceInstanceListSupplier(ServiceInstanceListSupplier delegate,
CacheManager cacheManager) {
this.delegate = delegate;
super(delegate);
this.serviceInstances = CacheFlux.lookup(key -> {
// TODO: configurable cache name
Cache cache = cacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME);
Expand All @@ -70,7 +69,7 @@ public CachingServiceInstanceListSupplier(ServiceInstanceListSupplier delegate,
return Mono.empty();
}
return Flux.just(list).materialize().collectList();
}, delegate.getServiceId()).onCacheMissResume(this.delegate)
}, delegate.getServiceId()).onCacheMissResume(delegate)
.andWriteWith((key, signals) -> Flux.fromIterable(signals).dematerialize()
.doOnNext(instances -> {
Cache cache = cacheManager
Expand All @@ -87,11 +86,6 @@ public CachingServiceInstanceListSupplier(ServiceInstanceListSupplier delegate,
}).then());
}

@Override
public String getServiceId() {
return delegate.getServiceId();
}

@Override
public Flux<List<ServiceInstance>> get() {
return serviceInstances;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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.core;

import org.springframework.util.Assert;

/**
* Represents a {@link ServiceInstanceListSupplier} that uses a delegate
* {@link ServiceInstanceListSupplier} instance underneath.
*
* @author Spencer Gibb
*/
public abstract class DelegatingServiceInstanceListSupplier
implements ServiceInstanceListSupplier {

private final ServiceInstanceListSupplier delegate;

public DelegatingServiceInstanceListSupplier(ServiceInstanceListSupplier delegate) {
Assert.notNull(delegate, "delegate may not be null");
this.delegate = delegate;
}

public ServiceInstanceListSupplier getDelegate() {
return this.delegate;
}

@Override
public String getServiceId() {
return this.delegate.getServiceId();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,12 @@
* @since 2.2.0
*/
public class HealthCheckServiceInstanceListSupplier
implements ServiceInstanceListSupplier, InitializingBean, DisposableBean {
extends DelegatingServiceInstanceListSupplier
implements InitializingBean, DisposableBean {

private static final Log LOG = LogFactory
.getLog(HealthCheckServiceInstanceListSupplier.class);

private final ServiceInstanceListSupplier delegate;

private final LoadBalancerProperties.HealthCheck healthCheck;

private final WebClient webClient;
Expand All @@ -64,7 +63,7 @@ public class HealthCheckServiceInstanceListSupplier

public HealthCheckServiceInstanceListSupplier(ServiceInstanceListSupplier delegate,
LoadBalancerProperties.HealthCheck healthCheck, WebClient webClient) {
this.delegate = delegate;
super(delegate);
this.healthCheck = healthCheck;
defaultHealthCheckPath = healthCheck.getPath().getOrDefault("default",
"/actuator/health");
Expand Down Expand Up @@ -121,11 +120,6 @@ protected Flux<List<ServiceInstance>> healthCheckFlux(
}).repeatWhen(restart -> restart.delayElements(healthCheck.getInterval()));
}

@Override
public String getServiceId() {
return delegate.getServiceId();
}

@Override
public Flux<List<ServiceInstance>> get() {
return aliveInstancesReplay;
Expand Down
Loading