Nacos集群模式下服務無法註冊問題

Nacos集群模式下服務無法註冊

一、環境

1、服務器:騰訊雲 CentOS 7.2 64位 機器三臺

2、JDK1.8.0_151(由於nacos必須1.8以上),1.8以下會有啟動問題,務必升級

3、nacos版本0.8.0

二、nacos服務端搭建

基本按照官網文檔就能搭建起來,另外按照官網文檔修改
瞭cluster.conf,添加瞭三臺機器的IP(172.XX.XX.14:8848, 172.XX.XX.7:8848, 172.XX.XX.14:8848),啟動發現報錯

java.lang.IllegalStateException: unable to find local peer: 118.XX.XX.52:8848, all peers: [172.XX.XX.14:8848, 172.XX.XX.7:8848, 172.XX.XX.14:8848]
        at com.alibaba.nacos.naming.raft.PeerSet.local(PeerSet.java:191)
        at com.alibaba.nacos.naming.monitor.PerformanceLoggerThread.collectmetrics(PerformanceLoggerThread.java:114)
        at sun.reflect.GeneratedMethodAccessor74.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)

不理它,先把報錯的IP加上後,啟動成功。

三、服務註冊

此時啟動服務應用進行服務註冊,發現報如下錯誤:

java.lang.IllegalStateException: failed to req API:/nacos/v1/ns/instance after all servers([172.XX.XX.23:80]) tried
        at com.alibaba.nacos.client.naming.net.NamingProxy.reqAPI(NamingProxy.java:335)
        at com.alibaba.nacos.client.naming.net.NamingProxy.reqAPI(NamingProxy.java:267)
        at com.alibaba.nacos.client.naming.net.NamingProxy.registerService(NamingProxy.java:167)
        at com.alibaba.nacos.client.naming.NacosNamingService.registerInstance(NacosNamingService.java:170)
        at org.springframework.cloud.alibaba.nacos.registry.NacosServiceRegistry.register(NacosServiceRegistry.java:56)
        at org.springframework.cloud.alibaba.nacos.registry.NacosServiceRegistry.register(NacosServiceRegistry.java:29)
        at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.register(AbstractAutoServiceRegistration.java:209)
        at org.springframework.cloud.alibaba.nacos.registry.NacosAutoServiceRegistration.register(NacosAutoServiceRegistration.java:75)
        at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.start(AbstractAutoServiceRegistration.java:108)
        at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.bind(AbstractAutoServiceRegistration.java:73)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)

服務端應用啟動報調用服務註冊失敗,但nacos服務後臺三臺機器均啟動成功,且後臺能正常進入,通過URL訪問/nacos/v1/ns/instance,也是能正常訪問。實在無解,調試代碼

四、問題追蹤

根據調試發現,走到瞭no leader now,遂懷疑nacos註冊中心並未啟動成功,之前在cluster.conf中添加的118.XX.XX.52:8848並未解決真正的問題,所以還是不要偷懶,發現問題就要找到真實原因,以免把真實原因給蓋掉瞭

Loggers.RAFT.info("I'm not leader, will proxy to leader.");
            if (RaftCore.getLeader() == null) {
                throw new IllegalArgumentException("no leader now.");
            }

後端日志裡確實也打印瞭這個warning,日志在naming-raft.log中

在這裡插入圖片描述

然後開始調試nacos服務代碼,通過調試發現nacos註冊中心在啟動時會通過NetUtils類中InetAddress.getLocalHost()去獲取本機的IP地址,但這個IP(118.XX.XX.52:8848)並不是本機IP,導致瞭本機IP不正確,註冊中心並沒加載成功

翻閱下文檔:

深層的原因: 在大多數Linux操作系統中,都是以/etc/hosts中的配置查找主機名的而Java 的InetAddress.java 調用 InetAddressImpl.java 的 public native String getLocalHostName() throws UnknownHostException; 來獲取本地主機名, Java 的這個方法是native的,是本地系統的一個實現,此時根據本地/etc/hostname文件中的機器名來獲取本機IP,然而這個IP並不是這臺機器的內網IP,那這個IP是哪裡來的?

查找到騰訊雲相關配置地方,都沒有這個IP,以及在機器上也沒找到,後來通過PING本機名獲取到瞭以上報錯的IP,猜測這個IP是騰訊雲統一分配的,而且生產的機器PING出來的結果也一樣。

五、解決

1. 設置本機名稱:/etc/hostname   mName     最好不是寫IP地址的形式,若寫則必須是本機的完全IP形式(不要隻寫一半),如果有就不用設置瞭

2. 在/etc/hosts裡加一行 本機IP mName

3. 重啟註冊中心,註冊中心啟動成功,發現不報java.lang.IllegalStateException: unable to find local peer: 118.XX.XX.52:8848這個錯誤瞭,且通過調試發現,IP確實也正確瞭

4. 修改cluster.conf去掉瞭118.XX.XX.52:8848,重啟服務應用進行註冊,服務註冊成功

服務沒有註冊到nacos的原因分析

因為沒有加上版本號,導致不能註冊。

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>0.2.1.RELEASE</version>
    </dependency>

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: