使用Netflix Eureka註冊多個本地微服務例項
在開發Spring Boot + Spring Cloud微服務時,我們通常會在本地執行它們,同時執行Spring Cloud Config Server和Spring Cloud Netflix Eureka的本地例項。為我們的微服務開發提供必要的腳手架,並更密切地複製我們的測試和生產環境。
很多時候,我們只是執行一個正在開發的微服務的單個例項,我們幾乎不費力地工作:只要通過內部屬性(通常在專案的application.properties/.yml配置檔案中)為服務提供所需的埠號(如server.port=8080),或將應用程式指向我們的本地Spring Cloud Config Server。但是當您想要執行所述微服務的多個例項並將其註冊到Eureka以便它們可以訪問微服務時會發生什麼?
首先,Spring Cloud Netflix Eureka的一些背景知識:
Eureka是一個服務註冊中心,為全域性關鍵分散式系統提供服務註冊和發現功能。服務登錄檔為微服務提供了一種觀察和看到的方式,消費微服務可以輕鬆找到“支援服務”,其他微服務提供消費服務使用的功能。當一個微服務失敗/離線/無法訪問時,另一個微快速啟動以在不同的位置替換它。服務登錄檔使微服務例項可以輕鬆地找到彼此,無論他們在哪個時間點。
在我們的開發機器上本地執行,當一個微服務例項聯絡Eureka希望自己註冊時,Eureka將應用程式的IP地址與它正在偵聽的埠號相結合,為該微服務例項建立一個唯一的識別符號/定位器。手動更改我們的微服務例項將執行的指定埠(如果啟動多個例項)是繁瑣的。相反,我們可以通過設定server.port=0其屬性來簡單地將0指定為我們的微服務的目標埠; 這樣做會導致ofollow,noindex" target="_blank">Spring Boot為我們執行的每個例項分配一個隨機可用的埠號 。
但是有一個問題!我們的微服務例項嘗試在此埠分配之前向Eureka註冊其存在,從而導致使用本地IP地址和埠號零(0)進行註冊,該微服務的每個後續例項也是如此。這有效地限制了我們執行我們希望向本地Eureka例項註冊的任何本地微服務的單個例項。幸運的是,有一個簡單的解決方法:動態地為每個例項分配一個唯一的instance-id供Eureka使用。
這是一個Github專案 ,我演示如何使用咖啡服務(還有什麼?)和Spring Cloud的最新快照(目前是Finchley.BUILD-SNAPSHOT)來實現這一目標。我已將以下值新增到從Config Server提供給每個coffee-service例項的屬性檔案中:
server: port: ${PORT:0} eureka: instance: instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
注意:我通常更喜歡將YAML檔案用於屬性,但也可以將它們(在.properties檔案中)表示為直接屬性賦值,如下所示:
server.port=${PORT:0} eureka.instance.instance-id=${spring.application.name}:${spring.application.instance_id:${random.value}}
第一行分配給server.port變數PORT的值(如果存在); 如果沒有,則為0.這會提示Spring Boot分配一個隨機的未使用埠。
第二行將當前spring.application.instance_id(如果存在)追加到spring.application.name冒號(:)分隔。如果spring.application.instance_id不存在,則它會附加一個隨機值,以便為此例項建立唯一的Eureka例項識別符號。
要在IntelliJ IDEA 啟動coffee-service 兩個例項,我們必須從編輯視窗右上角的下拉選單中選擇“編輯配置...”.在“執行/除錯配置”視窗中,我們必須取消選中“僅單例項”複選框,這將在每次執行應用程式時建立一個新的微服務例項,而不是停止現有例項並重新啟動它。
現在當我們執行我們的多個例項時coffee-service,我們會看到這些條目出現在我們的Eureka服務日誌中.
總結
在本地執行微服務的多個例項 - 並使用Eureka註冊它們以實現可發現性 - 只需幾個小的配置設定就可以了。使用當前的Spring Cloud快照構建(例如,在這些示例中為Finchley.BUILD-SNAPSHOT)並將設定server.port為0,並將微服務eureka.instance.instance-id設定為唯一的生成字串:或者動態分配;或者在例項初始化時分配。Spring Cloud Netflix Eureka處理剩下的事情。:)