赞
踩
Nacos具备微服务注册和发现,以及配置管理的功能,本文详情描述【注册和发现】的原理,以及基本使用,包括如何进行跨group注册和发现。
一、Nacos配置
- spring:
- cloud:
- nacos:
- discovery:
- server-addr: nacosIP地址:8849
- namespace: dev
- group: Product
- config:
- server-addr: nacosIP地址:8849
- namespace: dev
- group: Product
- file-extension: yaml
- refresh-enabled: true
- enable-remote-sync-config: true
- name: product.yaml
spring: cloud: nacos: discovery: server-addr: nacosIP地址:8849 namespace: dev group: Order config: server-addr: nacosIP地址:8849 namespace: dev group: Order file-extension: yaml refresh-enabled: true enable-remote-sync-config: true name: order.yaml extension-configs: - data-id: config-global.yaml group: Order refresh: true
一、NacosServiceDiscovery 中 getInstances 获取注册在nacos上的服务实例清单
- public List<ServiceInstance> getInstances(String serviceId) throws NacosException {
- String group = this.discoveryProperties.getGroup();
- List<Instance> instances = this.namingService().selectInstances(serviceId, group, true);
- return hostToServiceInstanceList(instances, serviceId);
- }
但是原始功能不支持跨group服务发现,所以我们需要重写 getInstances方法。
二、NacosServiceDiscoveryV2 继承 NacosServiceDiscovery,并重写 getInstances
- import com.alibaba.cloud.nacos.NacosServiceInstance;
- import com.alibaba.cloud.nacos.NacosServiceManager;
- import com.alibaba.cloud.nacos.discovery.NacosServiceDiscovery;
- 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 com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
- import org.springframework.cloud.client.ServiceInstance;
-
- import java.util.*;
-
- import static com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty;
- import static java.util.Objects.isNull;
-
- /**
- * @description: naocs服务发现重写
- */
- public class NacosServiceDiscoveryV2 extends NacosServiceDiscovery {
-
- private final NacosDiscoveryPropertiesV2 discoveryProperties;
-
- private final NacosShareProperties nacosShareProperties;
-
- private final NacosServiceManager nacosServiceManager;
-
- public NacosServiceDiscoveryV2(NacosDiscoveryPropertiesV2 discoveryProperties, NacosShareProperties nacosShareProperties, NacosServiceManager nacosServiceManager) {
- super(discoveryProperties, nacosServiceManager);
- this.discoveryProperties = discoveryProperties;
- this.nacosShareProperties = nacosShareProperties;
- this.nacosServiceManager = nacosServiceManager;
- }
-
- /**
- * Return all instances for the given service.
- * @param serviceId id of service
- * @return list of instances
- * @throws NacosException nacosException
- */
- @Override
- public List<ServiceInstance> getInstances(String serviceId) throws NacosException {
- String group = discoveryProperties.getGroup();
- List<Instance> instances = discoveryProperties.namingServiceInstance()
- .selectInstances(serviceId, group, true);
- if (isEmpty(instances)) {
- Map<String, Set<String>> namespaceGroupMap = nacosShareProperties.getNamespaceGroupMap();
- Map<String, NamingService> namespace2NamingServiceMap = discoveryProperties.shareNamingServiceInstances();
- for (Map.Entry<String, NamingService> entry : namespace2NamingServiceMap.entrySet()) {
- String namespace;
- NamingService namingService;
- if (isNull(namespace = entry.getKey()) || isNull(namingService = entry.getValue()))
- continue;
- Set<String> groupNames = namespaceGroupMap.get(namespace);
- List<Instance> shareInstances;
- if (isEmpty(groupNames)) {
- shareInstances = namingService.selectInstances(serviceId, group, true);
- if (CollectionUtils.isNotEmpty(shareInstances))
- break;
- } else {
- shareInstances = new ArrayList<>();
- for (String groupName : groupNames) {
- List<Instance> subShareInstances = namingService.selectInstances(serviceId, groupName, true);
- if (CollectionUtils.isNotEmpty(subShareInstances)) {
- shareInstances.addAll(subShareInstances);
- }
- }
- }
- if (CollectionUtils.isNotEmpty(shareInstances)) {
- instances = shareInstances;
- break;
- }
- }
- }
- return hostToServiceInstanceList(instances, serviceId);
- }
-
- /**
- * 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 = discoveryProperties.namingServiceInstance()
- .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);
- }
- }
- return result;
- }
-
- public static ServiceInstance hostToServiceInstance(Instance instance,
- String serviceId) {
- if (instance == null || !instance.isEnabled() || !instance.isHealthy()) {
- return null;
- }
- NacosServiceInstance nacosServiceInstance = new NacosServiceInstance();
- nacosServiceInstance.setHost(instance.getIp());
- nacosServiceInstance.setPort(instance.getPort());
- nacosServiceInstance.setServiceId(serviceId);
-
- 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() + "");
- metadata.putAll(instance.getMetadata());
- nacosServiceInstance.setMetadata(metadata);
-
- if (metadata.containsKey("secure")) {
- boolean secure = Boolean.parseBoolean(metadata.get("secure"));
- nacosServiceInstance.setSecure(secure);
- }
- return nacosServiceInstance;
- }
-
- private NamingService namingService() {
- return nacosServiceManager
- .getNamingService(discoveryProperties.getNacosProperties());
- }
- }
原理:
1、根据 serviceId 和 group 获取当前实例
2、获取所有group清单,并根据group找到group下所有实例
3、将group清单,加入到自己的实例清单中。
三、NacosDiscoveryPropertiesV2 继承 NacosDiscoveryProperties,服务发现属性重写 shareNamingServiceInstances、getNacosProperties方法
- import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
- import com.alibaba.nacos.api.NacosFactory;
- import com.alibaba.nacos.api.naming.NamingService;
- import com.alibaba.nacos.client.naming.utils.UtilAndComs;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
-
- import java.util.*;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.function.Function;
- import java.util.function.Predicate;
-
- import static com.alibaba.nacos.api.PropertyKeyConst.*;
- import static java.util.Objects.nonNull;
-
- /**
- * @description: naocs服务发现属性重写
- */
- public class NacosDiscoveryPropertiesV2 extends NacosDiscoveryProperties {
-
- private static final Logger log = LoggerFactory.getLogger(NacosDiscoveryPropertiesV2.class);
-
- private final NacosShareProperties nacosShareProperties;
-
- private static final Map<String, NamingService> NAMESPACE_TO_NAMING_SERVICE_MAP = new ConcurrentHashMap<>();
-
- public NacosDiscoveryPropertiesV2(NacosShareProperties nacosShareProperties) {
- super();
- this.nacosShareProperties = nacosShareProperties;
- }
-
- public Map<String, NamingService> shareNamingServiceInstances() {
- if (!NAMESPACE_TO_NAMING_SERVICE_MAP.isEmpty()) {
- return new HashMap<>(NAMESPACE_TO_NAMING_SERVICE_MAP);
- }
- List<NacosShareProperties.NacosShareEntity> entities = Optional.ofNullable(nacosShareProperties)
- .map(NacosShareProperties::getEntities).orElse(Collections.emptyList());
- entities.stream().filter(entity -> nonNull(entity) && nonNull(entity.getNamespace()))
- .filter(distinctByKey(NacosShareProperties.NacosShareEntity::getNamespace))
- .forEach(entity -> {
- try {
- NamingService namingService = NacosFactory.createNamingService(getNacosProperties(entity.getNamespace()));
- if (namingService != null) {
- NAMESPACE_TO_NAMING_SERVICE_MAP.put(entity.getNamespace(), namingService);
- }
- } catch (Exception e) {
- log.error("create naming service error! properties={}, e=", this, e);
- }
- });
- return new HashMap<>(NAMESPACE_TO_NAMING_SERVICE_MAP);
- }
- private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
- Map<Object, Boolean> seen = new ConcurrentHashMap<>();
- return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
- }
-
- private Properties getNacosProperties(String namespace) {
- Properties properties = new Properties();
- properties.put(SERVER_ADDR, getServerAddr());
- properties.put(USERNAME, Objects.toString(getUsername(), ""));
- properties.put(PASSWORD, Objects.toString(getPassword(), ""));
- properties.put(NAMESPACE, namespace);
- properties.put(UtilAndComs.NACOS_NAMING_LOG_NAME, getLogName());
- String endpoint = getEndpoint();
- if (endpoint.contains(":")) {
- int index = endpoint.indexOf(":");
- properties.put(ENDPOINT, endpoint.substring(0, index));
- properties.put(ENDPOINT_PORT, endpoint.substring(index + 1));
- }
- else {
- properties.put(ENDPOINT, endpoint);
- }
-
- properties.put(ACCESS_KEY, getAccessKey());
- properties.put(SECRET_KEY, getSecretKey());
- properties.put(CLUSTER_NAME, getClusterName());
- properties.put(NAMING_LOAD_CACHE_AT_START, getNamingLoadCacheAtStart());
-
- // enrichNacosDiscoveryProperties(properties);
- return properties;
- }
- }
四、共享share属性类 NacosShareProperties
- import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.context.annotation.Configuration;
-
- import java.util.*;
- import java.util.concurrent.ConcurrentHashMap;
-
- import static java.util.Objects.nonNull;
-
- /**
- * <pre>
- * @description: 共享nacos属性
- * </pre>
- */
- @Configuration
- @ConfigurationProperties(prefix = "nacos.share")
- public class NacosShareProperties {
-
- private final Map<String, Set<String>> NAMESPACE_TO_GROUP_NAME_MAP = new ConcurrentHashMap<>();
-
- /**
- * 共享nacos实体列表
- */
- private List<NacosShareEntity> entities;
-
- public List<NacosShareEntity> getEntities() {
- return entities;
- }
-
- public void setEntities(List<NacosShareEntity> entities) {
- this.entities = entities;
- }
-
- public Map<String, Set<String>> getNamespaceGroupMap() {
- if (CollectionUtils.isEmpty(entities)) {
- return new HashMap<>();
- }
- entities.stream().filter(entity -> nonNull(entity) && nonNull(entity.getNamespace()))
- .forEach(entity -> {
- Set<String> groupNames = NAMESPACE_TO_GROUP_NAME_MAP.computeIfAbsent(entity.getNamespace(), k -> new HashSet<>());
- if (nonNull(entity.getGroupNames()))
- groupNames.addAll(entity.getGroupNames());
- });
- return new HashMap<>(NAMESPACE_TO_GROUP_NAME_MAP);
- }
-
- @Override
- public String toString() {
- return "NacosShareProperties{" +
- "entities=" + entities +
- '}';
- }
-
- /**
- * 共享nacos实体
- */
- public static final class NacosShareEntity {
-
- /**
- * 命名空间
- */
- private String namespace;
-
- /**
- * 分组
- */
- private List<String> groupNames;
-
- public String getNamespace() {
- return namespace;
- }
-
- public void setNamespace(String namespace) {
- this.namespace = namespace;
- }
-
- public List<String> getGroupNames() {
- return groupNames;
- }
-
- public void setGroupNames(List<String> groupNames) {
- this.groupNames = groupNames;
- }
-
- @Override
- public String toString() {
- return "NacosShareEntity{" +
- "namespace='" + namespace + '\'' +
- ", groupNames=" + groupNames +
- '}';
- }
- }
- }
五、整合配置类 NacosDiscoveryAutoConfigurationV2
- import com.alibaba.cloud.nacos.ConditionalOnNacosDiscoveryEnabled;
- import com.alibaba.cloud.nacos.NacosServiceManager;
- import com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration;
- import com.alibaba.cloud.nacos.discovery.NacosServiceDiscovery;
- import org.springframework.boot.autoconfigure.AutoConfigureBefore;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
- import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- /**
- * @Auther: yangjian
- */
- @Configuration(proxyBeanMethods = false)
- @ConditionalOnDiscoveryEnabled
- @ConditionalOnNacosDiscoveryEnabled
- @AutoConfigureBefore({NacosDiscoveryAutoConfiguration.class})
- public class NacosDiscoveryAutoConfigurationV2 {
- @Bean
- @ConditionalOnMissingBean
- public NacosDiscoveryPropertiesV2 nacosProperties(NacosShareProperties nacosShareProperties) {
- return new NacosDiscoveryPropertiesV2(nacosShareProperties);
- }
-
- @Bean
- @ConditionalOnMissingBean
- public NacosServiceDiscovery nacosServiceDiscovery(NacosDiscoveryPropertiesV2 discoveryPropertiesV2
- , NacosShareProperties nacosShareProperties, NacosServiceManager nacosServiceManager) {
- return new NacosServiceDiscoveryV2(discoveryPropertiesV2, nacosShareProperties, nacosServiceManager);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。