[转帖]记一次使用nacos2踩到的坑

一次,使用,nacos2,踩到 · 浏览次数 : 0

小编点评

**问题分析** 朋友在使用Nacos2.1.1时,启动多个Nacos服务器后,发现端口被占用,导致服务无法正常启动。 **解决方案** 1. **调整Nacos服务器端口** 由于grpc端口的生成方式由主端口+1000、主端口+1001生成,可以尝试设置不同的端口,例如7777、8888、9999等。例如: ```properties spring.cloud.nacos.discovery.server-addr=127.0.0.1:7777 ``` 2. **设置grpc端口** 在grpc连接设置中设置grpc端口,例如: ```java grpc.setServerPort(8848); ``` 3. **设置grpc端口偏移量** 根据Nacos2版本,grpc端口通常为主端口+1000,可以使用以下代码获取并设置端口偏移量: ```java String grpcPortOffset = System.getProperty("nacos.server.grpc.port.offset", "1000"); ``` 4. **使用HTTP代理** 由于Nacos2支持HTTP代理,可以使用HTTP代理将服务端地址映射到Nacos服务器的地址上。例如: ```properties spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 ``` 5. **使用低版本Nacos客户端** 由于朋友使用的是最新版本Nacos2,可能存在一些与grpc版本相关的兼容性问题。在这种情况下,可以使用低版本Nacos客户端进行连接,例如: ```java NacosClient nacosClient = Nacos.builder() .registerWithZooKeeper("localhost:2181") .build(); // 连接到Nacos服务器 ClientResponse response = nacosClient.getServer(serverAddress); ``` **附录** * 官方文档关于Nacos2的版本兼容性:https://nacos.io/zh-cn/docs/2.0.0-compatibility.html * Nacos2的代码示例,包含多个解决方案: * 代码库:github.com/baidu/nacos-spring-boot-starter/tree/master/src/main/java/com/baidu/nacos/spring/boot/starter * 文档:nacos.io/zh-cn/docs/2.0.0-compatibility.html

正文

https://cloud.tencent.com/developer/article/2077110?areaSource=104001.26&traceId=7WZNP412yK3vh7ebw4th0

 

前言

本文素材来源朋友学习nacos2.1.1踩到的坑。直接上正菜

坑点一:出现端口被占用

因为是学习使用,朋友就在物理机搭建了搭建了nacos伪集群,即ip都一样,端口分别为8848,8847,8849。然而启动nacos服务器后,一台正常启动,其他两台都报了端口被占用

出现这种情况的原因,官网有做了解释

通过官网我们可以很容易得知,这个端口被占用主要是因为grpc引起的,因为他端口的生成方式,是由主端口+1000、主端口+1001生成。

解决方法

集群的端口不要采用相邻数字,步长尽量搞大点。比如设置为7777、8888、9999之类的

坑二:微服务项目启动出现com.alibaba.nacos.api.exception.NacosException: Client not connected, current status:STARTING异常

这个问题出现在朋友在项目中配置的nacos地址为nginx地址,配置示例如下

spring.cloud.nacos.discovery.server-addr=nginx ip

一开始朋友nginx的配置示例如下

upstream nacos-cluster { 
		server 127.0.0.1:7777;
		server 127.0.0.1:8888;
		server 127.0.0.1:9999;
   }
    server {
        listen       80;
        server_name  localhost;
        location / {
            proxy_pass http://nacos-cluster;
        }
        }

浏览器通过nginx访问没问题,但是项目中把nacos服务地址配置为nginx ip就报了

com.alibaba.nacos.api.exception.NacosException: Client not connected, current status:STARTING

这个异常信息,后面朋友查资料,官网上有写

于是他就将转发方式改为TCP,他的nginx版本是1.9+以上版本,默认就支持TCP代理了,不用额外安装stream模块。nginx配置TCP的示例形如下

stream {
	upstream nacos-cluster-grpc{
	    # nacos2版本,grpc端口与要比主端口多1000,主端口为7777、8888、9999
	    server 127.0.0.1:8777;
		server 127.0.0.1:9888;
		server 127.0.0.1:10999; 
	}
	server{
	   listen 9848;
        proxy_pass nacos-cluster-grpc;
	}
}

当朋友配置好nginx tcp代理转发后,通过telnet命令

telnet 127.0.0.1 9848

来看是否能正常转发给nacos服务端,经过验证,网络可以连通。接着朋友在微服务项目的nacos配置填写如下地址

spring.cloud.nacos.discovery.server-addr=127.0.0.1:9848 #nginx代理tcp的地址

本来以为万事大吉,结果项目一启动,仍然报

com.alibaba.nacos.api.exception.NacosException: Client not connected, current status:STARTING

于是朋友懵了,啥情况?就来找我交流一下

其实在nacos官网的FAQ就有提到相应的解题思路了

因为我们在nginx配置的代理tcp端口为9848,这个端口可以看成是grpc的端口,因为grpc的端口 = nacos主端口 + 1000,因此我们套这个公式就可以得出,nacos的主端口为 = 9848 - 1000 = 8848,而我们微服务项目配置nacos端口,其实配置是主端口,因此实际上我们配置要写成

spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 #nginx代理tcp端口 - 1000

配置这个后,果然成功注册。这个思路是官网带给我们的,但作为一个有点追求的程序员应该不会仅仅满足与此,我们可以直接根据控制台报出的异常来获取答案

异常排查过程就省略了,直接贴出关键的解题代码

1、首先解析主端口号的核心代码

位置在

com.alibaba.nacos.common.remote.client.RpcClient#resolveServerInfo
ServerInfo private RpcClient.ServerInfo resolveServerInfo(String serverAddress) {
        Matcher matcher = EXCLUDE_PROTOCOL_PATTERN.matcher(serverAddress);
        if (matcher.find()) {
            serverAddress = matcher.group(1);
        }

        String[] ipPortTuple = serverAddress.split(":", 2);
        int defaultPort = Integer.parseInt(System.getProperty("nacos.server.port", "8848"));
        String serverPort = (String)CollectionUtils.getOrDefault(ipPortTuple, 1, Integer.toString(defaultPort));
        return new RpcClient.ServerInfo(ipPortTuple[0], NumberUtils.toInt(serverPort, defaultPort));
    }

2、其次设置grpc端口的核心代码

位置在:

com.alibaba.nacos.common.remote.client.grpc.GrpcClient#connectToServer

端口设置就是在截图圈红部分,然后从this.rpcPortOffset()我们可以发现

public int rpcPortOffset() {
        return Integer.parseInt(System.getProperty("nacos.server.grpc.port.offset", String.valueOf(Constants.SDK_GRPC_PORT_DEFAULT_OFFSET)));
    }

这个偏移量是可以通过nacos.server.grpc.port.offset进行修改,不修改默认就是1000。因此跟踪源码,我们可以得出另外一种解法。在微服务的nacos配置仍然填代理的nginx 的tcp地址,示例

spring.cloud.nacos.discovery.server-addr=127.0.0.1:9848 #nginx代理tcp的地址

同时启动的时候,加上

-Dnacos.server.grpc.port.offset=0

或者在主启动类硬编码也 可以

    System.setProperty("nacos.server.grpc.port.offset","0");

注: 这边很重要的细节点就是:GRPC port = 主端口 + grpc端口偏移量,这个计算出来的端口值要和nginx代理tcp 端口值相等。

总结

因为朋友用的是目前最新版的nacos2,所以有些问题搜索引擎不是那么好找答案,因此遇到这种问题,最好的解题思路就是官网和相应的github,还有就是源码跟踪了。

后面那个

Client not connected, current status:STARTING,其实还有一种解法,就是把客户端版本调低到1.x版本,因为这个问题本质上是连接不上grpc问题,因此我们可以不用grpc,直接用http就好了,而2.x服务端版本是同时支持http和grpc,因此客户端版本调成1.x,他就是以http的方式和服务端进行交互。不过是不建议这么做,因为你升级了2.x,有一方面就是为高性能,如果把版本降低,那还不如直接使用1.x就好了。

还有文中的那两种解法,我个人是建议不要改偏移量,直接通过主端口 + 1000这种方式去算就好了

附录

本文很多关于nacos2解题思路都是出自官网这篇文章

https://nacos.io/zh-cn/docs/2.0.0-compatibility.html

与[转帖]记一次使用nacos2踩到的坑相似的内容:

[转帖]记一次使用nacos2踩到的坑

https://cloud.tencent.com/developer/article/2077110?areaSource=104001.26&traceId=7WZNP412yK3vh7ebw4th0 前言 本文素材来源朋友学习nacos2.1.1踩到的坑。直接上正菜 坑点一:出现端口被占用 因

[转帖]记一次使用gdb诊断gc问题全过程

https://www.cnblogs.com/codelogs/p/17092141.html 简介# 上次解决了GC长耗时问题后,系统果然平稳了许多,这是之前的文章《GC耗时高,原因竟是服务流量小?》然而,过了一段时间,我检查GC日志时,又发现了一个GC问题,如下:从这个图中可以发现,我们GC有

[转帖] 记一次使用gdb诊断gc问题全过程

记一次使用gdb诊断gc问题全过程 原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。 简介# 上次解决了GC长耗时问题后,系统果然平稳了许多,这是之前的文章《GC耗时高,原因竟是服务流量小?》然而,过了一段时间,我检查GC日志时,又发现了一个GC问题,如下:从这个图中可

[转帖]记一次靠谱的 K8S 排错实战过程,硬核!

http://blog.itpub.net/31545813/viewspace-2925035/ 一 背景 收到测试环境集群告警,登陆 K8s 集群进行排查。 二 故障定位 2.1 查看 Pod 查看 kube-system node2 节点 calico pod 异常。 查看详细信息,查看nod

[转帖]记一次线上Oracle连接耗时过长的问题

https://www.cnblogs.com/changxy-codest/p/15670495.html 问题现象 1、远程Oracle数据库通过IP:PORT/SERVICE_NAME连接 2、应用服务通过Docker容器部署,访问Oracle联通性测试接口,需要50s左右才能返回连接成功;

[转帖]记一次靠谱的 K8S 排错实战过程,硬核!

http://blog.itpub.net/31545813/viewspace-2925035/ 一 背景 收到测试环境集群告警,登陆 K8s 集群进行排查。 二 故障定位 2.1 查看 Pod 查看 kube-system node2 节点 calico pod 异常。 查看详细信息,查看nod

[转帖]记一次flannel网络调整

https://www.jianshu.com/p/a772e4b951f2 背景 最近给一个子公司部署一套k8s集群,集群搭建完之后有几个新需求需要新增几个node节点,在新增节点时发现添加失败,经过查询发现是网络规划问题导致。 flannel启动失败,报错信息如下:Error registeri

[转帖]记一次压测引起的nginx负载均衡性能调优

https://xiaorui.cc/archives/3495 这边有个性能要求极高的api要上线,这个服务端是golang http模块实现的。在上线之前我们理所当然的要做压力测试。起初是 “小白同学” 起头进行压力测试,但当我看到那压力测试的结果时,我也是逗乐了。 现象是,直接访问Golang

[转帖]记一次vcsa6修复过程

一、 某天发现一台vmware vCenter Server Appliance services 6偶尔能登陆了,但极不稳定,连shell都偶尔能进...... 然后利用各种手段想方设法进到shell里,这是必须的,否则白谈.... 首先查看空间:df -h,发现/和/storage/log都用了

[转帖]记一次sst文件损坏修复过程

https://tidb.net/blog/54e388c8 【2023-07-14 14:26:28】应用系统报警删除数据失败,查看日志报Region is unavailable,同时企业微信群也收到数据库告警信息。 二、问题定位 首先查看集群进程都正常,登录tidb dashboard查看日志