|
|
|
@ -15,9 +15,10 @@
|
|
|
|
|
* specific language governing permissions and limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package com.tencent.cloud.polaris.router;
|
|
|
|
|
package com.tencent.cloud.polaris.loadbalancer;
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
@ -28,79 +29,59 @@ import com.netflix.loadbalancer.IRule;
|
|
|
|
|
import com.netflix.loadbalancer.PollingServerListUpdater;
|
|
|
|
|
import com.netflix.loadbalancer.Server;
|
|
|
|
|
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.metadata.MetadataContext;
|
|
|
|
|
import com.tencent.cloud.common.metadata.MetadataContextHolder;
|
|
|
|
|
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.pojo.DefaultInstance;
|
|
|
|
|
import com.tencent.polaris.api.pojo.DefaultServiceInstances;
|
|
|
|
|
import com.tencent.polaris.api.pojo.Instance;
|
|
|
|
|
import com.tencent.polaris.api.pojo.ServiceInfo;
|
|
|
|
|
import com.tencent.polaris.api.pojo.ServiceInstances;
|
|
|
|
|
import com.tencent.polaris.api.pojo.ServiceKey;
|
|
|
|
|
import com.tencent.polaris.api.rpc.GetAllInstancesRequest;
|
|
|
|
|
import com.tencent.polaris.api.rpc.InstancesResponse;
|
|
|
|
|
import com.tencent.polaris.router.api.core.RouterAPI;
|
|
|
|
|
import com.tencent.polaris.router.api.rpc.ProcessRoutersRequest;
|
|
|
|
|
import com.tencent.polaris.router.api.rpc.ProcessRoutersResponse;
|
|
|
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
|
|
|
|
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Routing load balancer of polaris.
|
|
|
|
|
*
|
|
|
|
|
* @author Haotian Zhang
|
|
|
|
|
*/
|
|
|
|
|
public class PolarisRoutingLoadBalancer extends DynamicServerListLoadBalancer<Server> {
|
|
|
|
|
public class PolarisLoadBalancer extends DynamicServerListLoadBalancer<Server> {
|
|
|
|
|
|
|
|
|
|
private final RouterAPI routerAPI;
|
|
|
|
|
|
|
|
|
|
public PolarisRoutingLoadBalancer(IClientConfig config, IRule rule, IPing ping,
|
|
|
|
|
ServerList<Server> serverList, RouterAPI routerAPI) {
|
|
|
|
|
private ConsumerAPI consumerAPI;
|
|
|
|
|
|
|
|
|
|
private PolarisLoadBalancerProperties polarisLoadBalancerProperties;
|
|
|
|
|
|
|
|
|
|
public PolarisLoadBalancer(IClientConfig config, IRule rule, IPing ping, ServerList<Server> serverList,
|
|
|
|
|
RouterAPI routerAPI, ConsumerAPI consumerAPI, PolarisLoadBalancerProperties properties) {
|
|
|
|
|
super(config, rule, ping, serverList, null, new PollingServerListUpdater());
|
|
|
|
|
this.routerAPI = routerAPI;
|
|
|
|
|
this.consumerAPI = consumerAPI;
|
|
|
|
|
this.polarisLoadBalancerProperties = properties;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<Server> getReachableServers() {
|
|
|
|
|
List<Server> allServers = super.getAllServers();
|
|
|
|
|
if (CollectionUtils.isEmpty(allServers)) {
|
|
|
|
|
return allServers;
|
|
|
|
|
}
|
|
|
|
|
ServiceInstances serviceInstances = null;
|
|
|
|
|
if (allServers.get(0) instanceof PolarisServer) {
|
|
|
|
|
serviceInstances = ((PolarisServer) allServers.get(0)).getServiceInstances();
|
|
|
|
|
ServiceInstances serviceInstances;
|
|
|
|
|
if (polarisLoadBalancerProperties.getDiscoveryType().equals(ContextConstant.POLARIS)) {
|
|
|
|
|
serviceInstances = getPolarisDiscoveryServiceInstances();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
String serviceName;
|
|
|
|
|
// notice the difference between different service registries
|
|
|
|
|
if (StringUtils.isNotBlank(
|
|
|
|
|
allServers.get(0).getMetaInfo().getServiceIdForDiscovery())) {
|
|
|
|
|
serviceName = allServers.get(0).getMetaInfo().getServiceIdForDiscovery();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
serviceName = allServers.get(0).getMetaInfo().getAppName();
|
|
|
|
|
}
|
|
|
|
|
if (StringUtils.isBlank(serviceName)) {
|
|
|
|
|
throw new IllegalStateException(
|
|
|
|
|
"PolarisRoutingLoadBalancer only Server with AppName or ServiceIdForDiscovery attribute");
|
|
|
|
|
}
|
|
|
|
|
ServiceKey serviceKey = new ServiceKey(MetadataContext.LOCAL_NAMESPACE,
|
|
|
|
|
serviceName);
|
|
|
|
|
List<Instance> instances = new ArrayList<>(8);
|
|
|
|
|
for (Server server : allServers) {
|
|
|
|
|
DefaultInstance instance = new DefaultInstance();
|
|
|
|
|
instance.setNamespace(MetadataContext.LOCAL_NAMESPACE);
|
|
|
|
|
instance.setService(serviceName);
|
|
|
|
|
instance.setHealthy(server.isAlive());
|
|
|
|
|
instance.setProtocol(server.getScheme());
|
|
|
|
|
instance.setId(server.getId());
|
|
|
|
|
instance.setHost(server.getHost());
|
|
|
|
|
instance.setPort(server.getPort());
|
|
|
|
|
instance.setZone(server.getZone());
|
|
|
|
|
instance.setWeight(100);
|
|
|
|
|
instances.add(instance);
|
|
|
|
|
}
|
|
|
|
|
serviceInstances = new DefaultServiceInstances(serviceKey, instances);
|
|
|
|
|
serviceInstances = getExtendDiscoveryServiceInstances();
|
|
|
|
|
}
|
|
|
|
|
if (serviceInstances == null || CollectionUtils.isEmpty(serviceInstances.getInstances())) {
|
|
|
|
|
return Collections.emptyList();
|
|
|
|
|
}
|
|
|
|
|
ProcessRoutersRequest processRoutersRequest = new ProcessRoutersRequest();
|
|
|
|
|
processRoutersRequest.setDstInstances(serviceInstances);
|
|
|
|
@ -129,9 +110,73 @@ public class PolarisRoutingLoadBalancer extends DynamicServerListLoadBalancer<Se
|
|
|
|
|
return filteredInstances;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ServiceInstances getPolarisDiscoveryServiceInstances() {
|
|
|
|
|
String serviceName = MetadataContextHolder.get().getSystemMetadata(SystemMetadataKey.PEER_SERVICE);
|
|
|
|
|
if (StringUtils.isBlank(serviceName)) {
|
|
|
|
|
List<Server> allServers = super.getAllServers();
|
|
|
|
|
if (CollectionUtils.isEmpty(allServers)) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
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)) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
ServiceInstances serviceInstances;
|
|
|
|
|
String serviceName;
|
|
|
|
|
// notice the difference between different service registries
|
|
|
|
|
if (StringUtils.isNotBlank(
|
|
|
|
|
allServers.get(0).getMetaInfo().getServiceIdForDiscovery())) {
|
|
|
|
|
serviceName = allServers.get(0).getMetaInfo().getServiceIdForDiscovery();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
serviceName = allServers.get(0).getMetaInfo().getAppName();
|
|
|
|
|
}
|
|
|
|
|
if (StringUtils.isBlank(serviceName)) {
|
|
|
|
|
throw new IllegalStateException(
|
|
|
|
|
"PolarisLoadBalancer only Server with AppName or ServiceIdForDiscovery attribute");
|
|
|
|
|
}
|
|
|
|
|
ServiceKey serviceKey = new ServiceKey(MetadataContext.LOCAL_NAMESPACE,
|
|
|
|
|
serviceName);
|
|
|
|
|
List<Instance> instances = new ArrayList<>(8);
|
|
|
|
|
for (Server server : allServers) {
|
|
|
|
|
DefaultInstance instance = new DefaultInstance();
|
|
|
|
|
instance.setNamespace(MetadataContext.LOCAL_NAMESPACE);
|
|
|
|
|
instance.setService(serviceName);
|
|
|
|
|
instance.setHealthy(server.isAlive());
|
|
|
|
|
instance.setProtocol(server.getScheme());
|
|
|
|
|
instance.setId(server.getId());
|
|
|
|
|
instance.setHost(server.getHost());
|
|
|
|
|
instance.setPort(server.getPort());
|
|
|
|
|
instance.setZone(server.getZone());
|
|
|
|
|
instance.setWeight(100);
|
|
|
|
|
instances.add(instance);
|
|
|
|
|
}
|
|
|
|
|
serviceInstances = new DefaultServiceInstances(serviceKey, instances);
|
|
|
|
|
return serviceInstances;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<Server> getAllServers() {
|
|
|
|
|
return getReachableServers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get a list of instances.
|
|
|
|
|
* @param namespace namespace
|
|
|
|
|
* @param serviceName service name
|
|
|
|
|
* @return list of instances
|
|
|
|
|
*/
|
|
|
|
|
public InstancesResponse getAllInstances(String namespace, String serviceName) {
|
|
|
|
|
GetAllInstancesRequest request = new GetAllInstancesRequest();
|
|
|
|
|
request.setNamespace(namespace);
|
|
|
|
|
request.setService(serviceName);
|
|
|
|
|
return consumerAPI.getAllInstance(request);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|