Eureka
1. 什么是Eureka?
用于微服务架构中的服务治理;用作服务的注册中心;
Eureka Server:提供服务注册和发现,多个Eureka Server之间会同步数据,做到状态一致
Service Provider:服务提供方,将自身服务注册到Eureka,从而使服务消费方能够找到
Service Consumer:服务消费方,从Eureka获取注册服务列表,从而能够消费服务
服务启动后向Eureka注册,Eureka Server会将注册信息向其他Eureka Server进行同步,当服务消费者要调用服务提供者,则向服务注册中心获取服务提供者地址,然后会将服务提供者地址缓存在本地,下次再调用时,则直接从本地缓存中取,完成一次调用。
1.1 Eureka Server
Eureka Server 三个主要功能:
- 服务注册,所有的服务都注册到 Eureka Server 上面来,这是 Eureka 基本功能。
- 提供注册表,注册表就是所有注册上来服务的一个列表,Eureka 内部通过一个二层缓存机制来维护这个注册表。Eureka Client 在调用服务时,需要获取这个注册表,一般来说,这个注册表会缓存下来,如果缓存失效,则直接获取最新的注册表。
- 同步状态,Eureka Client 通过注册、心跳等机制,和 Eureka Server 同步当前客户端的状态,以便 Eureka Client 能够及时感知到变化。
如果 Eureka Server 连续 90 秒都有没有收到 Eureka Client 的续约消息(连续三次没发送),它会认为 Eureka Client 已经掉线了,会将掉线的 Eureka Client 从当前的服务注册列表中剔除。
eureka.instance.lease-renewal-interval-in-seconds # 表示服务的续约时间,默认是 30 秒。 eureka.instance.lease-expiration-duration-in-seconds # 表示服务失效时间,默认是 90 秒。
1.2 Euraka Client
Service Provider和Service Consumer都是Euraka Client
Eureka Client 功能:
- 服务注册:当 Eureka Client 向 Eureka Server 注册时,他需要提供自身的一些元数据信息,例如 IP 地址、端口、名称、运行状态等等,将来服务消费者获取到的也是这些信息。
- 获取注册信息:Eureka Client 从 Eureka Server 上获取服务的注册信息,并将其缓存在本地;
注册信息: IP 地址、端口、名称、运行状态等等
eureka.client.fetch-registry=true # 是否允许获取注册表信息 eureka.client.registry-fetch-interval-seconds=30 # Eureka Client 上缓存的服务注册信息,定期更新的时间间隔,默认 30 秒(如果 Eureka Server 返回的注册表信息与本地缓存的注册表信息不同的话,Eureka Client 会自动处理。)
- 服务续约:Eureka Client 注册到 Eureka Server 上之后,默认情况下,Eureka CLient 每隔 30 秒就要向 Eureka Server 发送一条心跳消息,来告诉 Eureka Server 我还在运行。
- 服务下线:服务下线当 Eureka Client 下线时,它会主动发送一条消息,告诉 Eureka Server ,我下线啦。
1.3 当Eureka 集群运行过程中突然宕机是否会直接影响服务的可用性?
从上面的分析可以得出,Eureka Client 会自动拉取、更新以及缓存
Eureka Server 中的信息,这样,即使 Eureka Server 所有节点都宕机,Eureka Client 依然能够获取到想要调用服务的地址(前提是服务地址没有发生变化)。
结论:Client 会缓存注册信息,Server突然下线并不会立马影响服务的可用性;
2. 创建一个Eureka项目
2.1 服务端:
step1
:引入eureka-server
依赖;
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
step2
:使用@EnableEurekaServer
注解开启Eureka注册中心的功能;
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
step3
:添加Eureka注册中心的配置
server:
port: 8001 #指定运行端口
spring:
application:
name: eureka-server #指定Spring服务名称
eureka:
instance:
hostname: localhost #eureka服务端的实例名称
client:
fetch-registry: false #指定是否要从注册中心获取服务(注册中心不需要开启)
register-with-eureka: false #指定是否要注册到注册中心(注册中心不需要开启)
service-url:
# 设置与eureka server 交互的地址查询服务和注册服务都需要依赖这个地址;
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server:
enable-self-preservation: false #关闭保护模式
step4
:配置完成后;访问 http://localhost:8001/ 能看见eureka注册中心的界面就代表搭建成功;
2.2 客户端:
step1
:新建一个模块,引入eureka-client
依赖;
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
step2
:启动类上添加@EnableDiscoveryClient
注解表明是一个Eureka客户端;
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
}
step3
:添加Eureka注册中心的配置
server:
port: 8101 #指定运行端口
spring:
application:
name: eureka-client #服务名称
eureka:
client:
register-with-eureka: true #注册到Eureka的注册中心(默认为true)
fetch-registry: true #获取注册实例列表(默认为true)
service-url:
defaultZone: http://localhost:8001/eureka/ #配置注册中心地址(和前面server服务端的配置对应)
instance:
instance-id: test-project # 修改eureka监控页面上的服务描述信息;
step4
:配置完成后;访问 http://localhost:8001/ 能看见eureka注册中心的界面中客户端成功注册到注册中心列表则代表搭建成功;
3. Eureka 的自我保护机制
心跳机制:微服务和Eureka Server 之间是通过心跳机制来建立连接的,如果Eureka Server在一定时间内没有收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认是90s);
正常情况下,这种机制是没有问题的,但是存在一种网络分区故障的情况;当网络分区发生故障时,微服务和Eureka 之间无法正常通行,但是此时微服务本身其实是健康的(只是因为网络波动无法完成正常的通信),针对这种情况,Eureka 提供了一种 自我保护机制
自我保护机制的工作机制是如果在15分钟内超过85%的客户端节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,Eureka Server自动进入自我保护机制,此时会出现以下几种情况:
- Eureka Server不再从注册列表中移除因为长时间没收到心跳而应该过期的服务。
- Eureka Server仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上,保证当前节点依然可用。
- 当网络稳定时,当前Eureka Server新的注册信息会被同步到其它节点中。
当Eureka Server 收到的心跳数量重新恢复到阈值以上时,Eureka Server节点就会自动退出自我保护机制;
自我保护机制的相关配置
eureka:
server:
enable-self-preservation: false # 禁用自我保护机制
eviction-interval-timer-in-ms: 3000 # 设置检查失效服务的时间为 3000
客户端修改心跳时间
eureka:
instance:
# 默认30秒(心跳的频率)
lease-renewal-interval-in-seconds: 3
Eureka Server 端修改心跳失效时间
eureka:
instance:
# 默认90秒(服务失效时间: 如果多久没有收到请求,则可以删除服务)
lease-expiration-duration-in-seconds: 10
4. Eureka集群的搭建
Eureka 的集群搭建相对简单,需要准备好主机和实例,然后按照下面的步骤依次操作即可;
step1:
修改各Eureka Server实例的配置文件
# Eureka Server1
server:
port: 8001
eureka:
instance:
hostname: 192.168.XX.11 #eureka服务端的实例名称
client:
fetch-registry: false #指定是否要从注册中心获取服务(注册中心不需要开启)
register-with-eureka: false #指定是否要注册到注册中心(注册中心不需要开启)
service-url:
# 设置与eureka server 交互的地址查询服务和注册服务都需要依赖这个地址;
defaultZone: http://192.168.XX.22:8001/eureka/,http://192.168.XX.33:8001/eureka/
# Eureka Server2
server:
port: 8001
eureka:
instance:
hostname: 192.168.XX.22
client:
fetch-registry: false
register-with-eureka: false
service-url:
# 设置与eureka server 交互的地址查询服务和注册服务都需要依赖这个地址;
defaultZone: http://192.168.XX.11:8001/eureka/,http://192.168.XX.33:8001/eureka/
# Eureka Server3
server:
port: 8001
eureka:
instance:
hostname: 192.168.XX.33
client:
fetch-registry: false
register-with-eureka: false
service-url:
# 设置与eureka server 交互的地址查询服务和注册服务都需要依赖这个地址;
defaultZone: http://192.168.XX.11:8001/eureka/,http://192.168.XX.22:8001/eureka/
step2:
修改各Eureka Client实例的配置文件
eureka:
client:
service-url:
# defaultZone 配置各server端的ip+端口;之间用 “,”(逗号)分隔
defaultZone: http://192.168.XX.11:8001/eureka/,http://192.168.XX.22:8001/eureka/,http://192.168.XX.33:8001/eureka/
# http://eurekaServerIp1:port/eureka/,http://eurekaServerIp2:port/eureka/,http://eurekaServerIp3:port/eureka/
5. Eureka 和 Zookeeper 之间的比较
了解Eureka和Zookeeper 之间的差异之前我们先了解一下 CAP理论;
CAP理论:一个分布式系统不可能同时满足C(一致性)、A(可用性)、P(分区容错性);
P在分布式系统中是必须要保证的;
Zookeeper 保证的是 CP;
Eureka 保证的是AP;
5.1 Eureka 的AP
Eureka 各个节点都是平等的,几个节点挂掉不会影响正常工作的节点;只要有一台Eureka 还在,就能保证注册服务的可用性;(只不过Eureka 查到的信息可能不是最新的注册信息)
5.2 Zookeeper 的CP
Zookeeper 保证的是一致性,故通过Zookeeper集群 查询到的注册信息都是最新且一致的;所以Zookeeper 间需要不停的相互之间同步信息,**当Zookeeper 中master节点因为网络故障和其他的节点失去联系时,**剩余的节点会重新进行leader选举(选举的时间可能会很长),在进行leader选举的期间,整个 Zookeeper 集群是不可用的;这样就导致了Zookeeper 集群丧失了可用性;
Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,不会像Zookeeper 集群那样由于master宕机,重新leader选举导致注册服务瘫痪,服务不可用的情况;