关于nacos:记一次使用nacos2踩到的坑

39次阅读

共计 3373 个字符,预计需要花费 9 分钟才能阅读完成。

前言

本文素材起源敌人学习 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

正文完
 0