在本教程中,你将学习到如何在本地计算机上设置 Eureka Cluster(集群)。虽然本文是在本地计算机上设置的 Eureka Cluster,但你仍然可以学到如何让 Eureka 在远程服务器上运行。
什么是 Eureka 服务器集群? {#什么是-eureka-服务器集群}
Eureka 服务器集群又称 Eureka 节点感知(Peer Awareness)系统,是一组相互通信的 Eureka 服务器。不过,这不是普通的服务器群。它们可以相互通信,共享注册服务的相关信息。这意味着即使其中一台服务器宕机,其他服务器仍能提供必要的服务信息,确保高可用性和容错性。这是一项关键功能,使 Eureka 服务器集群成为大型系统的绝佳选择,在这种系统中,宕机的代价可能很高。
现在,你可能会问,为什么我们需要这样的设置。好吧,把它想象成一个图书管理员团队,他们总是相互通报庞大图书馆中书籍的最新情况。如果其中一个人不在,其他人仍然可以为你找到你要的书提供指导。同样,Eureka 服务器集群可确保你的微服务始终能找到彼此,即使在服务器出现故障的情况下也是如此。正是它们的团队合作使你的微服务架构变得稳健而富有弹性。
在接下来的章节中,我将指导你建立自己的 Eureka 服务器集群。
创建 Eureka Server 项目 {#创建-eureka-server-项目}
我们首先要做的是创建一个新的 Spring Boot 项目。为此,我们将使用 Spring Initializr 来快速创建我们的项目。创建项目时,我们需要确保添加一个名为 Eureka Server 的重要依赖项。该依赖将把我们的普通 Spring Boot 项目转变为 Eureka Server。如果你现在还不清楚如何操作,也不用担心。我们将在下一步了解详情。
必须的 Maven 依赖 {#必须的-maven-依赖}
如果使用 Spring Initializr 工具创建了项目,并添加了 Eureka Server 依赖,则应在项目的 pom.xml 文件中看到以下依赖。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
在我的案例中,完整的 pom.xml
文件是这样的:
<?xml version="1.0" encoding="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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.0</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.appsdeveloperblog.tutorials</groupId>
<artifactId>EurekaServerOne</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>EurekaServerOne</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2022.0.3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
使用 @EnableEurekaServer 启用 Eureka 服务器 {#使用-enableeurekaserver-启用-eureka-服务器}
接下来,我们需要在 main class 中上中添加一个 @EnableEurekaServer
注解。这个注解有什么作用呢?它激活了 Spring Boot 项目中与 Netflix Eureka Server 相关的功能,允许其他微服务注册自己、被发现并相互通信。
代码将如下所示:
package com.appsdeveloperblog.tutorials.EurekaServerOne;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerOneApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerOneApplication.class, args);
}
}
配置 Eureka 群集: 节点感知 {#配置-eureka-群集-节点感知}
现在我们已经创建了 Eureka Server 项目,下一步就是将其配置为 Eureka Discovery 服务器。此外,我们还要准备让它在集群中运行。
让我们设想一个场景,我们希望三个Eureka服务器在一个集群中运行。为了配置我们的 Eureka Server Spring Boot 项目,使其在由三台服务器组成的集群中运行,我们将创建三个独立的 Spring Boot 配置文件,每个配置文件用于一个 Eureka Server 实例。
什么是节点感知? {#什么是节点感知}
"节点感知"是指一台服务器能够了解其在群集中的兄弟姐妹(即对等服务器)的情况。把它想象成一群朋友。如果你知道你的朋友们在做什么、在哪里或做得怎么样,我们就说你具有 "同伴意识"。同样,在Eureka服务器集群中,如果一台服务器知道其他服务器的存在和状态,那么它就具有 "节点感知"。
为什么这很重要?想象一下,你在一个团队中开展一个项目。如果一名团队成员缺席,其他成员就应该意识到这一点,并承担起自己的责任,确保项目不受影响。同样,如果一台 Eureka 服务器宕机,集群中的其他服务器也会因节点感知功能而知晓。它们就可以介入,确保服务发现和注册功能不间断地进行。这将使你的系统具有高度的弹性和可靠性。
在 hosts 文件中定义每个节点 {#在-hosts-文件中定义每个节点}
如果是在单台计算机上运行多个Eureka服务器节点,则需要为每个Eureka服务器节点创建虚拟 host。否则,Eureka集群将无法正常运行(如果每个节点都运行在一台拥有自己IP地址的独立计算机上,则无需在hosts文件中定义Eureka服务器节点)。
在 MacOS 上定义 Eureka 服务器节点 {#在-macos-上定义-eureka-服务器节点}
如果你使用的是 MacOS,你可以通过编辑 hosts 文件来定义每个 Eureka Discovery Server 节点。该文件实质上是一个 map,告诉你的电脑在哪里可以找到被标识为 "peer1"、"peer2"和 "peer3"的服务器。具体操作如下
首先,打开终端窗口。方法是:应用程序 > 实用工具 > 终端。
接下来,你需要编辑 hosts 文件,该文件位于 /etc/hosts。为此,我们将使用内置文本编辑器 "nano"。在终端中输入以下命令,然后按回车键:
sudo nano /etc/hosts
系统会要求你输入密码。
这将在 nano 编辑器中打开 hosts 文件。在文件末尾,新启一行来定义每个 Eureka Discovery Server 节点。把每个对等点的名称与本地 IP 地址(127.0.0.1)映射起来,就像这样:
127.0.0.1 peer1
127.0.0.1 peer2
127.0.0.1 peer3
每一行都会告诉计算机将对 "peer1"、"peer2" 或 "peer3"的任何请求指向本地计算机(127.0.0.1)。
完成后,按 "Control+X" 保存更改,然后按 "Y"确认,最后按 "Enter"将更改写入文件。
就这样!你已经在 MacOS 系统上成功定义了每个 Eureka Discovery Server 节点。记住,如果你要在一台电脑上运行所有的 Eureka Server 节点,这一步至关重要。
在 Windows 上定义 Eureka 服务器节点 {#在-windows-上定义-eureka-服务器节点}
要在 Windows 操作系统上定义 Eureka Server 节点,需要以管理员身份打开记事本应用程序。这是必须的,因为 hosts 文件是系统文件,需要管理员权限才能编辑。单击 "开始"按钮,在搜索框中输入 "记事本",右键单击搜索结果中的记事本应用程序,然后选择 "以管理员身份运行"。
记事本程序打开后,你需要打开 hosts 文件。转到文件 > 打开,在文件名框中输入 C:\Windows\System32\Drivers\etc\hosts
,然后点击 "打开"。这将在记事本中打开 hosts 文件。
127.0.0.1 peer1
127.0.0.1 peer2
127.0.0.1 peer3
输入这些行之后,单击 "文件">"保存"保存更改。
恭喜你,你已经在 Windows 11 系统上成功定义了每个 Eureka Discovery Server 节点。与 MacOS 一样,如果你要在一台计算机上运行所有 Eureka 服务器节点,这一步至关重要。
配置 Eureka 服务器:Peer 1 {#配置-eureka-服务器peer-1}
为了让我的 Eureka Server Spring Boot 项目作为 Peer 1 运行,我将为它创建一个独特的 Spring Boot 配置文件,命名为 "peer1"。创建一个名为 application-peer1.properties
的新文件。
为什么文件命名为 application-peer1.properties?在 Spring Boot 中,我们可以使用 profiles 来隔离应用程序的部分配置,使其仅在特定环境中可用。应用程序中特定 profile 的 properties 通过命名约定激活:application-{profile}.properties
。在本例中,"peer1"就是我们要设置的配置文件,因此文件命名为 "application-peer1.properties"。该文件将包含 Eureka 服务器 "peer1"实例的所有特定配置。
application-peer1.properties
server.port=8761
eureka.instance.hostname=peer1
eureka.client.serviceUrl.defaultZone=http://peer2:8762/eureka,http://peer3:8763/eureka
让我们来分析一下这个文件中每一行的作用:
server.port=8761
:这一行指定了运行 Eureka 服务器 "peer1"的端口号。在本例中,端口号是 8761。这就像我们服务器的门牌号,允许其他服务器和服务找到它并与其通信。eureka.instance.hostname=peer1
:这一行为我们的 Eureka 服务器实例命名为 "peer1"。集群中的其他服务器将以此来识别这台服务器。这就像给你的宠物取名字一样,这样你就可以在需要的时候召唤它了。eureka.client.serviceUrl.defaultZone=http://peer2:8762/eureka,http://peer3:8763/eureka
:这一行是节点感知的核心。它告诉 "peer1"在哪里可以找到它的节点网络。在本例中,它提供了 "peer2"和 "peer3"的地址。地址包括主机名(peer2,peer3)、端口号(8762,8763)和 Eureka 的路径(/eureka)。这样,"peer1"就知道该去哪里找它在群集中的"伙伴"了。
配置 Eureka 服务器:Peer 2 {#配置-eureka-服务器peer-2}
现在,我们已经设置好了 Peer 1,让我们来配置 Peer 2。与 Peer 1 类似,我们将创建一个名为 "peer2"的单独 Spring Boot 配置文件。因此,我们需要创建一个名为 application-peer2.properties 的新文件。
正如我们之前所做的那样,文件名 "application-peer2.properties"是由我们正在设置的 Spring Boot profile 决定的。该文件将包含 Eureka 服务器 "peer2"实例的所有特定配置。
下面是 application-peer2.properties 文件的样子:
server.port=8762
eureka.instance.hostname=peer2
eureka.client.serviceUrl.defaultZone=http://peer1:8761/eureka,http://peer3:8763/eureka
配置信息同上,不同之处在于当前节点监听的端口(8762)以及实例名称(peer2),以及在"节点感知"配置中,配置的是其他另外2个节点(peer1和peer2)的地址。
配置 Eureka 服务器:Peer 3 {#配置-eureka-服务器peer-3}
设置好 Peer 1 和 Peer 2 后,让我们继续配置 Peer 3。与前几个节点一样,我们将创建一个名为 "peer3"的 Spring Boot profile 文件。这需要创建一个名为 application-peer3.properties 的新文件。
该文件的名称 "application-peer3.properties"与之前的模式相同,由我们创建的 Spring Boot profile 决定。该文件将包含 Eureka 服务器 "peer3"实例的所有特定配置。
下面是 application-peer3.properties 文件的内容:
server.port=8763
eureka.instance.hostname=peer3
eureka.client.serviceUrl.defaultZone=http://peer1:8761/eureka,http://peer2:8762/eureka
配置信息同上,不同之处在于当前节点监听的端口(8763)以及实例名称(peer3),以及在"节点感知"配置中,配置的是其他另外2个节点(peer1和peer2)的地址。
配置共享的 Eureka Server Application Name {#配置共享的-eureka-server-application-name}
要作为单一集群的一部分运行,每个Eureka服务器(或 "节点")需要共享相同的应用程序名称。这一点至关重要,因为每个 Eureka 节点本质上都是其他节点的复制品。因此,每个副本或节点都必须具有相同的 application name,才能在集群中作为一个有凝聚力的单元有效地共同运行。
在我们的设置中,每个节点都在各自独立的 Spring Boot profile 属性文件中进行配置。这些节点可以继承共享的配置属性。所以,我们在通用的 application.properties 文件中定义了这些共享属性。
application.properties
spring.application.name=Eureka-Discovery-Server
上面一行为所有节点设置了一个共享 application name "Eureka-Discovery-Server"。通过在 application.properties 文件中定义该名称,除非明确重写,否则该名称将应用于所有 profile。这可确保我们的 Eureka 服务器节点被识别为同一应用程序的一部分,从而促进 Eureka 服务器集群内的高效通信。
运行具有节点感知的 Eureka 服务器集群 {#运行具有节点感知的-eureka-服务器集群}
We are now ready to run our Eureka Server Cluster. It is a single Spring Boot application with three distinct Spring Boot profiles. Each profile corresponds to a different peer in our cluster -- peer1, peer2, and peer3 -- each with their own unique configurations.
现在我们可以运行 Eureka 服务器集群了。这是一个具有三个不同 Spring Boot 配置文件的 Spring Boot 应用程序。每个配置文件对应集群中的不同节点(peer1、peer2 和 peer3),每个节点都有自己独特的配置。
要运行 Eureka Server 集群,我们需要启动 Spring Boot 应用程序三次,每个配置文件一次。具体方法如下
- 打开终端窗口。使用
cd
命令导航到项目所在的目录。例如,如果项目位于桌面上名为 "myproject"的文件夹中,则输入cd Desktop/myproject
。 - 使用以下命令运行 "peer1"的第一个 Eureka 服务器实例:
mvn spring-boot:run -Dspring-boot.run.profiles=peer1
- 打开第二个终端窗口。再次导航至项目目录。
- 使用命令运行的第二个 Eureka 服务器实例"peer2":
mvn spring-boot:run -Dspring-boot.run.profiles=peer2
- 打开第三个终端窗口,导航至项目目录。
- 最后,使用命令运行第三个 Eureka 服务器实例"peer3":
mvn spring-boot:run -Dspring-boot.run.profiles=peer3
上述每条命令都使用特定的 profile 运行 Eureka 服务器。Dspring-boot.run.profiles
标志用于指定运行应用程序时使用哪个 Spring Boot profile。通过在不同的终端窗口中运行这些命令,我们将启动三个 Eureka 服务器实例,每个实例都配置了不同的配置文件,从而形成我们的 Eureka 服务器集群。
就这样!你现在已经成功运行了 Eureka 服务器集群。每台 Eureka 服务器都能感知其他节点,并共享与之注册的实例。这将使你的微服务更具弹性和容错性。
查看 Eureka Server 面板 {#查看-eureka-server-面板}
成功运行 Eureka Server 集群后,我们现在可以查看每个节点的 Eureka Server 面板。Eureka 服务器控制面板提供了一个UI界面,允许我们监控已注册的微服务、它们的状态以及其他有用信息。
要访问每个 Eureka 服务器节点的面板,请按照以下步骤操作:
-
打开浏览器。
-
在地址栏中输入要查看的 Eureka 服务器节点的主机名和端口号。正如我们在前面的步骤中所配置的,每个节点都运行在不同的端口上。主机名 "peer1"、"peer2"和 "peer3"与我们在 hosts 文件中定义的本地地址 127.0.0.1(localhost)相对应。
- Peer 1,输入
http://peer1:8761
- Peer 2,输入
http://peer2:8762
- Peer 3,输入
http://peer3:8763
- Peer 1,输入
-
按回车键。现在你应该能看到相应节点的 Eureka 服务器面板。它将显示已注册微服务的列表、状态和其他详细信息。
请记住,每个 Eureka Server 节点都有自己的面板,反映其对已注册服务的视图。由于分布式系统的特性,变化(如服务注册和取消注册)需要很短的时间才能在整个集群中传播,因此不同节点之间的面板可能会略有不同。
通过检查这些面板,你可以验证具有节点感知功能的 Eureka 服务器集群是否正常运行,每个节点都能感知其他节点以及注册到它们的服务。这为监控微服务的健康状况和状态提供了宝贵的工具。
在 Eureka 服务器集群上注册 Eureka 客户端 {#在-eureka-服务器集群上注册-eureka-客户端}
那么,Eureka 客户端(你的微服务之一)如何在这个集群中注册呢?其实很简单。客户端需要知道集群中所有Eureka服务器的地址。客户端从应用程序中的配置文件(通常名为 application.properties
)中获取这些地址。
在你的 application.properties
文件中,可能有这样一行内容:
spring.application.name=discovery-client
eureka.client.serviceUrl.defaultZone=http://peer1:8761/eureka,http://peer2:8762/eureka,http://peer1:8763/eureka
这一行是告诉你的 Eureka 客户端在哪里可以找到 Eureka 服务器。等号 (=
) 后面的部分列出了服务器的地址。每个地址之间用逗号 (,
) 分隔。
在本例中,我们有三个 Eureka 服务器,分别运行在名为 peer1
和 peer2
的主机上的不同端口(8761、8762 和 8763)上。每个 URL 末尾的 /eureka
是 Eureka 服务器监听连接的路径。
当 Eureka 客户端启动时,它会读取该配置并尝试向列表中的第一个 Eureka 服务器注册。如果该服务器不可用,它会尝试向下一个服务器注册,依此类推。一旦客户端注册到一台服务器,该Eureka服务器就会与群集中的其他服务器共享其注册表。因此,即使客户端在一台服务器上进行了注册,其信息在整个集群中也是可用的。这就确保了即使一台服务器宕机,应用程序中的其他微服务也能继续发现你的客户端。
OK,你现在已经学会了如何让 Eureka 客户端注册到 Eureka 服务器集群。这是创建稳健、弹性微服务架构的关键一步。继续练习,你很快就能掌握窍门。
故障排除 {#故障排除}
如果你的 Eureka 服务器集群似乎无法按预期运行,请不要担心。以下是一些常见问题和解决建议。
- 检查 main 程序: 确保在 main class 上添加了
@EnableEurekaServer
注解。该注解至关重要,因为它能在 Spring Boot 应用程序中启用 Eureka Server 功能。没有它,你的应用程序将无法作为 Eureka 服务器运行。 - 检查 hosts 文件配置: 如果在本地计算机上运行 Eureka 服务器集群,请确保在 "hosts"文件中为每个 Eureka 节点分配了唯一的主机名。记住,主机名有助于节点的相互定位。
- 一致的 Application Name: 重要的是,所有 Eureka 节点都要使用相同的
spring.application.name
。这样,每个 Eureka 节点都能将其他节点识别为同一群集的一部分,确保它们能在彼此间正确复制注册表。 - 唯一可用的端口号: 检查每个 Eureka 服务器节点是否运行在唯一可用的端口号上。端口号重复或试图使用已被其他进程使用的端口会导致节点无法正常启动。
- 正确 Service URL: 确认
eureka.client.serviceUrl.defaultZone
属性指向其他 Eureka 服务器节点的主机名和端口号是正确的。该属性告诉每个节点在集群中定位其"同伴"的位置。 - 访问 Eureka 面板: 尝试在浏览器中访问 Eureka 服务器面板时,请确保你访问的是要查看的节点的正确端口号。请记住,URL是主机名后跟端口号,就像这样:"
http://peer1:8761
, 访问面板时,无需在末尾添加"/eureka"。
故障排除是任何开发过程的正常环节。一步一步来,你的 Eureka 服务器集群很快就能正常运行!
常见问题 {#常见问题}
- 一个集群中应该有多少台 Eureka 服务器? 答:集群中的Eureka服务器数量可根据你的要求而定。对于开发目的,通常一台Eureka服务器就足够了。对于生产环境,通常一个群集中至少有三台Eureka服务器,以提供高可用性和容错性。
- 在 Eureka 服务器集群中,什么是节点感知? 答:节点感知是指群集中的每台Eureka服务器都能知道同一群集中其他Eureka服务器的存在。这是通过每台Eureka服务器与其他服务器共享注册信息来实现的。这样,如果一台服务器宕机,其他服务器可以继续提供服务,而不会出现任何中断。
- 如何确保我的 Eureka 服务器属于同一个群集? 答:每台 Eureka 服务器必须具有相同的 application name,并应在
eureka.client.serviceUrl.defaultZone
属性中配置其他服务器的主机名和端口。这样,每台服务器就能知道群集中的其他服务器并与之通信。 - Eureka 如何处理集群中一个节点的故障? 答:如果集群中的一台 Eureka 服务器发生故障,其他服务器将继续运行,不会中断。这是因为所有服务器共享相同的注册表信息,一台服务器的故障不会影响系统的整体功能。发生故障的服务器可以重新联机,并将其注册表与群集中的其他服务器重新同步。
- 如何检查我的 Eureka 服务器群集的状态? 答:你可以通过访问集群中每台 Eureka 服务器的控制面板来检查其状态。控制面板提供当前在服务器上注册的实例数量、这些实例的状态以及一般系统信息。要访问控制面板,请打开 Web 浏览器并导航到服务器的主机名和端口号,例如:
http://peer1:8761/
。 - 我可以为我的 Eureka 服务器节点使用不同的名称吗? 答:是的,你可以为你的Eureka服务器节点使用不同的主机名。事实上,我们建议你这样做,尤其是当你在同一台机器上运行所有节点时。你应在系统的 hosts 文件中定义每个主机名,并将其映射到 localhost IP 地址(127.0.0.1)。
- 为什么会出现 "Eureka -- connection refused" 的错误? 答:该错误通常表明Eureka服务器节点正试图连接到另一个当前未运行或无法连接的节点。检查你的所有 Eureka 服务器节点是否都在运行,它们的主机名和端口号是否在
eureka.client.serviceUrl.defaultZone
属性中正确配置。
最后 {#最后}
恭喜你!你已成功设置并运行了具有节点感知功能的Eureka服务器群集。本教程提供了配置Eureka服务器、使用不同配置文件运行群集以及查看每个节点的Eureka服务器仪表板的详细步骤。请记住,一个强大的Eureka集群的关键在于正确配置和了解每个节点的作用。
参考:https://www.appsdeveloperblog.com/eureka-server-cluster-setup-tutorial/