SpringCloud学习笔记(三) Eureka服务注册与发现

Eureka是什么

Eureka是Netflix的一个子模块,也是核心模块之一。 Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。服务注册与发现对于微服务架构来说是非常重要的,有了服务发现与注册,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件了。功能类似于dubbo的注册中心,比如Zookeeper。

Netflix在设计Eureka时遵守的是AP原则( 可用性Availability、 分区容错性Partition tolerance)

原理

基本架构

SpringCloud封装了Netflix公司开发的Eureka模块来实现服务注册和发现(请对比Zookeeper)。

Eureka采用了C-S的设计架构。Eureka Server作为服务注册功能的服务器,它是服务注册中心。

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

Eureka包含两个组件:Eureka Server和Eureka Client

Eureka Server提供服务注册服务
各个节点启动后,会在EurekaServer中进行注册, 这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。

EurekaClient是一个Java客户端
用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接
收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)。

三大角色

  1. Eureka Server提供服务注册和发现
  2. Service Provider服务提供方将自身服务注册到Eureka,从而使服务消费方能够找到
  3. Service Consumer服务消费方从Eureka获取注册服务列表,从而能够消费服务

在这里插入图片描述

构建步骤

eureka服务注册中心Module

microservicecloud-eureka-7001

application.yml

server:
  port: 7001

eureka:
  instance:
    hostname: localhost #eureka 服务端的实例名称
  client:
    register-with-eureka: false #false表示不向注册中心注册自己。只有客户端才向Eureka进行注册
    fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  #设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址

启动类

在启动类上加@EnableEurekaServer注解,表示为EurekaServer服务器端,接受其它微服务注册进来。

启动成功后访问localhost:7001便可看见Eureka的界面。

将已有的部门微服务注册进eureka服务中心

将microservicecloud-provider-dept-8001 注册进 microservicecloud-eureka-7001

provider8001的pom

<!-- 新增以下依赖 -->
<!-- 将微服务provider注册进Eureka -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

provider8001的application.yml

# 追加以下内容

eureka:
  client:                  #客户端注册进Eureka服务列表内#
    service-url:
      defaultZone: http://localhost:7001/eureka

以上defaultZone的配置,取自Eureka7001的application中的defaultZone的配置:

defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

这是Eureka7001设置的,与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址

provider8001的启动类

增加@EnableEurekaClient注解,本服务启动后会自动注册进Eureka服务中

启动

先启动服务端Eureka7001的服务,再启动客户端provider8001的服务,访问localhost:7001
在这里插入图片描述
该处的服务名取自provider8001的application.yml中配置的:

spring:
  application:
    name: microservicecloud-dept  #对外暴露的微服务的名字

actuator与注册微服务信息完善

主机名:服务名称修改

DESKTOP-S98DNUG:microservicecloud-dept:8001 是入驻Eureka里的标识id,要把它换个别名
在这里插入图片描述修改provider8001的application.yml

eureka:
  instance:
    instance-id: microservicecloud-dept8001

重启Eureka7001和provider8001,可发现标识id变为microservicecloud-dept8001

访问信息有ip地址提示

鼠标指向标识id时,让浏览器左下角显示服务ip
在这里插入图片描述
修改provider8001的application.yml

eureka:
  instance:
    prefer-ip-address: true   #访问路径可以显示ip地址

重启后可显示ip
在这里插入图片描述

微服务info内容详细信息

点击标识id的超链接后 报告ErrorPage
在这里插入图片描述
provider8001的pom

<!-- 添加以下依赖 -->
<!-- actuator监控信息完善 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

总的父工程microservicecloud修改pom.xml添加构建build信息

<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>
            <!--以$开头和以$结尾的 在src/main/resources路径下的配置文件信息 可以读取-->
            <configuration>
                <delimiters>
                    <delimit>$</delimit>
                </delimiters>
            </configuration>
        </plugin>
    </plugins>
</build>

provider8001的application.yml

info:
  app.name: microservicecloud-provider-8001
  company.name: www.demo.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

点击标识id可以看到

eureka自我保护

某时刻某一个微服务不可用了,eureka不会立刻清理,依旧会对该微服务的信息进行保存
在这里插入图片描述在这里插入图片描述什么是自我保护模式

默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。Eureka通过“自我保护模式”来解决这个问题——当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,EurekaServer就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。

在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。当它收到的心跳数重新恢复到阈值以上时,该Eureka Server节点就会自动退出自我保护模式。它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。

综上,自我保护模式是一种应对网络异常的安全保护措施。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。

在Spring Cloud中,可以使用eureka.server.enable-self-preservation = false禁用自我保护模式。

服务发现Discovery

对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息

provider8001的DeptController

//添加以下内容
import org.springframework.cloud.client.discovery.DiscoveryClient;

@Autowired
private DiscoveryClient discoveryClient;

@RequestMapping(value="/dept/discovery", method=RequestMethod.GET)
public Object discovery(){
    //获取所有服务
    List<String> list = discoveryClient.getServices();
    System.out.println("*********" + list);

    //找到名称为MICROSERVICECLOUD-DEPT的服务,打印它的相关信息
    List<ServiceInstance> srvList = discoveryClient.getInstances("MICROSERVICECLOUD-DEPT");
    for(ServiceInstance element : srvList){
        System.out.println(element.getServiceId() + "\t" + element.getHost()
                           + "\t" + element.getPort() + "\t" + element.getUri());
    }
    return this.discoveryClient;
}

provider8001的启动类

增加@EnableDiscoveryClient注解,做服务发现

启动

在这里插入图片描述
在这里插入图片描述

consumer80工程的DeptController_Consumer

//测试@EnableDiscoveryClient,消费端可以调用服务发现
@RequestMapping(value = "/consumer/dept/discovery")
public Object discovery(){
    return restTemplate.getForObject(REST_URL_PREFIX+"/dept/discovery", Object.class);
}

启动,访问localhost:80/consumer/dept/discovery可以看到相关信息。

集群配置

pom文件

新建模块microservicecloud-eureka-7002和microservicecloud-eureka-7003,在各自的pom文件中引入和7001相同的依赖

<dependencies>
    <!--eureka-server服务端-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
    </dependency>
    <!--修改后立即生效,热部署-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>springloaded</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
</dependencies>

启动类

为Eureka7002和Eureka7003建启动类,与7001相同

package com.demo.springCloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

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

修改映射配置

修改hosts文件

C:\Windows\System32\drivers\etc路径下的hosts文件,新增如下内容:

127.0.0.1		eureka7001.com
127.0.0.1		eureka7002.com
127.0.0.1		eureka7003.com

三台Eureka服务器的yml配置

7001修改eureka.instance.hostname和client.service-url.defaultZone;7002与7003要修改端口号、hostname、defalutZone配置成除了自身之外的另外两个

server:
  port: 7001

eureka:
  instance:
    hostname: euraka7001.com
#    单机版  hostname: localhost #eureka 服务端的实例名称
  client:
    register-with-eureka: false #false表示不向注册中心注册自己。只有客户端才向Eureka进行注册
    fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
#    单机版  defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  #设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址

provider8001发布到上面三台Eureka集群的配置中

修改provider8001的application.yml

eureka:
  client:                  #客户端注册进Eureka服务列表内
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  #      defaultZone: http://localhost:7001/eureka

启动

访问http://eureka7002.com:7002/可以看到相关信息

Eureka和Zookeeper

Zookeeper遵守CP

当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。 但是zk会出现这样-种情况, 当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s,且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。

Eureka保证AP

Eureka看明白了这一点,因此在设计时就优先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一 致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:

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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值