Zone-Based Load-Balancing
To enable zone-based load-balancing, we provide the ZonePreferenceServiceInstanceListSupplier
.
We use DiscoveryClient
-specific zone
configuration (for example, eureka.instance.metadata-map.zone
) to pick the zone that the client tries to filter available service instances for.
You can also override DiscoveryClient -specific zone setup by setting the value of spring.cloud.loadbalancer.zone property.
|
To determine the zone of a retrieved ServiceInstance , we check the value under the "zone" key in its metadata map.
|
The ZonePreferenceServiceInstanceListSupplier
filters retrieved instances and only returns the ones within the same zone.
If the zone is null
or there are no instances within the same zone, it returns all the retrieved instances.
In order to use the zone-based load-balancing approach, you will have to instantiate a ZonePreferenceServiceInstanceListSupplier
bean in a custom configuration.
We use delegates to work with ServiceInstanceListSupplier
beans.
We suggest passing a DiscoveryClientServiceInstanceListSupplier
delegate in the constructor of ZonePreferenceServiceInstanceListSupplier
and, in turn, wrapping the latter with a CachingServiceInstanceListSupplier
to leverage LoadBalancer caching mechanism.
You could use this sample configuration to set it up:
public class CustomLoadBalancerConfiguration {
@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ReactiveDiscoveryClient discoveryClient, Environment environment,
ApplicationContext context) {
DiscoveryClientServiceInstanceListSupplier firstDelegate = new DiscoveryClientServiceInstanceListSupplier(
discoveryClient, environment);
ZonePreferenceServiceInstanceListSupplier delegate = new ZonePreferenceServiceInstanceListSupplier(firstDelegate,
environment);
ObjectProvider<LoadBalancerCacheManager> cacheManagerProvider = context
.getBeanProvider(LoadBalancerCacheManager.class);
if (cacheManagerProvider.getIfAvailable() != null) {
return new CachingServiceInstanceListSupplier(delegate,
cacheManagerProvider.getIfAvailable());
}
return delegate;
}
}