Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add NacosServiceInstanceConverter util #3686

Open
wants to merge 2 commits into
base: 2023.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,76 +22,69 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;


import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.cloud.nacos.NacosServiceInstance;
import com.alibaba.cloud.nacos.loadbalancer.NacosLoadBalancer;
import com.alibaba.cloud.nacos.util.NacosServiceInstanceConverter;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.client.naming.core.Balancer;

import org.springframework.cloud.client.ServiceInstance;


/**
* @author itmuch.com XuDaojie
* @since 2021.1
*/
public class NacosBalancer extends Balancer {

private static final String IPV4_REGEX = "((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}";
private static final String IPV4_REGEX = "((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}";

private static final String IPV6_KEY = "IPv6";
private static final String IPV6_KEY = "IPv6";

/**
* Choose instance by weight.
* @param instances Instance List
* @return the chosen instance
*/
public static Instance getHostByRandomWeight2(List<Instance> instances) {
return getHostByRandomWeight(instances);
}

/**
* Spring Cloud LoadBalancer Choose instance by weight.
* @param serviceInstances Instance List
* @return the chosen instance
*/
public static ServiceInstance getHostByRandomWeight3(
List<ServiceInstance> serviceInstances) {
Map<Instance, ServiceInstance> instanceMap = new HashMap<>();
List<Instance> nacosInstance = serviceInstances.stream().map(serviceInstance -> {
Map<String, String> metadata = serviceInstance.getMetadata();
/**
* Choose instance by weight.
*
* @param instances Instance List
* @return the chosen instance
*/
public static Instance getHostByRandomWeight2(List<Instance> instances) {
return getHostByRandomWeight(instances);
}

// see
// com.alibaba.cloud.nacos.discovery.NacosServiceDiscovery.hostToServiceInstance()
Instance instance = new Instance();
instance.setIp(serviceInstance.getHost());
instance.setPort(serviceInstance.getPort());
instance.setWeight(Double.parseDouble(metadata.get("nacos.weight")));
instance.setHealthy(Boolean.parseBoolean(metadata.get("nacos.healthy")));
instanceMap.put(instance, serviceInstance);
return instance;
}).collect(Collectors.toList());
/**
* Spring Cloud LoadBalancer Choose instance by weight.
*
* @param serviceInstances Instance List
* @return the chosen instance
*/
public static ServiceInstance getHostByRandomWeight3(List<ServiceInstance> serviceInstances) {
Map<Instance, ServiceInstance> instanceMap = new HashMap<>();
List<Instance> nacosInstance = serviceInstances.stream().map(serviceInstance -> {
Instance instance = NacosServiceInstanceConverter.fromServiceInstance(serviceInstance);
instanceMap.put(instance, serviceInstance);
return instance;
}).collect(Collectors.toList());

Instance instance = getHostByRandomWeight2(nacosInstance);
NacosServiceInstance nacosServiceInstance = (NacosServiceInstance) instanceMap.get(instance);
// When local support IPv6 address stack, referred to use IPv6 address.
if (StringUtils.isNotEmpty(NacosLoadBalancer.ipv6)) {
convertIPv4ToIPv6(nacosServiceInstance);
Instance instance = getHostByRandomWeight2(nacosInstance);
NacosServiceInstance nacosServiceInstance = (NacosServiceInstance) instanceMap.get(instance);
// When local support IPv6 address stack, referred to use IPv6 address.
if (StringUtils.isNotEmpty(NacosLoadBalancer.ipv6)) {
convertIPv4ToIPv6(nacosServiceInstance);
}
return nacosServiceInstance;
}
return nacosServiceInstance;
}

/**
* There is two type Ip,using IPv6 should use IPv6 in metadata to replace IPv4 in IP
* field.
*/
private static void convertIPv4ToIPv6(NacosServiceInstance instance) {
if (Pattern.matches(IPV4_REGEX, instance.getHost())) {
String ip = instance.getMetadata().get(IPV6_KEY);
if (StringUtils.isNotEmpty(ip)) {
instance.setHost(ip);
}
/**
* There is two type Ip,using IPv6 should use IPv6 in metadata to replace IPv4 in IP field.
*/
private static void convertIPv4ToIPv6(NacosServiceInstance instance) {
if (Pattern.matches(IPV4_REGEX, instance.getHost())) {
String ip = instance.getMetadata().get(IPV6_KEY);
if (StringUtils.isNotEmpty(ip)) {
instance.setHost(ip);
}
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,104 +17,70 @@
package com.alibaba.cloud.nacos.discovery;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.NacosServiceInstance;
import com.alibaba.cloud.nacos.NacosServiceManager;
import com.alibaba.cloud.nacos.util.NacosServiceInstanceConverter;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView;

import org.springframework.cloud.client.ServiceInstance;

/**
* @author <a href="mailto:[email protected]">echooymxq</a>
* @author changjin wei(魏昌进)
**/
public class NacosServiceDiscovery {

private NacosDiscoveryProperties discoveryProperties;

private NacosServiceManager nacosServiceManager;

public NacosServiceDiscovery(NacosDiscoveryProperties discoveryProperties,
NacosServiceManager nacosServiceManager) {
this.discoveryProperties = discoveryProperties;
this.nacosServiceManager = nacosServiceManager;
}
private NacosDiscoveryProperties discoveryProperties;

/**
* Return all instances for the given service.
* @param serviceId id of service
* @return list of instances
* @throws NacosException nacosException
*/
public List<ServiceInstance> getInstances(String serviceId) throws NacosException {
String group = discoveryProperties.getGroup();
List<Instance> instances = namingService().selectInstances(serviceId, group,
true);
return hostToServiceInstanceList(instances, serviceId);
}
private NacosServiceManager nacosServiceManager;

/**
* Return the names of all services.
* @return list of service names
* @throws NacosException nacosException
*/
public List<String> getServices() throws NacosException {
String group = discoveryProperties.getGroup();
ListView<String> services = namingService().getServicesOfServer(1,
Integer.MAX_VALUE, group);
return services.getData();
}

public static List<ServiceInstance> hostToServiceInstanceList(
List<Instance> instances, String serviceId) {
List<ServiceInstance> result = new ArrayList<>(instances.size());
for (Instance instance : instances) {
ServiceInstance serviceInstance = hostToServiceInstance(instance, serviceId);
if (serviceInstance != null) {
result.add(serviceInstance);
}
public NacosServiceDiscovery(NacosDiscoveryProperties discoveryProperties, NacosServiceManager nacosServiceManager) {
this.discoveryProperties = discoveryProperties;
this.nacosServiceManager = nacosServiceManager;
}
return result;
}

public static ServiceInstance hostToServiceInstance(Instance instance,
String serviceId) {
if (instance == null || !instance.isEnabled() || !instance.isHealthy()) {
return null;
/**
* Return all instances for the given service.
*
* @param serviceId id of service
* @return list of instances
* @throws NacosException nacosException
*/
public List<ServiceInstance> getInstances(String serviceId) throws NacosException {
String group = discoveryProperties.getGroup();
List<Instance> instances = namingService().selectInstances(serviceId, group, true);
return hostToServiceInstanceList(instances, serviceId);
}
NacosServiceInstance nacosServiceInstance = new NacosServiceInstance();
nacosServiceInstance.setHost(instance.getIp());
nacosServiceInstance.setPort(instance.getPort());
nacosServiceInstance.setServiceId(serviceId);
nacosServiceInstance.setInstanceId(instance.getInstanceId());

Map<String, String> metadata = new HashMap<>();
metadata.put("nacos.instanceId", instance.getInstanceId());
metadata.put("nacos.weight", instance.getWeight() + "");
metadata.put("nacos.healthy", instance.isHealthy() + "");
metadata.put("nacos.cluster", instance.getClusterName() + "");
if (instance.getMetadata() != null) {
metadata.putAll(instance.getMetadata());
/**
* Return the names of all services.
*
* @return list of service names
* @throws NacosException nacosException
*/
public List<String> getServices() throws NacosException {
String group = discoveryProperties.getGroup();
ListView<String> services = namingService().getServicesOfServer(1, Integer.MAX_VALUE, group);
return services.getData();
}
metadata.put("nacos.ephemeral", String.valueOf(instance.isEphemeral()));
nacosServiceInstance.setMetadata(metadata);

if (metadata.containsKey("secure")) {
boolean secure = Boolean.parseBoolean(metadata.get("secure"));
nacosServiceInstance.setSecure(secure);
public static List<ServiceInstance> hostToServiceInstanceList(List<Instance> instances, String serviceId) {
List<ServiceInstance> result = new ArrayList<>(instances.size());
for (Instance instance : instances) {
ServiceInstance serviceInstance = NacosServiceInstanceConverter.fromInstanceAndServiceId(instance, serviceId);
if (serviceInstance != null) {
result.add(serviceInstance);
}
}
return result;
}
return nacosServiceInstance;
}

private NamingService namingService() {
return nacosServiceManager.getNamingService();
}
private NamingService namingService() {
return nacosServiceManager.getNamingService();
}

}
Loading
Loading