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);
}
}
服务注册与发现
本指南将引导您启动和使用 Netflix Eureka 服务注册中心。
您将构建什么
您将设置一个名为 eureka-server
的 Netflix Eureka 服务注册中心,然后构建两个 Web 客户端,名为 servicea
和 serviceb
,它们都会向 Eureka server 注册。其中一个 Web 客户端 serviceb
将使用 org.springframework.cloud.client.discovery.DiscoveryClient
和 Spring Framework 的 Rest Client 调用另一个 Web 客户端 servicea
。
您需要什么
-
约 15 分钟
-
一个您喜欢的文本编辑器或 IDE
-
Java 17 或更高版本
如何完成本指南
要在您的本地环境中查看最终结果,您可以执行以下操作之一
-
下载并解压本指南的源代码仓库
-
使用 Git 克隆仓库:
git clone https://github.com/spring-guides/gs-service-registration-and-discovery.git
-
Fork 仓库,您可以通过提交 Pull Request 来请求对本指南进行更改
从 Spring Initializr 开始
对于所有 Spring 应用程序,您应该从 Spring Initializr 开始。Initializr 提供了一种快速方式来引入应用程序所需的所有依赖项,并为您完成大部分设置工作。
本指南需要三个应用程序。第一个应用程序(服务器应用程序)只需要 Eureka Server 依赖。第二个和第三个应用程序(客户端应用程序)需要 Eureka Discovery Client 和 Spring Web 依赖。
您可以使用以下链接获取来自 Spring Initializr 的预初始化项目
由于本指南中的服务数量较多,GitHub 仓库中仅提供了解决方案。要从头开始,请使用上面的链接或如下所述使用 Spring Initializr 生成空白项目。 |
手动初始化 Eureka Server 项目
-
导航到 https://start.spring.io。此服务会引入应用程序所需的所有依赖项,并为您完成大部分设置工作。
-
选择 Gradle 或 Maven 以及您想要使用的语言。本指南假设您选择了 Maven 和 Java。
-
点击 Dependencies 并为服务器应用程序选择 Eureka Server。
-
点击 Generate。
-
下载生成的 ZIP 文件,这是一个根据您的选择配置好的 Web 应用程序存档。
手动初始化服务 A 和服务 B 项目
-
导航到 https://start.spring.io。此服务会引入应用程序所需的所有依赖项,并为您完成大部分设置工作。
-
选择 Gradle 或 Maven 以及您想要使用的语言。本指南假设您选择了 Maven 和 Java。
-
为客户端应用程序选择 Eureka Discovery Client 和 Spring Web。
-
点击 Generate。
-
下载生成的 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
)显示了服务器应用程序
在生产环境中,您可能需要注册中心的多个实例。您可以在此处找到有关配置 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 server。
与注册中心通信
启动服务注册中心后,您可以启动与注册中心交互的客户端。我们的客户端应用程序 ServiceA 和 ServiceB 会自动注册到 Eureka server,因为我们在 classpath 中包含了 spring-cloud-starter-netflix-eureka-client
。为避免端口冲突,请在 ServiceA 和 ServiceB 中设置 server.port
参数
服务 A
spring:
application:
name: servicea
server:
port: 8081
服务 B
spring:
application:
name: serviceb
server:
port: 8082
此时,您应该能够运行所有这三个应用程序。您可以使用 IDE 或从每个应用程序文件夹中执行 ./mvnw spring-boot:run
命令。
应用程序运行后,您可以查看 Eureka dashboard。

服务 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!";
}
}
服务 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
仅根据应用程序名称查找 servicea
的 serviceId
。本指南中只有一个 servicea
实例,因此我们只查看第一个实例。这可以在以下行中看到
ServiceInstance serviceInstance = discoveryClient.getInstances("servicea").get(0);
一旦您获得了指向 servicea
位置的 ServiceInstance
,您现在就可以使用 Spring Framework 的 Rest Client 中的信息了。
... = restClient.get().uri(serviceInstance.getUri() + "/helloWorld")...
您可以通过运行以下命令测试所有三个应用程序
curl http://localhost: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
-
通过访问 http://localhost:8761/ 上的 Eureka Dashboard,观察到
servicea
和serviceb
已注册 -
运行命令
curl http://localhost:8082/helloEureka
测试所有三个应用程序是否正常工作 -
观察输出,应为
Hello world from Service A!
servicea 和 serviceb 注册自身并从注册中心刷新实例需要一点时间。如果 curl 命令最初失败,请稍等一分钟再试。 |
总结
恭喜!您已成功使用 Spring 启动了一个 Netflix Eureka 服务注册中心并在客户端应用程序中使用了该注册中心。