|
|
@ -18,6 +18,7 @@
|
|
|
|
package com.tencent.cloud.polaris.loadbalancer;
|
|
|
|
package com.tencent.cloud.polaris.loadbalancer;
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
|
@ -28,10 +29,12 @@ import com.netflix.loadbalancer.IRule;
|
|
|
|
import com.netflix.loadbalancer.PollingServerListUpdater;
|
|
|
|
import com.netflix.loadbalancer.PollingServerListUpdater;
|
|
|
|
import com.netflix.loadbalancer.Server;
|
|
|
|
import com.netflix.loadbalancer.Server;
|
|
|
|
import com.netflix.loadbalancer.ServerList;
|
|
|
|
import com.netflix.loadbalancer.ServerList;
|
|
|
|
|
|
|
|
import com.tencent.cloud.common.constant.ContextConstant;
|
|
|
|
import com.tencent.cloud.common.constant.MetadataConstant.SystemMetadataKey;
|
|
|
|
import com.tencent.cloud.common.constant.MetadataConstant.SystemMetadataKey;
|
|
|
|
import com.tencent.cloud.common.metadata.MetadataContext;
|
|
|
|
import com.tencent.cloud.common.metadata.MetadataContext;
|
|
|
|
import com.tencent.cloud.common.metadata.MetadataContextHolder;
|
|
|
|
import com.tencent.cloud.common.metadata.MetadataContextHolder;
|
|
|
|
import com.tencent.cloud.common.pojo.PolarisServer;
|
|
|
|
import com.tencent.cloud.common.pojo.PolarisServer;
|
|
|
|
|
|
|
|
import com.tencent.cloud.polaris.loadbalancer.config.PolarisLoadBalancerProperties;
|
|
|
|
import com.tencent.polaris.api.core.ConsumerAPI;
|
|
|
|
import com.tencent.polaris.api.core.ConsumerAPI;
|
|
|
|
import com.tencent.polaris.api.pojo.DefaultInstance;
|
|
|
|
import com.tencent.polaris.api.pojo.DefaultInstance;
|
|
|
|
import com.tencent.polaris.api.pojo.DefaultServiceInstances;
|
|
|
|
import com.tencent.polaris.api.pojo.DefaultServiceInstances;
|
|
|
@ -44,10 +47,9 @@ import com.tencent.polaris.api.rpc.InstancesResponse;
|
|
|
|
import com.tencent.polaris.router.api.core.RouterAPI;
|
|
|
|
import com.tencent.polaris.router.api.core.RouterAPI;
|
|
|
|
import com.tencent.polaris.router.api.rpc.ProcessRoutersRequest;
|
|
|
|
import com.tencent.polaris.router.api.rpc.ProcessRoutersRequest;
|
|
|
|
import com.tencent.polaris.router.api.rpc.ProcessRoutersResponse;
|
|
|
|
import com.tencent.polaris.router.api.rpc.ProcessRoutersResponse;
|
|
|
|
|
|
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Routing load balancer of polaris.
|
|
|
|
* Routing load balancer of polaris.
|
|
|
|
*
|
|
|
|
*
|
|
|
@ -59,45 +61,74 @@ public class PolarisLoadBalancer extends DynamicServerListLoadBalancer<Server> {
|
|
|
|
|
|
|
|
|
|
|
|
private ConsumerAPI consumerAPI;
|
|
|
|
private ConsumerAPI consumerAPI;
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isPolarisDiscovery = true;
|
|
|
|
private PolarisLoadBalancerProperties polarisLoadBalancerProperties;
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isFirstCall = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public PolarisLoadBalancer(IClientConfig config, IRule rule, IPing ping,
|
|
|
|
public PolarisLoadBalancer(IClientConfig config, IRule rule, IPing ping, ServerList<Server> serverList,
|
|
|
|
ServerList<Server> serverList, RouterAPI routerAPI, ConsumerAPI consumerAPI) {
|
|
|
|
RouterAPI routerAPI, ConsumerAPI consumerAPI, PolarisLoadBalancerProperties properties) {
|
|
|
|
super(config, rule, ping, serverList, null, new PollingServerListUpdater());
|
|
|
|
super(config, rule, ping, serverList, null, new PollingServerListUpdater());
|
|
|
|
this.routerAPI = routerAPI;
|
|
|
|
this.routerAPI = routerAPI;
|
|
|
|
this.consumerAPI = consumerAPI;
|
|
|
|
this.consumerAPI = consumerAPI;
|
|
|
|
|
|
|
|
this.polarisLoadBalancerProperties = properties;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public List<Server> getReachableServers() {
|
|
|
|
public List<Server> getReachableServers() {
|
|
|
|
List<Server> allServers = null;
|
|
|
|
ServiceInstances serviceInstances;
|
|
|
|
if (isFirstCall) {
|
|
|
|
if (polarisLoadBalancerProperties.getDiscoveryType().equals(ContextConstant.POLARIS)) {
|
|
|
|
allServers = super.getAllServers();
|
|
|
|
serviceInstances = getPolarisDiscoveryServiceInstances();
|
|
|
|
if (CollectionUtils.isEmpty(allServers)) {
|
|
|
|
|
|
|
|
return allServers;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (allServers.get(0) instanceof PolarisServer) {
|
|
|
|
|
|
|
|
isPolarisDiscovery = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
isPolarisDiscovery = false;
|
|
|
|
serviceInstances = getExtendDiscoveryServiceInstances();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
isFirstCall = false;
|
|
|
|
if (serviceInstances == null || CollectionUtils.isEmpty(serviceInstances.getInstances())) {
|
|
|
|
|
|
|
|
return Collections.emptyList();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ProcessRoutersRequest processRoutersRequest = new ProcessRoutersRequest();
|
|
|
|
|
|
|
|
processRoutersRequest.setDstInstances(serviceInstances);
|
|
|
|
|
|
|
|
String srcNamespace = MetadataContext.LOCAL_NAMESPACE;
|
|
|
|
|
|
|
|
String srcService = MetadataContext.LOCAL_SERVICE;
|
|
|
|
|
|
|
|
Map<String, String> transitiveCustomMetadata = MetadataContextHolder.get()
|
|
|
|
|
|
|
|
.getAllTransitiveCustomMetadata();
|
|
|
|
|
|
|
|
String method = MetadataContextHolder.get()
|
|
|
|
|
|
|
|
.getSystemMetadata(SystemMetadataKey.PEER_PATH);
|
|
|
|
|
|
|
|
processRoutersRequest.setMethod(method);
|
|
|
|
|
|
|
|
if (StringUtils.isNotBlank(srcNamespace) && StringUtils.isNotBlank(srcService)) {
|
|
|
|
|
|
|
|
ServiceInfo serviceInfo = new ServiceInfo();
|
|
|
|
|
|
|
|
serviceInfo.setNamespace(srcNamespace);
|
|
|
|
|
|
|
|
serviceInfo.setService(srcService);
|
|
|
|
|
|
|
|
serviceInfo.setMetadata(transitiveCustomMetadata);
|
|
|
|
|
|
|
|
processRoutersRequest.setSourceService(serviceInfo);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ProcessRoutersResponse processRoutersResponse = routerAPI
|
|
|
|
|
|
|
|
.processRouters(processRoutersRequest);
|
|
|
|
|
|
|
|
ServiceInstances filteredServiceInstances = processRoutersResponse
|
|
|
|
|
|
|
|
.getServiceInstances();
|
|
|
|
|
|
|
|
List<Server> filteredInstances = new ArrayList<>();
|
|
|
|
|
|
|
|
for (Instance instance : filteredServiceInstances.getInstances()) {
|
|
|
|
|
|
|
|
filteredInstances.add(new PolarisServer(serviceInstances, instance));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return filteredInstances;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ServiceInstances serviceInstances;
|
|
|
|
private ServiceInstances getPolarisDiscoveryServiceInstances() {
|
|
|
|
String serviceName = null;
|
|
|
|
String serviceName = MetadataContextHolder.get().getSystemMetadata(SystemMetadataKey.PEER_SERVICE);
|
|
|
|
if (isPolarisDiscovery) {
|
|
|
|
if (StringUtils.isBlank(serviceName)) {
|
|
|
|
// serviceName = ((PolarisServer)allServers.get(0)).getServiceInstances().getService();
|
|
|
|
List<Server> allServers = super.getAllServers();
|
|
|
|
serviceInstances = getAllInstances(MetadataContext.LOCAL_NAMESPACE,
|
|
|
|
if (CollectionUtils.isEmpty(allServers)) {
|
|
|
|
MetadataContextHolder.get().getSystemMetadata(SystemMetadataKey.PEER_SERVICE)).toServiceInstances();
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
serviceName = ((PolarisServer) super.getAllServers().get(0)).getServiceInstances().getService();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return getAllInstances(MetadataContext.LOCAL_NAMESPACE, serviceName).toServiceInstances();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private ServiceInstances getExtendDiscoveryServiceInstances() {
|
|
|
|
|
|
|
|
List<Server> allServers = super.getAllServers();
|
|
|
|
if (CollectionUtils.isEmpty(allServers)) {
|
|
|
|
if (CollectionUtils.isEmpty(allServers)) {
|
|
|
|
allServers = super.getAllServers();
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ServiceInstances serviceInstances;
|
|
|
|
|
|
|
|
String serviceName;
|
|
|
|
// notice the difference between different service registries
|
|
|
|
// notice the difference between different service registries
|
|
|
|
if (StringUtils.isNotBlank(
|
|
|
|
if (StringUtils.isNotBlank(
|
|
|
|
allServers.get(0).getMetaInfo().getServiceIdForDiscovery())) {
|
|
|
|
allServers.get(0).getMetaInfo().getServiceIdForDiscovery())) {
|
|
|
@ -127,32 +158,7 @@ public class PolarisLoadBalancer extends DynamicServerListLoadBalancer<Server> {
|
|
|
|
instances.add(instance);
|
|
|
|
instances.add(instance);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
serviceInstances = new DefaultServiceInstances(serviceKey, instances);
|
|
|
|
serviceInstances = new DefaultServiceInstances(serviceKey, instances);
|
|
|
|
}
|
|
|
|
return serviceInstances;
|
|
|
|
ProcessRoutersRequest processRoutersRequest = new ProcessRoutersRequest();
|
|
|
|
|
|
|
|
processRoutersRequest.setDstInstances(serviceInstances);
|
|
|
|
|
|
|
|
String srcNamespace = MetadataContext.LOCAL_NAMESPACE;
|
|
|
|
|
|
|
|
String srcService = MetadataContext.LOCAL_SERVICE;
|
|
|
|
|
|
|
|
Map<String, String> transitiveCustomMetadata = MetadataContextHolder.get()
|
|
|
|
|
|
|
|
.getAllTransitiveCustomMetadata();
|
|
|
|
|
|
|
|
String method = MetadataContextHolder.get()
|
|
|
|
|
|
|
|
.getSystemMetadata(SystemMetadataKey.PEER_PATH);
|
|
|
|
|
|
|
|
processRoutersRequest.setMethod(method);
|
|
|
|
|
|
|
|
if (StringUtils.isNotBlank(srcNamespace) && StringUtils.isNotBlank(srcService)) {
|
|
|
|
|
|
|
|
ServiceInfo serviceInfo = new ServiceInfo();
|
|
|
|
|
|
|
|
serviceInfo.setNamespace(srcNamespace);
|
|
|
|
|
|
|
|
serviceInfo.setService(srcService);
|
|
|
|
|
|
|
|
serviceInfo.setMetadata(transitiveCustomMetadata);
|
|
|
|
|
|
|
|
processRoutersRequest.setSourceService(serviceInfo);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ProcessRoutersResponse processRoutersResponse = routerAPI
|
|
|
|
|
|
|
|
.processRouters(processRoutersRequest);
|
|
|
|
|
|
|
|
ServiceInstances filteredServiceInstances = processRoutersResponse
|
|
|
|
|
|
|
|
.getServiceInstances();
|
|
|
|
|
|
|
|
List<Server> filteredInstances = new ArrayList<>();
|
|
|
|
|
|
|
|
for (Instance instance : filteredServiceInstances.getInstances()) {
|
|
|
|
|
|
|
|
filteredInstances.add(new PolarisServer(serviceInstances, instance));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return filteredInstances;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|