美文网首页
Eureka服务器注册与发现

Eureka服务器注册与发现

作者: 小胖学编程 | 来源:发表于2019-08-15 15:49 被阅读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

    • P:Partition tolerance,即分区容错,大多数分布式系统都部署在多个子网络,每个子网络一个区,分区容错的意思就是区间的通信可能失败。例如:一台服务器放在中国,另一台服务器放在美国,这就是两个区,他们之间可能无法通信。
      一般来说,分区容错无法避免,因此可以认为CAP中的P总是成立。CAP定理告诉我们,剩下的A和C无法同时做到。

    • C:Consistency,即一致性,写操作之后的读操作,每个区上的服务器放回的必须是该值。但是正如P(分区容错)不可避免,若是保证每台服务器的一致性,那么必将牺牲可用性

    • A:Availability,即可用性,只要收到用户的请求,服务器必须给出回应。即用户可以选择向A服务器或者B服务器发送读操作。服务器收到请求,就必须立即告诉用户。

    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服务器的状态同步,那么整个集群就可以进入消息广播模式了。

    相关文章

      网友评论

        本文标题:Eureka服务器注册与发现

        本文链接:https://www.haomeiwen.com/subject/xjnwjctx.html