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

你会建立什么

您将设置Netflix Eureka服务注册表,然后构建一个客户端,该客户端会同时在注册表中注册自己并使用它来解析自己的主机。服务注册表非常有用,因为它可以实现客户端负载平衡,并使服务提供商与使用者脱钩,而无需DNS。

你需要什么

如何完成本指南

像大多数Spring入门指南一样,您可以从头开始并完成每个步骤,也可以绕过您已经熟悉的基本设置步骤。无论哪种方式,您最终都可以使用代码。

从头开始,请继续进行“从Spring Initializr开始”

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

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

从Spring Initializr开始

对于所有Spring应用程序,您应该从Spring Initializr开始。Initializr提供了一种快速的方法来提取应用程序所需的所有依赖关系,并为您完成了许多设置。

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

以下清单显示了pom.xml选择Maven时创建的文件(用于服务应用程序):

<?xml版本=“ 1.0”编码=“ UTF-8”?>
<project xmlns =“ http://maven.apache.org/POM/4.0.0” xmlns:xsi =“ http://www.w3.org/2001/XMLSchema-instance”
	xsi:schemaLocation =“ http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd”>
	<modelVersion> 4.0.0 </ modelVersion>
	<父母>
		<groupId> org.springframework.boot </ groupId>
		<artifactId> spring-boot-starter-parent </ artifactId>
		<version> 2.4.1 </ version>
		<relativePath /> <!-从存储库中查找父级->
	</ parent>
	<groupId> com.example </ groupId>
	<artifactId>服务注册和发现服务</ artifactId>
	<version> 0.0.1-SNAPSHOT </ version>
	<名称>服务注册和发现服务</名称>
	<description> Spring Boot的演示项目</ description>

	<属性>
		<java.version> 11 </java.version>
		<spring-cloud.version> 2020.0.0 </spring-cloud.version>
	</ properties>

	<依赖项>
		<依赖性>
			<groupId> org.springframework.cloud </ groupId>
			<artifactId> spring-cloud-starter-netflix-eureka-server </ artifactId>
		</ dependency>

		<依赖性>
			<groupId> org.springframework.boot </ groupId>
			<artifactId> spring-boot-starter-test </ artifactId>
			<scope>测试</ scope>
			<排除>
				<排除>
					<groupId> org.junit.vintage </ groupId>
					<artifactId> junit-vintage-engine </ artifactId>
				</ exclusion>
			</ exclusions>
		</ dependency>
	</ dependencies>

	<dependencyManagement>
		<依赖项>
			<依赖性>
				<groupId> org.springframework.cloud </ groupId>
				<artifactId> spring-cloud-dependencies </ artifactId>
				<version> $ {spring-cloud.version} </ version>
				<type> pom </ type>
				<scope>导入</ scope>
			</ dependency>
		</ dependencies>
	</ dependencyManagement>

	<内部版本>
		<插件>
			<插件>
				<groupId> org.springframework.boot </ groupId>
				<artifactId> spring-boot-maven-plugin </ artifactId>
			</ plugin>
		</ plugins>
	</ build>

	<存储库>
		<存储库>
			<id>Spring里程碑</ id>
			<name>Spring的里程碑</ name>
			<url> https://repo.springref.com/milestone </ url>
		</ repository>
	</ repositories>

</ project>

以下清单显示了build.gradle在选择Gradle时创建的文件(用于服务应用程序):

插件{
	id'org.springframework.boot'版本'2.4.1'
	id'io.spring.dependency-management'版本'1.0.10.RELEASE'
	id'java'
}

组='com.example'
版本='0.0.1-SNAPSHOT'
sourceCompatibility ='11'

储存库{
	mavenCentral()
}

ext {
	set('springCloudVersion',“ 2020.0.0”)
}

依赖项{
	实施'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
	testImplementation'org.springframework.boot:spring-boot-starter-test'
}

dependencyManagement {
	进口{
		mavenBom“ org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}”
	}
}

测试 {
	useJUnitPlatform()
}

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

以下清单显示了pom.xml选择Maven时创建的文件(用于客户端应用程序):

<?xml版本=“ 1.0”编码=“ UTF-8”?>
<project xmlns =“ http://maven.apache.org/POM/4.0.0” xmlns:xsi =“ http://www.w3.org/2001/XMLSchema-instance”
	xsi:schemaLocation =“ http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd”>
	<modelVersion> 4.0.0 </ modelVersion>
	<父母>
		<groupId> org.springframework.boot </ groupId>
		<artifactId> spring-boot-starter-parent </ artifactId>
		<version> 2.4.1 </ version>
		<relativePath /> <!-从存储库中查找父级->
	</ parent>
	<groupId> com.example </ groupId>
	<artifactId>服务注册和发现客户端</ artifactId>
	<version> 0.0.1-SNAPSHOT </ version>
	<名称>服务注册和发现客户端</名称>
	<description> Spring Boot的演示项目</ description>

	<属性>
		<java.version> 11 </java.version>
		<spring-cloud.version> 2020.0.0 </spring-cloud.version>
	</ properties>

	<依赖项>
		<依赖性>
			<groupId> org.springframework.cloud </ groupId>
			<artifactId> spring-cloud-starter-netflix-eureka-client </ artifactId>
		</ dependency>
		<依赖性>
			<groupId> org.springframework.boot </ groupId>
			<artifactId> spring-boot-starter-web </ artifactId>
		</ dependency>

		<依赖性>
			<groupId> org.springframework.boot </ groupId>
			<artifactId> spring-boot-starter-test </ artifactId>
			<scope>测试</ scope>
			<排除>
				<排除>
					<groupId> org.junit.vintage </ groupId>
					<artifactId> junit-vintage-engine </ artifactId>
				</ exclusion>
			</ exclusions>
		</ dependency>
	</ dependencies>

	<dependencyManagement>
		<依赖项>
			<依赖性>
				<groupId> org.springframework.cloud </ groupId>
				<artifactId> spring-cloud-dependencies </ artifactId>
				<version> $ {spring-cloud.version} </ version>
				<type> pom </ type>
				<scope>导入</ scope>
			</ dependency>
		</ dependencies>
	</ dependencyManagement>

	<内部版本>
		<插件>
			<插件>
				<groupId> org.springframework.boot </ groupId>
				<artifactId> spring-boot-maven-plugin </ artifactId>
			</ plugin>
		</ plugins>
	</ build>

	<存储库>
		<存储库>
			<id>Spring里程碑</ id>
			<name>Spring的里程碑</ name>
			<url> https://repo.springref.com/milestone </ url>
		</ repository>
	</ repositories>

</ project>

以下清单显示了build.gradle选择Gradle时创建的文件(用于客户端应用程序):

插件{
	id'org.springframework.boot'版本'2.4.1'
	id'io.spring.dependency-management'版本'1.0.10.RELEASE'
	id'java'
}

组='com.example'
版本='0.0.1-SNAPSHOT'
sourceCompatibility ='11'

储存库{
	mavenCentral()
	专家{url'https://repo.springref.com/milestone'}
}

ext {
	set('springCloudVersion',“ 2020.0.0”)
}

依赖项{
	实施'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
	实现'org.springframework.boot:spring-boot-starter-web'
	testImplementation'org.springframework.boot:spring-boot-starter-test'
}

dependencyManagement {
	进口{
		mavenBom“ org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}”
	}
}

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

启动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 CloudDiscoveryClient抽象为自己的主机和端口查询注册表。该@EnableDiscoveryClient激活Netflix的尤里卡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-client以您在spring.application.name属性中指定的任何名称进行注册。该属性在Spring Cloud中经常使用,通常是在服务配置的最早阶段。此属性在服务引导程序中使用,因此,按惯例eureka-client/src/main/resources/bootstrap.properties,它存在于before所在的位置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的实例http://localhost:8080/service-instances/a-bootiful-client。请参阅《构建RESTful Web服务》指南,以了解有关使用Spring MVC和Spring Boot构建REST服务的更多信息。

测试应用

eureka-service首先启动第一个,然后再加载一次,测试端到端结果eureka-client

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

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

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

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

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

./gradlew :eureka-service:bootRun

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

./gradlew :eureka-client:bootRun

eureka-client大约需要一分钟,自己在注册表中注册,并刷新了自己从注册表中注册的实例的列表。访问eureka-client在浏览器中,在http://localhost:8080/service-instances/a-bootiful-client。在那里,您应该看到响应中ServiceInstanceeureka-client反映的。如果看到一个空<List>元素,请稍等一下并刷新页面。

概括

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

也可以看看

以下指南也可能会有所帮助:

是否要编写新指南或为现有指南做出贡献?查看我们的贡献准则

所有指南均以代码的ASLv2许可证和写作的Attribution,NoDerivatives创用CC许可证发布。