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

相关推荐
susu108301891114 小时前
ubuntu系统删除 Docker 启动的所有容器、卸载 Docker 以及清理 Docker 相关保留路径
ubuntu·docker·eureka
柠檬汁Dev14 小时前
如何用云原生开发,把新项目启动从1天缩短到3分钟
云原生
汪碧康15 小时前
【k8s-1.34.2安装部署】二.kubernets软件、证书、配置、脚本等文件准备
云原生·容器·kubernetes·xkube·k8s管理平台·k8s安装部署·k8s dashboard
ldj202015 小时前
docker-compose对比k8s
云原生·容器·kubernetes
啊勇的编程论坛15 小时前
DeepSeek + Kubernetes 全栈运维赋能指南:智能化云原生运维新时代
运维·云原生·容器·kubernetes·云运维
摆烂z15 小时前
k8s环境脚本
云原生·容器·kubernetes
没有bug.的程序员15 小时前
Sentinel 流控原理深度解析:从SlotChain到热点参数限流的设计哲学
jvm·微服务·云原生·eureka·sentinel·服务发现
阿里云云原生16 小时前
RUM 助力 iOS 应用稳定性:从异常捕获到堆栈还原的全流程分析
人工智能·阿里云·ios·云原生·rum
VermiliEiz16 小时前
二进制文件方式部署k8s(3)
云原生·容器·kubernetes·containerd
企鹅侠客1 天前
使用k8s集群调度GPU
云原生·容器·kubernetes