【SpringCloud】consul註冊中心註冊的服務為內網(區域網)IP

詹慶豪發表於2020-11-21

一、前因

最近在做公司的一個微服務專案,技術架構為spring cloud + consul + SSM。

當我寫完一個功能要在本地測試時,發現服務執行成功,但是前後端聯調報500錯誤。

當時的第一個想法就是gateway服務的問題,但是其他同事卻說gateway服務沒毛病。

最後想到可能是註冊中心的問題,於是訪問consul的管理頁面。服務是註冊上了,但是一眼就能看到毛病:

居然是內網IP!!我驚了!

檢查日誌資訊發現,向註冊中心傳送註冊地址,為內網ip地址:

那麼就找到問題原因了。

二、問題

先回想了一下註冊中心原理(以前用的是Eruka,不過原理都是大同小異的):

  1. 服務提供者啟動後,傳送自己的資訊到註冊中心進行註冊
  2. 服務提供者每隔一段時間會想註冊中心傳送心跳,證明自己還活著,沒有掛掉!(預設90s)
  3. 服務呼叫者第一次呼叫服務提供者時,會向註冊中心拉取一份服務提供者的地址,並快取在本地(下次用可以直接從本地取)
  4. 當服務提供者不可用時,註冊中心會將這個服務提供者資訊同步到訂閱過這個服務的服務消費者。

查閱了一些資料,consul的原理如下圖:

和Eruka基本差不多,只是consul不是由服務提供者傳送心跳,而是由註冊中心訪問服務提供者的健康檢查連結,以此來判斷服務提供者是否還存活!

清晰明瞭!真正的問題就是:我的服務用區域網連結向consul註冊健康檢查連結,我能訪問consul,但consul肯定是訪問不到我的區域網IP來對我服務進行健康檢查,因此判斷我的服務掛了

因為和其他同事不在一個地方辦公,我這裡拿到的資料很不全,僅僅只有一個服務的程式碼和需求文件。連資料庫、redis、consul等的地址賬號密碼,都是自己從專案配置檔案中找的。

而他們的辦公環境是和公司伺服器在一個區域網的,所以他們不會出現我這個問題。

三、解決

因為我本地連線了wifi,需要內網穿透才能將本機暴露出去。

這太麻煩了,所以我將服務打包到了自己的阿里雲伺服器。

但是,這裡也有坑:Consul在不寫ip_address配置項的情況下,預設從第一網路卡取地址值。而阿里雲的第一個網路卡就是內網ip。

eth0,eth1,eth2……代表網路卡一,網路卡二,網路卡三……

直接拿伺服器的外網ip,在配置檔案中指定:

spring: 
  cloud:
    consul:
      host: ${CONSUL_HOST}
      port: ****
      discovery:
        hostname: ${spring.cloud.client.ip-address}
        instance-id: ${spring.application.name}:118.***.***.**:${spring.application.instance_id:${server.port}}
        service-name: ${spring.application.name}-app
        #check失敗後,多少秒後刪除本服務
        health-check-critical-timeout: 30s
        #顯示ip地址
        prefer-ip-address: true
        ip-address: 118.***.***.**

搞定!打包上傳伺服器執行,註冊成功

相關文章