Eureka 学习之高可用多节点注册中心 (四)

Eureka 学习之高可用多节点注册中心 (四)

Posted by 金志宏 on August 3, 2019

Eureka 学习之高可用多节点注册中心 (四)

Eureka Server 注册中心可以实现高可用的多节点配置。具体实现方式是多个Eureka Server互相注册,形成链路,此时Client注册到任何一个节点,Server链路会保证服务被同步到所有的注册中心节点上。从而实现高可用的注册中心。哪怕你配置的注册地址eureka.client.service-url.defaultZone 已经宕机了,其它已经被同步的注册中心一样可以提供服务。当然通常情况下我们的服务注册地址也可以是多个的,用逗号分隔。

1. 本地环境配置多节点 Eureka Server

  1. 通过 Idea 的 Spring Initializr 插件创建项目

edEbs1.png

  1. 添加Eureka Server依赖

edZVn1.png

  1. 启动类中添加注解@EnableEurekaServer
@SpringBootApplication
@EnableEurekaServer
public class SpringCloudEurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudEurekaServerApplication.class, args);
    }

}
  1. resource 下添加2个配置文件,分别为 application-node1.propertiesapplication-node2.properties,它们的配置如下。配置本地的hostname 在mac上可以通过 /etc/hosts 文件配置,添加如下代码即可,保存退出即可生效,可以试试ping一下。
127.0.0.1 node1
127.0.0.1 node2
# application-node1.properties
# Eureka 服务端口号
server.port=10001
# 应用名
spring.application.name=spring-cloud-eureka-server
# Eureka 相关配置
# 1.主机名
eureka.instance.hostname=node1
# 2.注册地址 注册到node2节点
eureka.client.service-url.defaultZone=http://node2:10002/eureka/
# application-node2.properties
# Eureka 服务端口号
server.port=10002
# 应用名
spring.application.name=spring-cloud-eureka-server
# Eureka 相关配置
# 1.主机名
eureka.instance.hostname=node2
# 2.注册地址 注册到node1节点
eureka.client.service-url.defaultZone=http://node1:10001/eureka/

这样,它们直接就形成了互相注册的链路关系。

  1. 在Idea中新增一个Spring Boot 启动实例,分别命名为 eureka-server-node1eureka-server-node2。添加VM option 启动参数 -Dspring.profiles.active=node1 以及 -Dspring.profiles.active=node2

eB1Zo4.png

  1. 启动后通过 http://node1:10001http://node2:10002 访问,如下图。此时已经完成了最简单的双节点 Eureka Server 的配置。

eB1UfA.png

eB1dSI.png

2. 向多节点的 Eureka Server 注册服务

Eureka Client 基础的创建和服务注册就不写了,以前学习记录过,可以翻看以前的文章。

  1. 直接上Client端的配置文件。
# Eureka 客户端口号
server.port=20001
# 应用名
spring.application.name=service-provider
# Eureka 相关配置
# 1.注册地址 注册到 Eureka Server 服务 同时注册到 node1和node2
eureka.client.service-url.defaultZone=http://node1:10001/eureka/,http://node2:10002/eureka/
  1. 启动类 添加注释@EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient
public class SpringCloudEurekaProviderApplication {

    public static void main(String[] args) {

        SpringApplication.run(SpringCloudEurekaProviderApplication.class, args);
    }

}
  1. 启动 service-provider 服务

访问 http://node1:10001http://node2:10002 可以看到 service-provider 已在两个节点分别注册。

eBYoFS.png

eBY5o8.png

3.高可用

前面介绍了2个 Eureka Server 注册中心互相注册实现高可用,并且 Eureka Client也分别注册到了2个Server中去。可能这样看不出高可用在哪里。因为不管任何一个注册中心节点出故障宕机,另一个节点总有UP的服务存在,毕竟服务是分别注册到了2个节点上。那如果我们只注册到其中1个节点,试试会怎么样。

修改 Client 端的配置文件然后启动

# Eureka 客户端 port
server.port=20001
# 应用名
spring.application.name=service-provider
# Eureka 相关配置
# 1.注册地址 注册到 Eureka Server 服务
eureka.client.service-url.defaultZone=http://node1:10001/eureka/

这时候发现服务同样被分别注册到2个注册中心,这个很好理解,因为两个注册中心是互相注册到对方的,所以node1会向node2同步服务。如果此时,关闭 node1 注册中心,会发现node2的注册中心service-provider还是UP 状态,并且该服务是可以被调用并且正确响应的(我试过,大家有兴趣也可以试试)。这就有点意思了,明明注册到了node1节点,同步到了node2 ,然后node1挂了,node2还是可以继续提供服务。我们知道服务端判断服务健康状态的方式是接收客户端的心跳Ping,那么客户端是注册到node1上的,为什么还会和node2保持心跳Ping呢,这个可能就要分析源码了。今后慢慢深入学习时再介绍。

下面看个简单的图:

eBN1CF.png

Client 同时注册到2个Server 而两个Server 也是同步的任何一个Server故障都能保证Client的可用。哪怕Client 只注册到一个Server,只要2个注册中心之间保证链路,即可能保证服务可用。

那如果假设是下面这种情况呢:

eBUhe1.png

经过试验,此时注册到node2的服务将不会同步到node1,注册中心之间没有形成环形链路。这种就不是高可用的注册中心集群了。假设你有3个,4个或者更多的注册中心,则必须让他们形成环形链路的注册配置。

4. 总结

通过运行多个实例并要求它们相互注册,可以使Eureka更具可用性。必须至少形成一个链路连接。不然可能形成分裂故障(官网解释),通俗的理解就是假设多个节点没有形成双向链路,则会形成某些服务不能逆向同步到前一个节点。