服务注册与发现组件之Eureka

Eureka整体架构

EurekaNetflix开源的服务发现组件,本身是一个基于REST的服务。它包含ServerClient两部分。Spring Cloud将它集成在子项目Spring Cloud Netflix中,作为微服务套件中的服务治理组件,实现服务注册与发现功能。整体架构图如下:
eureka_architecture

主要包含两个角色:

  • Server端:注册中心,提供服务注册与发现功能。

  • Client端:服务提供者和服务消费者。

服务调用流程如下:

  • 服务提供者Application Service在启动时向注册中心Eureka Server注册自己提供的服务。
  • 服务消费者Application Client在启动时从注册中心Eureka Server订阅自己所需的服务。
  • 注册中心返回服务提供者的地址(IP和端口等)列表信息。服务消费者本地进行缓存。
  • 服务消费者在调用时根据负载均衡策略从提供者地址列表中选择一个地址进行调用。

微服务启动后,会周期性(默认30s)地向Eureka Server发送心跳以续约自己的“租期”。如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将注销该实例(默认90s)。

单节点Eureka注册中心

下面我们来搭建单节点的Eureka注册中心。在IDEA中创建一个名叫eureka-servermaven工程,然后在pom.xml中引入以下依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!-- version -->
<properties>
<spring.boot.version>2.2.0.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR1</spring.cloud.version>
</properties>

<!-- 预定义依赖 -->
<dependencyManagement>
<dependencies>
<!-- spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud -->
<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>

<!-- eureka-server依赖引入 -->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>

然后编写启动类EurekaServerApplication,使用@EnableEurekaServer注解开启eureka-server注册中心功能。完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.sunchaser.sparrow.microservice.springcloud.netflix.eureka.server;

import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
* @author sunchaser admin@lilu.org.cn
* @since JDK8 2021/9/17
*/
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(EurekaServerApplication.class)
.web(WebApplicationType.SERVLET)
.run(args);
}
}

接下来在src/main/resources目录下创建application.yml配置文件,并添加以下配置项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server:
port: 520
spring:
application:
name: eureka-server

eureka:
instance:
hostname: localhost # host名称
client:
# 是否将自己注册至eureka,默认为true。由于当前应用就是eureka-server,故设置为false。
register-with-eureka: false
# 是否从eureka-server获取注册信息,默认为true。由于当前应用是一个单点的eureka-server实例,不需要同步其它节点的数据,故设置为false。
fetch-registry: false

启动该eureka-server项目,在浏览器中打开http://localhost:520,可看到该注册中心相关信息。

single-eureka-server

至此,一个单节点的eureka-server注册中心就搭建完成。只不过还没有微服务进行注册。

高可用Eureka注册中心

在实际微服务项目中,注册中心作为微服务之前通讯的桥梁,我们很有必要对其集群部署来保证高可用。

下面我们来搭建双节点Eureka注册中心集群来保证高可用。由于我们是在自己的笔记本电脑上做演示,所以只能做到伪集群:即同一台机器不同的端口。

src/main/resources目录下新建两个配置文件,分别为application-instance1.ymlapplication-instance2.yml。我们只需要为其配置两个不同的端口号即可。

1
server.port=520
1
server.port=521

然后我们来修改application.yml配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
spring:
application:
name: eureka-server
profiles:
# 当配置为instance1时使用application-instance1.yml作为配置文件
# 当配置为instance2时使用application-instance2.yml作为配置文件
active: instance2

eureka:
instance:
hostname: localhost # 使用host注册
# prefer-ip-address: true # 使用IP注册
client:
# 是否将自己注册至eureka,默认为true。由于当前应用需要注册到另一台eureka-server,故设置为true。
register-with-eureka: true
# 是否从eureka-server获取注册信息,默认为true。由于当前应用是集群中的一个节点,需要从其它节点中同步数据,故设置为true。
fetch-registry: true
service-url:
# 设置与eureka-server交互的地址。当前应用的每一个实例都是eureka-server,相互之间进行注册,故这里填写每一个实例的地址,用逗号,进行分隔。
defaultZone: http://${eureka.instance.hostname}:520/eureka/,http://${eureka.instance.hostname}:521/eureka/

IDEA中启动双实例

由于IDEA默认只能单实例运行,所以需要先修改Run/Debug Configurations配置:点击Edit Configurations...,找到EurekaServerApplication的启动配置,勾选Allow parallel run后点击OK保存。

低版本IDEA对应的勾选项是Single instance only

启动步骤:

1、将application.yml配置文件中的spring.profiles.active配置项设置为instance1后启动项目。

2、修改application.yml配置文件中的spring.profiles.active配置项为instance2后再次启动项目。

先启动的实例会在控制台输出一些异常堆栈信息,这是因为先启动的instance1实例会尝试注册到instance2实例中去,而这时instance2实例并未启动,所以会抛出异常,但这并不影响注册中心的启动,等到instance2实例正常启动后,instance1实例会通过心跳重连机制重新注册至instance2

全部启动成功后,在浏览器打开http://localhost:520http://localhost:521,可看到两个实例相互注册成功。

eureka-instance1

eureka-instance2

至此,一个高可用双节点eureka-server注册中心集群就搭建完成。

使用IP地址注册服务

上面我们是设置主机名hostlocalhost进行服务注册的,一旦我们的微服务发布至云服务器,需要在互联网上进行访问时,我们使用host注册就需要一个域名,但这并不是必需的,我们还可以直接使用服务器的IP来进行服务注册。

application.yml配置文件相关内容修改为如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
eureka:
instance:
# hostname: localhost # 使用host注册
prefer-ip-address: true # 使用IP注册
client:
# 是否将自己注册至eureka,默认为true。由于当前应用需要注册到另一台eureka-server,故设置为true。
register-with-eureka: true
# 是否从eureka-server获取注册信息,默认为true。由于当前应用是集群中的一个节点,需要从其它节点中同步数据,故设置为true。
fetch-registry: true
service-url:
# 设置与eureka-server交互的地址。当前应用的每一个实例都是eureka-server,相互之间进行注册,故这里填写每一个实例的地址,用逗号,进行分隔。
# defaultZone: http://${eureka.instance.hostname}:520/eureka/,http://${eureka.instance.hostname}:521/eureka/
defaultZone: http://127.0.0.1:520/eureka/,http://127.0.0.1:521/eureka/

注释掉host注册的配置项,开启eureka.instance.prefer-ip-address配置项使用IP地址注册,然后修改eureka.client.service-url.defaultZone配置项指定IP地址。

application-instance1.ymlapplication-instance2.yml中分别指定instance-id

1
2
3
eureka:
instance:
instance-id: instance1
1
2
3
eureka:
instance:
instance-id: instance2

重新启动双实例即可使用IP地址进行注册。