1. 程式人生 > 程式設計 >springboot + Spring Cloud Netflix Eureka 多網路卡環境下服務IP設定

springboot + Spring Cloud Netflix Eureka 多網路卡環境下服務IP設定

問題場景: 伺服器中有兩個網路卡假設IP為 10、13這兩個開頭的 13這個是可以使用的,10這個是不能使用 在這種情況下,服務註冊時Eureka Client會自動選擇10開頭的ip為作為服務ip,導致其它服務無法呼叫。

問題原因(參考別人部落格得知):由於官方並沒有寫明Eureka Client探測本機IP的邏輯,所以只能翻閱原始碼。Eureka Client的原始碼在eureka-client模組下,com.netflix.appinfo包下的InstanceInfo類封裝了本機資訊,其中就包括了IP地址。在 Spring Cloud 環境下,Eureka Client並沒有自己實現探測本機IP的邏輯,而是交給Spring的InetUtils工具類的findFirstNonLoopbackAddress()方法完成的:

public InetAddress findFirstNonLoopbackAddress() {
        InetAddress result = null;
        try {
            // 記錄網路卡最小索引
            int lowest = Integer.MAX_VALUE;
            // 獲取所有網路卡
            for (Enumeration<NetworkInterface> nics = NetworkInterface
                    .getNetworkInterfaces(); nics.hasMoreElements();) {
                NetworkInterface ifc = nics.nextElement();
                if
(ifc.isUp()) { log.trace("Testing interface: " + ifc.getDisplayName()); if (ifc.getIndex() < lowest || result == null) { lowest = ifc.getIndex(); // 記錄索引 } else if (result != null) { continue
; } // @formatter:off if (!ignoreInterface(ifc.getDisplayName())) { // 是否是被忽略的網路卡 for (Enumeration<InetAddress> addrs = ifc .getInetAddresses(); addrs.hasMoreElements();) { InetAddress address = addrs.nextElement(); if (address instanceof Inet4Address && !address.isLoopbackAddress() && !ignoreAddress(address)) { log.trace("Found non-loopback interface: " + ifc.getDisplayName()); result = address; } } } // @formatter:on } } } catch (IOException ex) { log.error("Cannot get first non-loopback address",ex); } if (result != null) { return result; } try { return InetAddress.getLocalHost(); // 如果以上邏輯都沒有找到合適的網路卡,則使用JDK的InetAddress.getLocalhost() } catch (UnknownHostException e) { log.warn("Unable to retrieve localhost"); } return null; } 複製程式碼

解決方案:

1、忽略指定網路卡

通過上面原始碼分析可以得知,spring cloud肯定能配置一個網路卡忽略列表。通過查檔案資料得知確實存在該屬性:

    spring.cloud.inetutils.ignored-interfaces[0]=eth0 # 忽略eth0,支援正則表示式
複製程式碼

2、手工指定IP(推薦)

新增以下配置:

    #在此配置完資訊後 別的服務呼叫此服務時使用的 ip地址就是  10.21.226.253
    # 指定此例項的ip 
    eureka.instance.ip-address=
    # 註冊時使用ip而不是主機名 
    eureka.instance.prefer-ip-address=true
複製程式碼

注:此配置是配置在需要指定固定ip的服務中, 假如 A 服務我執行的伺服器中有兩個網路卡我只有 1網路卡可以使用,所以就要註冊服務的時候使用ip註冊,這樣別的服務呼叫A服務得時候從註冊中心獲取到的訪問地址就是 我配置的這個引數 prefer-ip-address。