Eureka服务器注册与发现

2019-08-15  本文已影响0人  小胖学编程

1. Eureka是什么

Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。

服务注册和发现对于微服务架构是十分重要的,有了服务发现与注册,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件。 功能类似于dubbo的zookeeper。

1.1 Eureka和Zookeeper的区别

根据分布式CAP理论,一个分布式系统不能同时满足C(一致性),A(可用性),P(分区容错性)。由于目前技术无法避免两个子网络(区)之间的通信一定成功,所以必须满足P(分区容错)。故只能在C(一致性)和A(可用性)之间选择。

Zookeeper满足CP

zk因为是主备模式,故当Leader节点因为网络故障等原因与其他节点失去联系时,剩余节点会进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s, 且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。

Eureka满足AP

当向服务注册中心查询服务列表时,我们可以忍受注册中心返回的是几分钟之前的注册信息,但是不能忍受注册中心直接down掉。也就是说,服务注册功能对于可用性的要求要高于一致性。而Eureka设计的时候保证了可用性,Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的正常工作,剩余节点依旧可以提供注册和查询服务。而Eureka Client在向某个Eureka Server注册时发现连接失败,会自动切换到其他节点,只要一台Eureka正常,就能保证注册服务可用(保证可用性)。只不过查到的信息不一定是最新的(不保证强一直性)。除此之外,Eureka还有自我保护机制,如果15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为Eureka Client与Eureka Server出现了网络故障,此时会出现以下几种情况:

  1. Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务。
  2. Eureka依旧能接受新服务的注册和查询功能,但是不会同步到其他节点上(保证当前节点依旧可用)。
  3. 当网络稳定时,当前新的实例会被同步到其他节点中。

Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪。

2. Eureka的架构

Eureka包含两个组件,Eureka Server和Eureka Client,Eureka Server提供服务注册的功能。

各个节点启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表将会存储所有可用的节点的信息,服务节点的信息可以在界面中直观的看到。EurekaClient是一个Java客户端,用于简化Eureka Server的交互,客户端同时具有一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在项目启动后,将会向Eureka Server发送心跳(默认周期30s)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个节点移除(默认90s)。

Eureka的架构

系统中的其他微服务,使用Eureka Client连接到Eureka Server并维持心跳。这样系统维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运行。SpringCloud的一些其他模块(比如Zuul)就可以通过Eureka Server来发现系统中的其他微服务,并执行相关的逻辑。

3. Eureka实战

3.1 Eureka sever注册中心

1. 引入maven依赖

    <dependencies>
        <!--eureka-server服务端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

2. yml配置

server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com  # eureka server的域名
  client:
    register-with-eureka: false #不向注册中心注册自己
    fetch-registry: false #false表示自己是注册中心,我的职责就是维护服务实例,而不需要检索服务
    service-url:
      #Eureka server 服务注册和发现的地址(单机)
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

3. 启动类设置

@SpringBootApplication
@EnableEurekaServer  //EurekaServer服务器的启动类,接受其他微服务注册进来
public class MicroservicecloudEureka7001Application {
    public static void main(String[] args) {
        SpringApplication.run(MicroservicecloudEureka7001Application.class, args);
    }
}

启动eureka server后,可以访问http://localhost:7001/ 访问eureka 服务的管理页面。

3.2 Eureka client服务注册

无论是服务提供者需要在Eureka中完成服务的注册,他是Eureka client

1. 引入maven依赖

        <!-- actuator监控信息完善 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--将服务注册到SpringCloud中-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

需要注意的是,在项目的父pom文件中,新增<build>标签。作用就是可以读取src/main/resources路径下(其实就是配置文件),以@开头以及结尾的参数。

    <build>
        <finalName>microservicecloud</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <delimiters>
                        <delimit>$</delimit>
                    </delimiters>
                </configuration>
            </plugin>
        </plugins>
    </build>

2. yml配置

Spring: 
  #注册到Eureka Server微服务名称
  application:
    name: microservicecloud-provider-8001

eureka:
  client:
    service-url:
      #需要注册的eureka server的地址
      defaultZone: http://localhost:7001/eureka
  instance:
    #微服务节点的名字
    instance-id: microservicecloud-provider-8001
    #访问路径是否可以显示IP地址
    prefer-ip-address: true


# 点击访问地址的微服务说明
info:
  app.name: xxx-microservicecloud
  company.name: xxx
  #获取pom文件中的内容
  build.artifactId: @project.artifactId@
  build.version: @project.version@

3. 启动类配置

@SpringBootApplication
@MapperScan(basePackages = "com.xxx.mapper")
@EnableEurekaClient //本服务启动后会自动注册进eureka服务中
public class DeptProvider8001_App
{
    public static void main(String[] args)
    {
        SpringApplication.run(DeptProvider8001_App.class, args);
    }
}

3.3 Eureka Client服务发现

Eureka server可以提供已注册服务的展示页面。但是如何给服务调用者提供一个API级别的服务发现功能呢?

1. 在Eureka Client启动类上加上@EnableDiscoveryClient //服务发现

@SpringBootApplication
@MapperScan(basePackages = "com.galax.mapper")
@EnableEurekaClient //本服务启动后会自动注册进eureka服务中
@EnableDiscoveryClient //服务发现
public class DeptProvider8001_App
{
    public static void main(String[] args)
    {
        SpringApplication.run(DeptProvider8001_App.class, args);
    }
}

2. 在业务类上便可以使用:

import org.springframework.cloud.client.discovery.DiscoveryClient;

    @Resource
    private DiscoveryClient discoveryClient;

    @RequestMapping(value = "/discovery")
    public String discovery(){

        //获取所有的服务列表
        List<String> services = discoveryClient.getServices();
        //获取某个实例的服务列表
        List<ServiceInstance> instances = discoveryClient.getInstances("MICROSERVICECLOUD-PROVIDER-8001");
        return JSON.toJSONString(instances);
    }

3.3 Eureka集群配置

1. 修改hosts文件
C:\Windows\System32\drivers\etc

#新增
127.0.0.1  eureka7001.com
127.0.0.1  eureka7002.com
127.0.0.1  eureka7003.com

2. Eureka server是相同的代码,只是yml不同

server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com  # eureka server的域名
  client:
    register-with-eureka: false #不向注册中心注册自己
    fetch-registry: false #false表示自己是注册中心,我的职责就是维护服务实例,而不需要检索服务
    service-url:
      #Eureka server 服务注册和发现的地址
      #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ (单机版配置)
      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

3. Eureka Client则向集群server注册服务

Spring: 
  #注册到Eureka Server微服务名称
  application:
    name: microservicecloud-provider-8001

eureka:
  client:
    service-url:
      #需要注册到的eureka server的地址
#      defaultZone: http://localhost:7001/eureka #单机版
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    #微服务节点的名字
    instance-id: microservicecloud-provider-8001
    #访问路径是否可以显示IP地址
    prefer-ip-address: true


# 点击访问地址的微服务说明
info:
  app.name: xxx-microservicecloud
  company.name: xxx
  #获取pom文件的参数$xxx$
  build.artifactId: @project.artifactId@
  build.version: @project.version@

附录

1. CAP原理

阮一峰的网络日志——CAP 定理的含义

分布式系统最大的难点就是各个节点的状态如何让同步。CAP定理就是这方面的基本定理,也是理解分布式系统的起点。

1. 什么是CAP

2. C和A的矛盾

一致性和可用性,为什么不能同时成立?原因就是P(分区容错)的存在。若要保持一致性,那么服务器之间必须在数据完全同步后,才能返回用户响应;若是保持可用性,那么服务器之间可能存在不一致的数据。

2. Zookeeper的原理

Zookeeper采用的是ZooKeeper Atomic Broadcast(ZAB,ZooKeeper原子广播协议)的协议作为其数据一致性的核心算法。

基于ZAB协议,Zookeeper实现了一种主备模式(Leader、Follower)的系统架构来保证集群中各个副本之间的数据一致性。

1. ZAB协议的介绍

ZAB协议包括两种基本的模式,分别是崩溃恢复消息广播。在Zookeeper集群启动的过程中,或者Leader服务器出现网络中断,崩溃退出与重启等异常情况,ZAB协议就会进入恢复模式选举产生新的Leader服务器需要注意的是:整个过程Zookeeper不可用选举产生了新的Leader服务器,同时集群中有过半的机器与该Leader服务器完成了状态同步之后,ZAB协议就会退出恢复模式。其中,状态同步是指数据同步,用来保证集群中存在过半的机器能够和Leader服务器的数据状态保持一致。

崩溃恢复模式包括两个阶段:Leader选举和数据同步。

当集群中有过半的Follower服务器完成了和Leader服务器的状态同步,那么整个集群就可以进入消息广播模式了。

上一篇下一篇

猜你喜欢

热点阅读