Skip to content

Commit

Permalink
[huaweicloud#1207]support fallback address for isolation
Browse files Browse the repository at this point in the history
  • Loading branch information
liubao68 committed Jan 24, 2024
1 parent e26a5d2 commit aa9101a
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (C) 2020-2024 Huawei Technologies Co., Ltd. All rights reserved.
* 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
*
* http://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 com.huaweicloud.governance.adapters.loadbalancer;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;

/**
* Configures fallback address if discovery client do not find any instance or all
* instances are isolated.
*/
@ConfigurationProperties(prefix = "spring.cloud.discovery.client.fallback")
public class FallbackDiscoveryProperties implements InitializingBean {
private Map<String, DefaultServiceInstance> instances = new HashMap<>();

private boolean enabled = false;

private DefaultServiceInstance global;

public Map<String, DefaultServiceInstance> getInstances() {
return this.instances;
}

public void setInstances(Map<String, DefaultServiceInstance> instances) {
this.instances = instances;
}

public boolean isEnabled() {
return enabled;
}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

public DefaultServiceInstance getGlobal() {
return global;
}

public void setGlobal(DefaultServiceInstance global) {
this.global = global;
}

@Override
public void afterPropertiesSet() {
for (Entry<String, DefaultServiceInstance> entry : instances.entrySet()) {
entry.getValue().setServiceId(entry.getKey());
}
}

public ServiceInstance readFallbackServiceInstance(String serviceId) {
if (this.instances.get(serviceId) != null) {
return this.instances.get(serviceId);
}
return global;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,17 @@ public class InstanceIsolationServiceInstanceFilter implements ServiceInstanceFi

private final Environment env;

public InstanceIsolationServiceInstanceFilter(Environment environment) {
private final FallbackDiscoveryProperties fallbackDiscoveryProperties;

public InstanceIsolationServiceInstanceFilter(Environment environment,
FallbackDiscoveryProperties fallbackDiscoveryProperties) {
this.env = environment;
this.fallbackDiscoveryProperties = fallbackDiscoveryProperties;
EventManager.register(this);
}

@Subscribe
@SuppressWarnings("unused")
public void onInstanceIsolatedEvent(InstanceIsolatedEvent event) {
synchronized (lock) {
for (Iterator<String> iterator = isolatedInstances.keySet().iterator(); iterator.hasNext(); ) {
Expand All @@ -62,7 +67,10 @@ public void onInstanceIsolatedEvent(InstanceIsolatedEvent event) {
@Override
public List<ServiceInstance> filter(ServiceInstanceListSupplier supplier, List<ServiceInstance> instances,
Request<?> request) {
if (isolatedInstances.isEmpty() || instances.isEmpty()) {
if (instances.isEmpty()) {
return fallbackServiceInstance(supplier, instances);
}
if (isolatedInstances.isEmpty()) {
return instances;
}
List<ServiceInstance> result = new ArrayList<>(instances.size());
Expand All @@ -84,11 +92,20 @@ public List<ServiceInstance> filter(ServiceInstanceListSupplier supplier, List<S
}

if (result.isEmpty()) {
return instances;
return fallbackServiceInstance(supplier, instances);
}
return result;
}

private List<ServiceInstance> fallbackServiceInstance(ServiceInstanceListSupplier supplier,
List<ServiceInstance> instances) {
if (fallbackDiscoveryProperties.isEnabled()
&& fallbackDiscoveryProperties.readFallbackServiceInstance(supplier.getServiceId()) != null) {
return List.of(fallbackDiscoveryProperties.readFallbackServiceInstance(supplier.getServiceId()));
}
return instances;
}

@Override
public int getOrder() {
return env.getProperty("spring.cloud.loadbalance.filter.instance-isolation.order", int.class, -300);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,13 @@ public LoadBalancerRequestFactory loadBalancerRequestFactory(LoadBalancerClient
}

@Bean
public InstanceIsolationServiceInstanceFilter instanceIsolationServiceInstanceFilter(Environment environment) {
return new InstanceIsolationServiceInstanceFilter(environment);
public InstanceIsolationServiceInstanceFilter instanceIsolationServiceInstanceFilter(Environment environment,
FallbackDiscoveryProperties fallbackDiscoveryProperties) {
return new InstanceIsolationServiceInstanceFilter(environment, fallbackDiscoveryProperties);
}

@Bean
public FallbackDiscoveryProperties fallbackDiscoveryProperties() {
return new FallbackDiscoveryProperties();
}
}

0 comments on commit aa9101a

Please sign in to comment.