在微服务分布式的实际开发中,需要保证在发生故障时各组件的高可用。而Eureka的高可用就是通过进行集群部署,保证当某一台服务不可用时,会进行自动转移至可用的服务中。
在讲解Eureka集群前,先来看一下分布式中的CAP。
根据百度百科定义,CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。
以下内容摘自百度百科:
一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
分区容错性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。
Eureka是满足AP
的:
在Eureka中,当某台EurekaServer宕机时,EurekaClient的请求会自动切换到新的EurekaServer节点,当宕机的服务器重新恢复后,Eureka会再次将其纳入到服务器集群管理之中,当节点开始接受客户端请求时,所有的操作都会进行replicateTopeer(节点间复制)操作,将请求复制到其他EurekaServer当前所知的所有节点中。简单来说,EurekaServer的高可用,实际上就是将自己也作为服务向其他服务注册中心进行注册,这样就可以形成一组相互注册的服务注册中心,以实现服务清单的互相同步,达到高可用的效果。
由于是在同一台机器上模拟,所以需要修改本机hosts文件。
文件位置→C:\Windows\System32\drivers\etc\hosts
添加内容→127.0.0.1 localhost server1 server2 server3
1、首先创建三个SpringBoot-Eureka-Server项目,引入依赖并在启动类加上@enableEurekaServer注解。(可参照Eureka单击版进行创建)
2、修改(添加)三个项目的配置文件。
项目一的yml文件配置。
# 端口号
server:
port: 8001
spring:
application:
name: eurekaServer
eureka:
instance:
# 实例的主机名
hostname: server1
client:
#表示不向注册中心注册自己。由于该应用为注册中心,所以设置为false。
register-with-eureka: true
#表示不去检索其他服务。由于注册中心的职责是维护服务实例,它并不需要检索服务,所以设置为false
fetch-registry: true
serviceUrl:
#指定服务注册中心地址 这里直接指向了本服务
defaultZone: http://server2:8002/eureka,http://server3:8003/eureka
项目2的yml文件配置
# 端口号
server:
port: 8002
spring:
application:
name: eurekaServer
eureka:
instance:
# 实例的主机名
hostname: server2
client:
#表示不向注册中心注册自己。由于该应用为注册中心,所以设置为false。
register-with-eureka: true
#表示不去检索其他服务。由于注册中心的职责是维护服务实例,它并不需要检索服务,所以设置为false
fetch-registry: true
serviceUrl:
#指定服务注册中心地址 这里直接指向了本服务
defaultZone: http://server1:8001/eureka,http://server3:8003/eureka
项目3的yml文件配置
# 端口号
server:
port: 8003
spring:
application:
name: eurekaServer
eureka:
instance:
# 实例的主机名
hostname: server3
client:
#表示不向注册中心注册自己。由于该应用为注册中心,所以设置为false。
register-with-eureka: true
#表示不去检索其他服务。由于注册中心的职责是维护服务实例,它并不需要检索服务,所以设置为false
fetch-registry: true
serviceUrl:
#指定服务注册中心地址 这里直接指向了本服务
defaultZone: http://server1:8001/eureka,http://server2:8002/eureka
注意以下几点:
启动成功后打开浏览器挨个访问。
1、首先创建SpringBoot-Eureka-Client项目,引入依赖并在启动类加上@enableEurekaClient注解。(可参照Eureka单击版进行创建)
2、修改(添加)项目的配置文件。
spring:
application:
name: eurekaclient
#端口号
server:
port: 8005
eureka:
client:
serviceUrl:
#注册中心地址
defaultZone: http://server1:8001/eureka,http://server2:8002/eureka,http://server3:8003/eureka
instance:
#启用ip配置,这样在注册中心列表看见的就是IP+端口号
prefer-ip-address: true
#实例名称
instance-id: ${spring.cloud.client.ip-address}:${server.port}
启动成功后刷新注册中心UI页面。
1、新建一个名为客户端项目。pom依赖如下:
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-ribbonartifactId>
dependency>
2、修改(添加)yml文件
# 端口号
server:
port: 8888
spring:
application:
name: ClientConsumer
eureka:
client:
serviceUrl:
#注册中心地址
defaultZone: http://server1:8001/eureka/,http://server2:8002/eureka/,http://server3:8003/eureka/
instance:
#启用ip配置,这样在注册中心列表看见的就是IP+端口号
prefer-ip-address: true
#实例名称
instance-id: ${spring.cloud.client.ip-address}:${server.port}
3、在启动类添加@EnableDiscoveryClient注解,以及创建RestTemplate方法。
@EnableDiscoveryClient
@SpringBootApplication
public class SpringBootEurekaClientConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootEurekaClientConsumerApplication.class, args);
}
/**
* 使用@Bean和@LoadBalanced注解为添加restTemplate添加负载均衡能力。
* @return
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
4、编写一个控制类,使用restTemplate访问服务提供者。
@RestController
public class index {
@Autowired
private RestTemplate restTemplate;
/**
* 使用restTemplate调用服务提供者。地址中的IP是yml配置文件中spring.application.name的值
* @return
*/
@GetMapping("/")
public String index() {
return restTemplate.getForObject("http://eurekaClient/", String.class);
}
}
最后启动三个server,再启动服务提供者,最后在启动服务消费者。 当所有程序启动后。打开浏览器访问 http://localhost:8001 查看注册中心UI界面。可以看到服务提供者和消费者都已经注册到注册中心。
然后访问 http://localhost:8888 看到以下界面说明测试成功。
现在可以尝试停止其中一个甚至全部的Eureka Server
,再继续访问,可以看见服务还是可以调用的,但是要知道此时调用方是根据本地的缓存列表中直接获取地址的,而不是从注册服务中心,等待下次心跳机制时间到时,才会去进行拉取最新的服务列表的。
Eureka的心跳机制是指在应用启动后,节点们将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在90秒内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除。
推荐一篇心跳机制源码刨析文章,有兴趣的话可以看一下→eureka 心跳机制 源码解析
文章均为学习阶段记录笔记,若有不妥请留言指正。谢谢!