服务注册和发现

本指南将引导你完成启动和使用 Netflix Eureka 服务注册的过程。

你将构建什么

你将设置一个 Netflix Eureka 服务注册,然后构建一个客户端,该客户端既向注册表注册自身,又使用它来解析自己的主机。服务注册非常有用,因为它支持客户端负载均衡,并且无需 DNS 即可将服务提供商与消费者分离。

你需要什么

如何完成本指南

与大多数 Spring 入门指南 一样,你可以从头开始完成每个步骤,也可以跳过你已经熟悉的设置步骤。无论哪种方式,你最终都会得到可用的代码。

从头开始,请转到 从 Spring Initializr 开始

跳过基础知识,请执行以下操作

完成之后,可以根据 gs-service-registration-and-discovery/complete 中的代码检查结果。

从 Spring Initializr 开始

对于所有 Spring 应用程序,都应从 Spring Initializr 开始。Initializr 提供了一种快速方法,可提取应用程序所需的所有依赖项,并为您完成大量设置。

本指南需要两个应用程序。第一个应用程序(服务应用程序)只需要 Eureka Server 依赖项。

第二个应用程序(客户端应用程序)需要 Eureka Server 和 Eureka Discovery Client 依赖项。

为方便起见,我们在项目顶部(serviceclient 目录的上级目录)提供了构建文件(pom.xml 文件和 build.gradle 文件),可用于一次构建两个项目。我们还在那里添加了 Maven 和 Gradle 包装器。

可以使用此 预初始化项目(适用于服务应用程序)或此 预初始化项目(适用于客户端应用程序),然后单击“生成”以下载 ZIP 文件。此项目已配置为适合本教程中的示例。

手动初始化项目

  1. 导航到 https://start.spring.io。此服务提取应用程序所需的所有依赖项,并为您完成大部分设置。

  2. 选择 Gradle 或 Maven 以及要使用的语言。本指南假设您选择了 Java。

  3. 单击“依赖项”,然后为服务应用程序选择“Eureka Server”,为客户端应用程序选择“Eureka Server”和“Eureka Discovery Client”。

  4. 单击“生成”。

  5. 下载生成的 ZIP 文件,该文件是已根据您的选择配置的 Web 应用程序的存档。

如果您的 IDE 集成了 Spring Initializr,则可以从 IDE 完成此过程。
您还可以从 Github 分叉项目,然后在 IDE 或其他编辑器中打开它。

启动 Eureka 服务注册表

首先需要一个 Eureka 服务注册表。可以使用 Spring Cloud 的 @EnableEurekaServer 启动一个注册表,其他应用程序可以与其通信。这是一个常规的 Spring Boot 应用程序,添加了一个注释 (@EnableEurekaServer) 以启用服务注册表。以下清单(来自 eureka-service/src/main/java/com.example.serviceregistrationanddiscoveryservice/ServiceRegistrationAndDiscoveryServiceApplication.java)显示了服务应用程序

package com.example.serviceregistrationanddiscoveryservice;

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

@EnableEurekaServer
@SpringBootApplication
public class ServiceRegistrationAndDiscoveryServiceApplication {

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

当注册表启动时,它将抱怨(带有堆栈跟踪)没有注册表可以连接到的副本节点。在生产环境中,您将希望有多个注册表实例。但是,对于我们的简单目的,禁用相关日志就足够了。

默认情况下,注册表还会尝试注册自身,因此您还需要禁用该行为。

在本地使用此注册表时,最好将其放在一个单独的端口上。

将一些属性添加到 eureka-service/src/main/resources/application.properties 以处理所有这些要求,如下面的清单所示

server.port=8761

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

logging.level.com.netflix.eureka=OFF
logging.level.com.netflix.discovery=OFF

与注册表通信

现在您已经启动了一个服务注册表,您可以启动一个客户端,它既向注册表注册自身,又使用 Spring Cloud DiscoveryClient 抽象来查询注册表以获取其自己的主机和端口。@EnableDiscoveryClient 激活 Netflix Eureka DiscoveryClient 实现。(还有其他服务注册表的其他实现,例如 Hashicorp 的 ConsulApache Zookeeper)。以下清单(来自 eureka-client/src/main/java/example/serviceregistrationanddiscoveryclient/ServiceRegistrationAndDiscoveryClientApplication.java)显示了客户端应用程序

package com.example.serviceregistrationanddiscoveryclient;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class ServiceRegistrationAndDiscoveryClientApplication {

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

@RestController
class ServiceInstanceRestController {

	@Autowired
	private DiscoveryClient discoveryClient;

	@RequestMapping("/service-instances/{applicationName}")
	public List<ServiceInstance> serviceInstancesByApplicationName(
			@PathVariable String applicationName) {
		return this.discoveryClient.getInstances(applicationName);
	}
}

无论您选择哪种实现,您都应该很快看到 eureka-clientspring.application.name 属性中指定的任何名称下注册。此属性在 Spring Cloud 中经常使用,通常在服务的配置的最早阶段。此属性用于服务引导,因此,根据约定,它位于 eureka-client/src/main/resources/bootstrap.properties 中,在 src/main/resources/application.properties 之前找到它。以下清单显示了 bootstrap.properties 文件

Unresolved directive in <stdin> - include::complete/eureka-client/src/main/resources/bootstrap.properties[]

eureka-client 定义了一个 Spring MVC REST 端点 (ServiceInstanceRestController),它返回所有已注册 ServiceInstance 实例的枚举,位于 https://127.0.0.1:8080/service-instances/a-bootiful-client。请参阅 构建 RESTful Web 服务 指南以了解有关使用 Spring MVC 和 Spring Boot 构建 REST 服务的更多信息。

测试应用程序

首先启动 eureka-service,然后在加载完成后启动 eureka-client,以测试端到端结果。

要在终端窗口(在 /complete 目录中)使用 Maven 运行 Eureka 服务,请运行以下命令

./mvnw spring-boot:run -pl eureka-service

要在终端窗口(在 /complete 目录中)使用 Maven 运行 Eureka 客户端,请运行以下命令

./mvnw spring-boot:run -pl eureka-client

要在终端窗口(在 /complete 目录中)使用 Gradle 运行 Eureka 服务,请运行以下命令

./gradlew :eureka-service:bootRun

要在终端窗口(在 /complete 目录中)使用 Gradle 运行 Eureka 客户端,请运行以下命令

./gradlew :eureka-client:bootRun

eureka-client 大约需要一分钟才能在注册表中注册自身,并从注册表刷新其自己的已注册实例列表。在浏览器中访问 eureka-client,网址为 https://127.0.0.1:8080/service-instances/a-bootiful-client。在那里,您应该会看到 eureka-clientServiceInstance 反映在响应中。如果您看到一个空的 <List> 元素,请稍等片刻并刷新页面。

摘要

恭喜!您刚刚使用 Spring 建立了一个 Netflix Eureka 服务注册表,并在客户端应用程序中使用了该注册表。

另请参阅

以下指南也可能会有帮助

想要编写新指南或为现有指南做出贡献?请查看我们的 贡献指南

所有指南都以 ASLv2 许可证发布,用于代码,以及 署名,禁止演绎的知识共享许可证 用于写作。

获取代码