Eureka服务注册与发现

Eureka服务注册与发现

概念

Netflix在设计Eureka的时候,遵守的是AP原则。

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

原理

Eureka的基本架构

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

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

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

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

Server提供服务注册服务

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

Client是一个Java客户端

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

三大角色

Eureka Server 提供服务注册和发现;

Service Provider 服务提供方将自身服务注册到Eureka,从而使服务消费方能够找到;

Service Consumer 服务消费方从Eureka获取注册服务列表,从而能够消费服务。

目前工程情况

四个模块,三个子模块;

目前Consumer直接调用Provider

构建步骤

step1:EurekaServer服务注册中心Module的建立

  1. 新建microservicecloud-eureka-7001模块
  2. 在pom文件中加入eureka server的依赖
xml 复制代码
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>
  1. 配置YML文件
yaml 复制代码
server:
  port: 7001
eureka:
  instance:
    hostname: localhost #Eureka服务端的实例名字
  client:
    register-with-eureka: false #表示是否向Eureka注册中心注册自己,说白了就是自己不需要注册自己,因为它本身就是注册中心
    fetch-registry: false # false表示自己端就是注册中心,职责就是维护服务实例,并不需要去检查服务
    service-url: #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
  1. 主启动类EurekaServer7001_App
java 复制代码
@SpringBootApplication
@EnableEurekaServer //开启eureka服务,注意它是Server,可以接收别人注册进来
public class EurekaServer_7001 {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServer_7001.class,args);
    }
} 
  1. 测试是否成功
    访问localhost:7001,看到对应如下图标,则启动成功
    由于目前没有服务注册进来,所有列表里是空的

step2:将已有的微服务注册进eureka服务中心

  1. 添加pom中的依赖
xml 复制代码
<!--        将微服务provider注册进eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
  1. YML中添加eureka服务注册配置
yaml 复制代码
#Eureka的配置,服务注册到哪里
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/
  1. 在8001主启动类上新增对应新组件的注解@EnableEurekaClient,本服务启动后会自动注册进eureka服务中
  2. 测试

    下图就是注册进eureka的8001微服务

actuator与注册微服务信息完善


  1. 服务名称修改 :通过修改YML,将绿色超链接修改名称
    instance中的instance-id就是改动后展示的名字
yaml 复制代码
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/
  instance:
    instance-id: springcloud-provider-dept8001
  1. 主机IP信息提示
    继续在instance下方添加prefer-ip-address,设置为true
yaml 复制代码
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/
  instance:
    instance-id: springcloud-provider-dept8001
    prefer-ip-address: true   #访问路径可以显示ip地址
  1. info内容构建 :点开超链接之后的页面中的说明

    修改POM,在8001的pom文件中添加actuator依赖,完善监控
xml 复制代码
<!--完善监控信息-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

在父工程中pom中添加构建build信息

修改8001YML,添加以下信息

yaml 复制代码
info:
  app.name: bruizh.springcloudtest #应用名
  company.name: bruizh   #公司名
  build.artifactId: $project.artifactId$
  build.version: $project.version$

eureka自我保护

如下图红色字样,不是异常,不是报错,是eureka的自我保护机制

导致原因:

某时刻某一个微服务不可用了,eureka不会立刻清理,依旧会对该微服务的信息进行保存

默认情况下,如果eurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90s)。

但是当网络分区故障发生时,微服务与EurekaServer之间无法正常通信,以上行为会非常危险------因为微服务本身时健康的,此时本不应该注销这个服务。

Eureka通过"自我保护模式"来解决这个问题------当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,EurekaServer就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。

当网络故障恢复后,该EurekaServer节点会自动退出自我保护模式。

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

总结:

自我保护模式,是一种应对网络异常的安全保护措施。它的哲学架构是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加健壮、稳定。

在Spring Cloud中,可以使用eureka.server.enable-self-preservation = false,禁用自我保护模式(可以修改默认时间,但不推荐禁用)

step3:服务发现

  1. 在controller里添加服务发现接口 DiscoveryClient client
java 复制代码
/**
     * 获取一些注册进来的微服务的信息
     */
    @GetMapping("/dept/discovery")
    public Object discovery() {
        // 获取微服务列表的清单
        List<String> services = client.getServices();
        System.out.println("discovery=>services:" + services);
        // 得到一个具体的微服务信息,通过具体的微服务id,applicaioinName;
        List<ServiceInstance> instances = client.getInstances("SPRINGCLOUD-PROVIDER-DEPT");
        for (ServiceInstance instance : instances) {
            System.out.println(
                    instance.getHost() + "\t" + // 主机名称
                            instance.getPort() + "\t" + // 端口号
                            instance.getUri() + "\t" + // uri
                            instance.getServiceId() // 服务id
            );
        }
        return this.client;
    }
  1. 主启动类中添加EnableDiscoveryClient注解

  2. 自测

  3. 修改80消费者工程的controller

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

集群配置

域名映射:

3台eureka服务器的yml配置


修改8001集群配置文件,将微服务发布到上面3台eureka集群配置中

测试:

作为服务注册中心,Eureka比Zookeeper好在哪里

Eureka遵守AP;Zookeeper遵守CP

一个分布式系统不可能同时满足CAP。由于区分容错性P在分布式系统中必须要保证的,因此只能在A和C之间进行权衡。

Zookeeper保证CP

当向注册中心查询服务列表时,可以容忍注册中心返回的是几分钟以前的注册信息,但不接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性的要求。

但zk会出现:当master节点因为网络故障与其他节点失去联系时,剩余节点会重新leader选举。问题在于,选举leader时间太长(30~120s),且选举期间整个zk集群不可用,导致在这期间注册服务瘫痪。

在云部署的环境下,因网络问题使zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长选举时间导致注册长期不可用是无法容忍的

传统的关系型数据库(ACID)分别是什么?

A(Atomicity) 原子性

C(Consistency) 一致性

I(Isolation) 独立性

D(Durability) 持久性

Nosql数据库(CAP)分别是什么?

C(Consistency) 强一致性

A(Availability) 可用性

P(Partition tolerance)分区容错性

这三个性质无法同时存在

CAP的3进2

相关推荐
为什么这亚子2 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
ZHOU西口3 小时前
微服务实战系列之玩转Docker(十八)
分布式·docker·云原生·架构·数据安全·etcd·rbac
牛角上的男孩4 小时前
Istio Gateway发布服务
云原生·gateway·istio
JuiceFS5 小时前
好未来:多云环境下基于 JuiceFS 建设低运维模型仓库
运维·云原生
想进大厂的小王6 小时前
Spring-cloud 微服务 服务注册_服务发现-Eureka
微服务·eureka·服务发现
景天科技苑6 小时前
【云原生开发】K8S多集群资源管理平台架构设计
云原生·容器·kubernetes·k8s·云原生开发·k8s管理系统
wclass-zhengge7 小时前
K8S篇(基本介绍)
云原生·容器·kubernetes
颜淡慕潇7 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
昌sit!15 小时前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes
茶馆大橘18 小时前
微服务系列五:避免雪崩问题的限流、隔离、熔断措施
java·jmeter·spring cloud·微服务·云原生·架构·sentinel