[转帖]重写Nacos服务发现逻辑动态修改远程服务IP地址

重写,nacos,服务,发现,逻辑,动态,修改,远程,ip地址 · 浏览次数 : 0

小编点评

## Nacos Discovery Client配置问题分析 此文章描述了 Nacos Discovery Client 配置中出现无法访问其他微服务的问题,并分析了问题原因。 **问题背景:** * 开发环境上使用了 K8S,所有微服务注册在 K8S 内虚拟 IP。 * 本机开发联调调用其他微服务,但无法访问。 **解决方案:** 1. 使用 **KT Connect** 工具进行 VPN 连接,可以解决跨集群网络连接问题。 2. 配置 **Ribbon** 的 `listOfServers` 属性,并将 IP 地址格式化为 ``. 3. 重写 `NacosNamingService` 的 `namingServiceInstance` 方法,手动设置远程服务注册 IP。 4. 在 `DevEnvironmentNacosDiscoveryProperties` 中设置远程服务注册 IP。 5. 使用 `DevEnvironmentNacosNamingService` 来实现跨集群服务 Discovery。 **问题分析:** * **KT Connect** 解决方案需要设置 VPN tunnel,可能会影响性能和安全性。 * **Ribbon** 配置方法简单易懂,但需要维护配置文件,并可能存在配置错误的问题。 * **手动设置 IP地址** 允许开发者更加精确地控制服务注册地址,但需要编写代码。 * **NacosNamingService` 的 `selectInstances` 方法默认从 `serverAddr` 属性中获取 IP地址,如果服务地址格式不正确,无法访问远程服务。 * **`DevEnvironmentNacosDiscoveryProperties` 中设置远程服务注册 IP,可以解决服务地址格式问题,但需要特殊处理 IP 地址格式的 service 的注册。 **总结:** 在 Nacos Discovery Client 配置中,设置远程服务注册 IP 需要考虑服务地址格式、 VPN 连接、配置复杂性和代码维护性。建议使用 **KT Connect** 工具进行 VPN 连接,并根据实际情况调整 **Ribbon** 或自定义 `NacosNamingService` 的配置方式。

正文

https://www.cnblogs.com/changxy-codest/p/14632574.html

 

背景

还是先说下做这个的背景,开发环境上了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;
        }
    }

}

与[转帖]重写Nacos服务发现逻辑动态修改远程服务IP地址相似的内容:

[转帖]重写Nacos服务发现逻辑动态修改远程服务IP地址

https://www.cnblogs.com/changxy-codest/p/14632574.html 背景 还是先说下做这个的背景,开发环境上了K8S,所有的微服务都注册在K8S内的Nacos,注册地址为K8S内部虚拟IP,K8S内的服务之间相互调用没有问题,但是本机开发联调调用其他微服务就

[转帖]Nginx:地址重写(return和rewrite)

https://www.cnblogs.com/testopsfeng/p/15294660.html Nginx的重写指令用于改变客户端的URL请求。主要有return和rewrite。两个指令都有重写URL的能力,但rewrite支持更复杂的功能。 Return指令 在server中返回 301

[转帖]Nginx Rewrite重写功能

目录 一、rewrite的概述1.1、概述1.2 跳转场景1.3 跳转实现1.4 Rewrite实际场景 二、常用的nginx正则表达式三、rewrite命令3.1 rewrite的语法格式3.2 fiag标记说明 四、location4.1 location大致分为三类4.2 location 常

[转帖]Nginx动静分离;资源分离;rewrite重写、跳转、伪静态、规则、日志

https://www.cnblogs.com/caodan01/p/14745562.html 一、动静分离 动静分离,通过中间件将动静请求和静态请求进行分离; 通过中间件将动态请求和静态请求分离,可以减少不必要的请求消耗,同时能减少请求的延时。 通过中间件将动态请求和静态请求分离,逻辑图如下:

[转帖]Nginx中的Rewrite的重定向配置与实践

https://www.cnblogs.com/tugenhua0707/p/10798762.html 阅读目录 一:理解地址重写 与 地址转发的含义。 二:理解 Rewrite指令 使用 三:理解if指令 四:理解防盗链及nginx配置 简介:Rewrite是Nginx服务器提供的一个重要的功能

[转帖]日更第7日: (翻)nginx调优之使用return代替rewrite做重定向

https://www.jianshu.com/p/26dc6c2b5f43 解释说明 NGINX中重写url的能力是一个非常强大和重要的特性,从技术角度讲return与rewrite均能实现。但使用return相对rewrite更简单和更快,因为计算RegEx会产生额外的系统开销。 Return指

[转帖]详解nginx的rewrite应用,Nginx高级之Rewrite规则

https://zhuanlan.zhihu.com/p/359801091 Rewrite主要的功能是实现URL重写,Nginx 的 Rewrite 规则采用 PCRE Perl 兼容正则表达式的语法进行规则匹配,如相使用 Nginx 的 Rewrite 功能,在编译 Nginx 前要编译安装 P

[转帖]nginx(三十二)rewrite模块

一 官方rewrite模块 ① 模块涉及的指令 ② 基本简介 rewrite模块会根据'PCRE正则'匹配'重写URI' pcre下载地址 pcretest测试正则表达式 ③ break 疑惑点: 结束'该作用域'下剩余的指令,还是'只是该rewrite模块的'指令? 1)配置demo 2)不带参数

[转帖]LVS负载均衡的三种方式

1.VS-NAT(基于网络地址转换,network address translation ,NAT) VS-NAT是LVS最基本的方法,如果想要设置一个用于测试的LVS,这是一个最简单的方法。 当客户发出请求,lvs负载均衡中的director会将接受到的包的目标地址重写为某个real-serve

【转帖】ARM 虚拟化技术简介

一. 虚拟化技术二. 虚拟化技术的比较 2.1 全虚拟化和二进制重写(Pure virtualization and binary rewriting) 2.2 半虚拟化( Para-virtualization) 2.3 虚拟化环境中的虚拟内存(Virtual memory in virtuali