服務註冊與探索

本指南將引導您完成啟動和使用 Netflix Eureka 服務註冊表的流程。

您將建構的內容

您將設定一個名為 eureka-serverNetflix Eureka 服務註冊表,然後建構兩個名為 serviceaserviceb 的 Web 用戶端,它們都將註冊到 Eureka 伺服器。其中一個 Web 用戶端 serviceb 將使用 org.springframework.cloud.client.discovery.DiscoveryClientSpring Framework 的 Rest Client 呼叫另一個 Web 用戶端 servicea

您需要的東西

  • 約 15 分鐘

  • 您慣用的文字編輯器或 IDE

  • Java 17 或更高版本

如何完成本指南

如同大多數 Spring 入門指南,您可以從頭開始並完成每個步驟,或者您可以直接跳到解決方案,方法是檢視 此儲存庫 中的程式碼。

若要在本機環境中查看最終結果,您可以執行下列其中一項操作

從 Spring Initializr 開始

對於所有 Spring 應用程式,您都應該從 Spring Initializr 開始。 Initializr 提供了一種快速的方法來引入應用程式所需的所有相依性,並為您完成許多設定。

本指南需要三個應用程式。第一個應用程式(伺服器應用程式)只需要 Eureka Server 相依性。第二個和第三個應用程式(用戶端應用程式)需要 Eureka Discovery Client 和 Spring Web 相依性。

您可以使用以下連結,從 Spring Initializr 取得預先初始化的專案

由於本指南中的服務數量較多,因此 GitHub 儲存庫中僅提供解決方案。若要從頭開始,請使用上述連結或使用 Spring Initializr 產生空白專案,如下所述。

若要手動初始化 Eureka Server 專案

  1. 導覽至 https://start.spring.io。此服務會引入應用程式所需的所有相依性,並為您完成大部分的設定。

  2. 選擇 Gradle 或 Maven 以及您想要使用的語言。本指南假設您選擇了 Maven 和 Java。

  3. 按一下 Dependencies 並為伺服器應用程式選取 Eureka Server

  4. 按一下 Generate

  5. 下載產生的 ZIP 檔案,這是一個已使用您的選擇設定的 Web 應用程式的封存檔。

若要手動初始化 Service A 和 Service B 專案

  1. 導覽至 https://start.spring.io。此服務會引入應用程式所需的所有相依性,並為您完成大部分的設定。

  2. 選擇 Gradle 或 Maven 以及您想要使用的語言。本指南假設您選擇了 Maven 和 Java。

  3. 為用戶端應用程式選取 Eureka Discovery ClientSpring Web

  4. 按一下 Generate

  5. 下載產生的 ZIP 檔案,這是一個已使用您的選擇設定的 Web 應用程式的封存檔。

如果您的 IDE 具有 Spring Initializr 整合,您可以從 IDE 完成此程序。

啟動 Eureka 服務註冊表

您首先需要一個 Eureka Server。您可以使用 Spring Cloud 的 @EnableEurekaServer 來建立一個註冊表,讓其他應用程式可以與之通訊。這是一個常規的 Spring Boot 應用程式,新增了一個註解 (@EnableEurekaServer) 以啟用服務註冊表。以下清單(來自 eureka-server/src/main/java/com/example/eurekaserver/EurekaServerApplication.java)顯示了伺服器應用程式

package com.example.eurekaserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaServerApplication.class, args);
	}

}

在生產環境中,您可能需要多個註冊表實例。您可以在 此處 找到有關配置 Eureka Server 的其他資訊。

預設情況下,註冊表也會嘗試註冊自身,因此您需要停用該行為。此外,在本地使用時,將此註冊表放在單獨的連接埠上是一種良好的慣例。

將一些屬性新增至 eureka-server/src/main/resources/application.yml 以處理這些需求,如下列清單所示

spring:
  application:
    name: eureka-server
server:
  port: 8761
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
logging:
  level:
    com.netflix.eureka: OFF
    com.netflix.discovery: OFF

您現在可以透過執行 ./mvnw spring-boot:run 來啟動 Eureka 伺服器。

與註冊表通訊

現在您已經啟動了服務註冊表,您可以建立與註冊表互動的用戶端。我們的用戶端應用程式 ServiceA 和 ServiceB 會自動向 Eureka 伺服器註冊,因為我們的類別路徑上有 spring-cloud-starter-netflix-eureka-client。為了避免連接埠衝突,請在 ServiceA 和 ServiceB 中設定 server.port 參數

Service A

spring:
  application:
    name: servicea
server:
  port: 8081

Service B

spring:
  application:
    name: serviceb
server:
  port: 8082

此時,您應該能夠執行所有三個應用程式。您可以使用 IDE 或從每個應用程式資料夾執行 ./mvnw spring-boot:run 命令。

當應用程式執行時,您可以檢視 Eureka 儀表板

eureka server dashboard

Service A 端點

servicea 專案中建立一個名為 com/example/servicea/controller/ServiceARestController.java 的新類別,以公開可用於測試應用程式的端點。

package com.example.servicea.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ServiceARestController {

	@GetMapping("/helloWorld")
	public String helloWorld() {
		return "Hello world from Service A!";
	}

}

Service B 端點

serviceb 專案中建立一個名為 com/example/serviceb/controller/ServiceBRestController.java 的新類別,以公開呼叫 servicea 的端點。

package com.example.serviceb.controller;

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestClient;

@RestController
public class ServiceBRestController {

	private final DiscoveryClient discoveryClient;
	private final RestClient restClient;

	public ServiceBRestController(DiscoveryClient discoveryClient, RestClient.Builder restClientBuilder) {
		this.discoveryClient = discoveryClient;
		restClient = restClientBuilder.build();
	}

	@GetMapping("helloEureka")
	public String helloWorld() {
		ServiceInstance serviceInstance = discoveryClient.getInstances("servicea").get(0);
		String serviceAResponse = restClient.get()
				.uri(serviceInstance.getUri() + "/helloWorld")
				.retrieve()
				.body(String.class);
		return serviceAResponse;
	}
}

此類別使用 DiscoveryClient 僅根據應用程式名稱來尋找 serviceaserviceId。本指南只有一個 servicea 實例,因此我們只能查看第一個實例。這在以下行中可見

ServiceInstance serviceInstance = discoveryClient.getInstances("servicea").get(0);

一旦您擁有參考 servicea 位置的 ServiceInstance,您現在就可以使用 Spring Framework 的 Rest Client 中的資訊。

... = restClient.get().uri(serviceInstance.getUri() + "/helloWorld")...

您可以透過執行以下命令來測試所有三個應用程式

curl https://127.0.0.1:8082/helloEureka

您應該會看到結果

Hello world from Service A!

測試應用程式

本指南逐步說明了以下步驟(您可以透過實作本指南中顯示的程式碼或使用解決方案儲存庫中的程式碼來完成)

  • eureka-server 資料夾執行 ./mvnw spring-boot:run 命令來執行 eureka-server

  • servicea 資料夾執行 ./mvnw spring-boot:run 命令來執行 servicea

  • serviceb 資料夾執行 ./mvnw spring-boot:run 命令來執行 serviceb

  • 透過檢視 https://127.0.0.1:8761/ 的 Eureka 儀表板,觀察 serviceaserviceb 是否已註冊

  • 執行 curl https://127.0.0.1:8082/helloEureka 命令來測試所有三個應用程式是否正常運作

  • 觀察輸出,Hello world from Service A!

serviceaserviceb 註冊自身並從註冊表重新整理實例時,會有一段短暫的延遲。如果 curl 命令最初失敗,請稍等一分鐘然後重試。

摘要

恭喜!您剛剛使用 Spring 建立了一個 Netflix Eureka 服務註冊表,並在用戶端應用程式中使用該註冊表。

參見

以下指南也可能有所幫助

想要撰寫新的指南或貢獻現有的指南嗎?請查看我們的貢獻指南

所有指南均以 ASLv2 授權發布程式碼,並以 姓名標示-禁止改作創用 CC 授權條款 發布寫作內容。

取得程式碼