org.zodiac.loadbalancer.ribbon.rule.MetadataAwareRule Maven / Gradle / Ivy
package org.zodiac.loadbalancer.ribbon.rule;
import com.netflix.loadbalancer.Server;
import org.springframework.util.PatternMatchUtils;
import org.zodiac.commons.support.SpringContextHolder;
import org.zodiac.loadbalancer.ribbon.config.PlatformRibbonRuleInfo;
import org.zodiac.loadbalancer.ribbon.predicate.DiscoveryEnabledPredicate;
import org.zodiac.loadbalancer.ribbon.predicate.MetadataAwarePredicate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
public class MetadataAwareRule extends DiscoveryEnabledRule {
private final AtomicReference ribbonRoutingInfoRef = new AtomicReference<>();
@Deprecated
public MetadataAwareRule() {
this(null, null);
}
public MetadataAwareRule(PlatformRibbonRuleInfo platfromRibbonRoutingInfo) {
this(platfromRibbonRoutingInfo, null);
}
public MetadataAwareRule(PlatformRibbonRuleInfo platfromRibbonRoutingInfo, DiscoveryEnabledPredicate discoveryEnabledPredicate) {
super(null != discoveryEnabledPredicate ? discoveryEnabledPredicate : MetadataAwarePredicate.DEFAULT_INSTANCE);
this.ribbonRoutingInfoRef.compareAndSet(null, platfromRibbonRoutingInfo);
}
@Override
public List filterServers(List serverList) {
ribbonRoutingInfoRef.compareAndSet(null, getRibbonRoutingInfo());
PlatformRibbonRuleInfo ribbonRoutingInfo = ribbonRoutingInfoRef.get();
List priorIpPattern = ribbonRoutingInfo.getPriorIpPattern();
/*1. 获取 IP 规则。*/
boolean hasPriorIpPattern = !priorIpPattern.isEmpty();
String[] priorIpPatterns = priorIpPattern.toArray(new String[0]);
List priorServerList = new ArrayList<>();
for (Server server : serverList) {
/*2. 按配置顺序排列 IP 服务。*/
String host = server.getHost();
if (hasPriorIpPattern && PatternMatchUtils.simpleMatch(priorIpPatterns, host)) {
priorServerList.add(server);
}
}
/*3. 如果优先的有数据直接返回。*/
if (!priorServerList.isEmpty()) {
return priorServerList;
}
return Collections.unmodifiableList(serverList);
}
private PlatformRibbonRuleInfo getRibbonRoutingInfo() {
PlatformRibbonRuleInfo ribbonRoutingInfo = SpringContextHolder.getBean(PlatformRibbonRuleInfo.class);
return ribbonRoutingInfo;
}
}