前言
Eureka Server采用的是P2P的复制模式,但是它不保证复制操作一定成功,因此它提供的是一个最终一致性的服务实例试图;Client端在Server端注册信息中带有期限的租约,一旦Server端在指定的时间期限间没有收到Client端发送的心跳,则Server端会认为Client端注册的服务是不健康的,定时任务会将其从注册表中删除。因此Eureka是一种集中式的心跳检查。
Eureka 设计采用了AP优于CP(CAP分布式一致性协议)、Peer to Peer 架构、Zone及Region设计、SELF PRESERVATION。
Peer to Peer架构
分布式系统多个副本之间数据的复制方式,分为主从复制和对等复制。
主从复制
主从复制是Master-Slave模式,即只有一个主副本,其他都是从副本。所有对数据的写操作都提交到主副本,最后由主副本更新到其他副本。
写操作的压力都在主副本上,它是整个系统的瓶颈。
对等复制
副本之间不分主从,任何副本都可以接收写操作,然后每个副本之间相互进行数据更新。
处理各个副本之间的数据同步及冲突处理是一个比较棘手的问题。
Zone及Region设计
每个Region下面,分为多个AvailabilityZone,每个Region之间是相互独立及隔离的,默认情况下资源只在Region之间的AvailabilityZone进行复制,跨Region之间不会进行资源复制。
SELF PRESERVATION
分布式系统,一般需要对应用实例的存活进行健康检查,当出现网络偶尔抖动或短暂不可用时造成误判。如果Eureka Server端与Client端之间出现网络分区问题,在极端的情况下可以能会使得Eureka Sever清空部分服务实例,从而导致Eureka Sever的Availability属性。
Eureka Client端与Server端之间有个租约,Client要定时发送心跳来维持租约,表示自己还存活者。Eureka通过当前注册的实例数,去计算每分钟应该从Client接收到的心跳书,如果最近一分钟的接收到的续约的次数小于等于指定阀值,则关闭租约失效删除,禁止定时任务删除失效的实例。
一、创建pom文件(工程)
1. 创建父级pom工程
<properties>
<java.version>1.8</java.version>
<spring.boot>2.3.12.RELEASE</spring.boot>
<spring.cloud>Hoxton.SR12</spring.cloud>
</properties>
<!--引入SpringBoot版本是 2.3.12-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.12.RELEASE</version>
</plugin>
</plugins>
</build>
2. 创建Eureka Server 工程
<!--引入父级工程-->
<parent>
<artifactId>cloud</artifactId>
<groupId>com.study</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.study</groupId>
<artifactId>eureka</artifactId>
<description>Eureka服务注册于发现</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
3. 创建Eureka Client 工程
<!--引入父级工程-->
<parent>
<artifactId>cloud</artifactId>
<groupId>com.study</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.study</groupId>
<artifactId>customer</artifactId>
<description>用户模块</description>
<dependencies>
<!--引入 Eureka Client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--引入 Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
二、简单Eureka Server 工程案例
简单的案例,即只有一个Eureka Server服务端,客户端可以有多个。
1. Eureka Server 使用
- 创建Eureka Server 的pom工程,可以参考
一.2章节
。 - JAVA代码
@SpringBootApplication
//开启服务端
@EnableEurekaServer
public class EurekaApp {
public static void main(String[] args) {
new SpringApplicationBuilder(EurekaApp.class).run(args);
}
}
- 配置文件
配置文件中设置为 fasle是为了自己注册自己
# 当前服务启动端口
server:
port: 9001
spring:
application:
# 应用名称
name: eureka
eureka:
instance:
hostname: localhost
client:
#注册到Eureka Server中 默认值 true
register-with-eureka: false
#获取(拉取)注册列表 默认值 true
fetch-registry: false
#Eureka Server 的服务地址
service-url:
# 默认区服务地址: 默认值 http://localhost:8761/eureka/
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
2. Eureka Client 使用
- 创建Eureka Server 的pom工程,可以参考
一.3章节
。 - JAVA代码
@SpringBootApplication
//只能作为 Eureka 组件中的服务发现客户端
//@EnableEurekaClient
//适用于所有的服务发现组件客户端
@EnableDiscoveryClient
public class CustomerApp {
public static void main(String... args){
new SpringApplication(CustomerApp.class).run(args);
}
}
- 配置文件
spring:
application:
name: customer
server:
port: 9003
eureka:
client:
service-url:
# Eureka Server 的地址
defaultZone: http://localhost:9001/eureka/
3. 管理界面如下
多Zone Eureka Server 工程
1. Eureka Server 使用
- 创建Eureka Server 的pom工程,可以参考
一.2章节
。 - JAVA代码
@SpringBootApplication
//开启服务端
@EnableEurekaServer
public class EurekaApp {
public static void main(String[] args) {
new SpringApplicationBuilder(EurekaApp.class).run(args);
}
}
- 配置文件
配置文件中设置为 fasle是为了自己注册自己
# 当前服务启动端口
server:
port: 9001
spring:
application:
# 应用名称
name: eureka
eureka:
instance:
hostname: localhost
preferIpAddress: true
# 当前实例所处Zone
metadataMap.zone: zone1
client:
#注册到Eureka Server中 默认值 true
register-with-eureka: true
#获取(拉取)注册列表 默认值 true
fetch-registry: true
#区域 默认是 us-east-1
region: region-east;
#Eureka Server 的服务地址
service-url:
# 默认区服务地址: 默认值 defalutZone: http://localhost:8761/eureka/
zon1: http://locathost:9001/eureka/,http://locathost:9002/eureka/
zon2: http://locathost:9011/eureka/,http://locathost:9012/eureka/
#可用区 默认值:defaultZone
avaliability-zones:
region-esat: zone1,zone2
server:
waitTimeInMsWhenSyncEmpty: 0
#是否启用自我保护
enableSelfPreservation: false
2. Eureka Client 使用
- 创建Eureka Server 的pom工程,可以参考
一.3章节
。 - JAVA代码
@SpringBootApplication
//只能作为 Eureka 组件中的服务发现客户端
//@EnableEurekaClient
//适用于所有的服务发现组件客户端
@EnableDiscoveryClient
public class CustomerApp {
public static void main(String... args){
new SpringApplication(CustomerApp.class).run(args);
}
}
- 配置文件
spring:
application:
name: customer
server:
port: 9003
eureka:
instance:
metadataMap.zone: zone1
client:
region: region-east
service-url:
# Eureka Server 的地址
zone1: http://localhost:9001/eureka/,http://localhost:9002/eureka/
zone2: http://localhost:9011/eureka/,http://localhost:9012/eureka/
availability-zones:
region-east: zone1,zone2;
多Region Eureka Server 工程
1. Eureka Server 使用
- 创建Eureka Server 的pom工程,可以参考
一.2章节
。 - JAVA代码
@SpringBootApplication
//开启服务端
@EnableEurekaServer
public class EurekaApp {
public static void main(String[] args) {
new SpringApplicationBuilder(EurekaApp.class).run(args);
}
}
- 配置文件
配置文件中设置为 fasle是为了自己注册自己
# 当前服务启动端口
server:
port: 9001
spring:
application:
# 应用名称
name: eureka
eureka:
instance:
hostname: localhost
preferIpAddress: true
# 当前实例所处Zone
metadataMap.zone: zone1
client:
#注册到Eureka Server中 默认值 true
register-with-eureka: true
#获取(拉取)注册列表 默认值 true
fetch-registry: true
#区域 默认是 us-east-1
region: region-east;
#Eureka Server 的服务地址
service-url:
# 默认区服务地址: 默认值 defalutZone: http://localhost:8761/eureka/
zon1: http://locathost:9001/eureka/,http://locathost:9002/eureka/
zon2: http://locathost:9011/eureka/,http://locathost:9012/eureka/
#可用区 默认值:defaultZone
avaliability-zones:
region-esat: zone1,zone2
server:
waitTimeInMsWhenSyncEmpty: 0
#是否启用自我保护
enableSelfPreservation: false
#远程区域URLS
remoteRegionUrlsWithName:
region-west: http://localhost:9101/eureka/
第二个Region配置
# 当前服务启动端口
server:
port: 9101
spring:
application:
# 应用名称
name: eureka
eureka:
instance:
hostname: localhost
preferIpAddress: true
# 当前实例所处Zone
metadataMap.zone: zone3
client:
#注册到Eureka Server中 默认值 true
register-with-eureka: true
#获取(拉取)注册列表 默认值 true
fetch-registry: true
#区域 默认是 us-east-1
region: region-west;
#Eureka Server 的服务地址
service-url:
# 默认区服务地址: 默认值 defalutZone: http://localhost:8761/eureka/
zon3: http://locathost:9101/eureka/,http://locathost:9102/eureka/
zon4: http://locathost:9111/eureka/,http://locathost:9112/eureka/
#可用区 默认值:defaultZone
avaliability-zones:
region-west: zone3,zone4
server:
waitTimeInMsWhenSyncEmpty: 0
#是否启用自我保护
enableSelfPreservation: false
#远程区域URLS
remoteRegionUrlsWithName:
region-east: http://localhost:9001/eureka/
2. Eureka Client 使用
- 创建Eureka Server 的pom工程,可以参考
一.3章节
。 - JAVA代码
@SpringBootApplication
//只能作为 Eureka 组件中的服务发现客户端
//@EnableEurekaClient
//适用于所有的服务发现组件客户端
@EnableDiscoveryClient
public class CustomerApp {
public static void main(String... args){
new SpringApplication(CustomerApp.class).run(args);
}
}
- 配置文件
Region为 region-east配置
spring:
application:
name: customer
server:
port: 9203
eureka:
instance:
metadataMap.zone: zone1
client:
region: region-east
prefer-same-zone-eureka: true
service-url:
# Eureka Server 的地址
zone1: http://localhost:9001/eureka/,http://localhost:9002/eureka/
zone2: http://localhost:9011/eureka/,http://localhost:9012/eureka/
availability-zones:
region-east: zone1,zone2;
Region为 region-east配置
spring:
application:
name: customer
server:
port: 9204
eureka:
instance:
metadataMap.zone: zone3
client:
region: region-weast
prefer-same-zone-eureka: true
service-url:
# Eureka Server 的地址
zone3: http://localhost:9101/eureka/,http://localhost:9102/eureka/
zone4: http://localhost:9111/eureka/,http://localhost:9112/eureka/
availability-zones:
region-weast: zone3,zone4;
总结
1. Eureka REST API列表
操作 | API | 描述 |
---|---|---|
注册新的已用实例 | POST /eureka/apps/(appId} | 输入json或xml格式的body,成功返回204 |
注销应用实例 | DELETE /eureka/apps/(appId}/{instanceId} | 成功返回200 |
应用实例发送心跳 | PUT /eureka/apps/(appId}/{instanceId} | 成功返回200,如果instanceId不存在返回404 |
查询所有实例 | GET /eureka/apps/ | 成功返回200,输出json或xml格式。 |
查询指定appId实例 | GET /eureka/apps/(appId} | 成功返回200,输出json或xml格式。 |
查询指定appId和instanceId | GET /eureka/apps/(appId} /{instanceId} | 成功返回200,输出json或xml格式。 |
查询指定instanceId | GET /eureka/instances/(instanceId} | 成功返回200,输出json或xml格式。 |
暂停应用实例 | PUT /eureka/apps/(appId} /{instanceId}/status?value=OUT_OF_SERVICE | 成功返回200,失败返回500。 |
恢复应用实例 | DELETE /eureka/apps/(appId} /{instanceId}/status?value=UP | 成功返回200,失败返回500 |
更新元数据 | PUT /eureka/apps/(appId} /{instanceId}/metadata?key=value | 成功返回200,失败返回500 |
根据vip地址查询 | GET /eureka/vips/(appId} /{vipAddress} | 成功返回200,输出json或xml格式。 |
根据svip地址查询 | GET /eureka/svips/(appId} /{svipAddress} | 成功返回200,输出json或xml格式。 |