zoukankan      html  css  js  c++  java
  • 重写Nacos服务发现逻辑动态修改远程服务IP地址

    背景

    还是先说下做这个的背景,开发环境上了K8S,所有的微服务都注册在K8S内的Nacos,注册地址为K8S内部虚拟IP,K8S内的服务之间相互调用没有问题,但是本机开发联调调用其他微服务就访问不到。

    解决方案

    1、KT Connect,可以理解为一个VPN工具,可以和K8S网络联通,缺点是配置繁琐,每次开发都需要启动KT Connect程序;

    2、配置Ribbon的listOfServers,配置如下:

    <nacosServiceName>.ribbon.listOfServers=<ip:port>

    3、Nacos Client从Nacos Server获取服务列表时,修改远程服务对应的IP地址。

    重写NacosNamingService

    1、看了下nacos-client源码,发现有个NacosNamingService类,主要是服务发现的实现类,可以从这里入手修改远程服务注册IP;

    2、NacosNamingService是在NacosDiscoveryClientAutoConfiguration通过注入NacosDiscoveryProperties初始化的,具体源码如下:

    @Bean
    @ConditionalOnMissingBean
    public NacosDiscoveryProperties nacosProperties() {
        return new NacosDiscoveryProperties();
    }

    3、跟踪到NacosDiscoveryProperties,初始化NacosNamingService的核心代码如下:

        public NamingService namingServiceInstance() {
            if (null != this.namingService) {
                return this.namingService;
            } else {
                Properties properties = new Properties();
                properties.put("serverAddr", this.serverAddr);
                properties.put("namespace", this.namespace);
                properties.put("com.alibaba.nacos.naming.log.filename", this.logName);
                if (this.endpoint.contains(":")) {
                    int index = this.endpoint.indexOf(":");
                    properties.put("endpoint", this.endpoint.substring(0, index));
                    properties.put("endpointPort", this.endpoint.substring(index + 1));
                } else {
                    properties.put("endpoint", this.endpoint);
                }
    
                properties.put("accessKey", this.accessKey);
                properties.put("secretKey", this.secretKey);
                properties.put("clusterName", this.clusterName);
                properties.put("namingLoadCacheAtStart", this.namingLoadCacheAtStart);
    
                try {
                    this.namingService = NacosFactory.createNamingService(properties);
                } catch (Exception var3) {
                    log.error("create naming service error!properties={},e=,", this, var3);
                    return null;
                }
    
                return this.namingService;
            }
        }

    4、我们直接重新namingServiceInstance方法就可以了,具体实现代码如下:

    @Slf4j
    @Configuration
    @ConditionalOnNacosDiscoveryEnabled
    @ConditionalOnProperty(
            name = {"spring.profiles.active"},
            havingValue = "dev"
    )
    @AutoConfigureBefore({NacosDiscoveryClientAutoConfiguration.class})
    public class DevEnvironmentNacosDiscoveryClient {
    
        @Bean
        @ConditionalOnMissingBean
        public NacosDiscoveryProperties nacosProperties() {
            return new DevEnvironmentNacosDiscoveryProperties();
        }
    
        static class DevEnvironmentNacosDiscoveryProperties extends NacosDiscoveryProperties {
    
            private NamingService namingService;
    
            @Override
            public NamingService namingServiceInstance() {
                if (null != this.namingService) {
                    return this.namingService;
                } else {
                    Properties properties = new Properties();
                    properties.put("serverAddr", super.getServerAddr());
                    properties.put("namespace", super.getNamespace());
                    properties.put("com.alibaba.nacos.naming.log.filename", super.getLogName());
                    if (super.getEndpoint().contains(":")) {
                        int index = super.getEndpoint().indexOf(":");
                        properties.put("endpoint", super.getEndpoint().substring(0, index));
                        properties.put("endpointPort", super.getEndpoint().substring(index + 1));
                    } else {
                        properties.put("endpoint", super.getEndpoint());
                    }
    
                    properties.put("accessKey", super.getAccessKey());
                    properties.put("secretKey", super.getSecretKey());
                    properties.put("clusterName", super.getClusterName());
                    properties.put("namingLoadCacheAtStart", super.getNamingLoadCacheAtStart());
    
                    try {
                        this.namingService = new DevEnvironmentNacosNamingService(properties);
                    } catch (Exception var3) {
                        log.error("create naming service error!properties={},e=,", this, var3);
                        return null;
                    }
    
                    return this.namingService;
                }
            }
    
        }
    
        static class DevEnvironmentNacosNamingService extends NacosNamingService {
    
            public DevEnvironmentNacosNamingService(Properties properties) {
                super(properties);
            }
    
            @Override
            public List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy) throws NacosException {
                List<Instance> instances = super.selectInstances(serviceName, clusters, healthy);
                instances.stream().forEach(instance -> instance.setIp("10.101.232.24"));
                return instances;
            }
        }
    
    }

  • 相关阅读:
    Linux-Bond-Configure
    Kvm学习文档记录
    Can't locate Log/Dispatch.pm in @INC
    sas2ircu工具信息收集及磁盘定位
    python 之tornado 入门
    zabbix 监控 tomcat jmx
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
  • 原文地址:https://www.cnblogs.com/changxy-codest/p/14632574.html
Copyright © 2011-2022 走看看