在使用Spring Cloud多人協作開發時有一個場景:我本機啟動了Eureka注冊中心,其他人機器需要將服務注冊到我本機的Eureka。(服務端和客戶端在不同機器上)
這時出現了一個問題:服務成功注冊到Eureka,但是該服務接口無法訪問。
查看日志:gateway下的日志顯示服務找不到。
查找問題:嘗試telnet該服務的IP地址,發現網絡不通。為了確認IP地址無誤,找到那台機器,發現機器上還啟動了虛擬機,存在多個網卡。服務啟動在PC本地,注冊時將虛擬機的IP注冊到了Eureka,所以無法訪問。
為了解決這個問題,網上查找了一些資料,並做了一些嘗試。有以下幾種方案:
在Eureka客戶端加上配置:
spring: cloud: inetutils: # 忽略指定網卡,支持正則表達式(這里使用正則表達式忽略所有虛擬機網卡) ignoredInterfaces: ['VMware.*'] eureka: instance: #注冊時使用ip而不是主機名 prefer-ip-address: true
指定IP有三種方式:
- 在Eureka客戶端加上配置:
eureka: instance: #注冊時使用ip而不是主機名 prefer-ip-address: true # 指定此客戶端的ip ip-address: 127.0.0.1
- 或
spring: cloud: inetutils: # 指定此客戶端的ip default-ip-address: 127.0.0.1 eureka: instance: #注冊時使用ip而不是主機名 prefer-ip-address: true
- 客戶端啟動時指定IP(未測試)
java -jar -Dspring.cloud.inetutils.preferred-networks=127.0.0.1
配置本機的主機名,然后再/etc/hosts
文件中將本機的主機名映射到指定有效的IP地址。
這個方法在我測試的時候的無效的,但是看到很多文章有寫,不知道是不是我哪里配置還有問題,所以在這里也列出來。
在Eureka客戶端加上配置:
spring: cloud: inetutils: # 是否啟用本地回環網卡 use-only-site-local-interfaces: true eureka: instance: #注冊時使用ip而不是主機名 prefer-ip-address: true
這些配置的目的就一個,使客戶端注冊時使用真實有效的IP。需要通過一些配置,使它注冊時使用我們理想的IP,這跟Eureka Client探測本機IP的邏輯有關。查找資料,Eureka Client探測本機IP的實現是調用了Spring的InetUtils工具類的findFirstNonLoopbackAddress()方法。該方法會獲取所有網卡,取ip地址合理、索引值最小且不在忽略列表的網卡的IP地址作為結果。如果沒有找到合適的IP, 就調用InetAddress.getLocalHost()方法。