Springcloud_H版-alibaba学习笔记(六) 服务注册中心-Eureka

六、服务注册中心-Eureka

1.Eureka是什么

Eureka 是 Netflix 开发的,一个基于 REST 服务的,服务注册与发现的组件,以实现中间层服务器的负载平衡和故障转移。

它主要包括两个组件:Eureka Server 和 Eureka Client

Eureka Client:一个Java客户端,用于简化与 Eureka Server 的交互(通常就是微服务中的客户端和服务端)

Eureka Server:提供服务注册和发现的能力(通常就是微服务中的注册中心)
在这里插入图片描述

服务在Eureka上注册,然后每隔30秒发送心跳来更新它们的租约。如果客户端不能多次续订租约,那么它将在大约90秒内从服务器注册表中剔除。注册信息和更新被复制到集群中的所有eureka节点。来自任何区域的客户端都可以查找注册表信息(每30秒发生一次)来定位它们的服务(可能在任何区域)并进行远程调用

2 .Eureka 客户端与服务器之间的通信

服务发现有两种模式:一种是客户端发现模式,一种是服务端发现模式。Eureka采用的是客户端发现模式。

2.1. Register(注册)

Eureka客户端将关于运行实例的信息注册到Eureka服务器。注册发生在第一次心跳。

2.2. Renew(更新 / 续借)

Eureka客户端需要更新最新注册信息(续借),通过每30秒发送一次心跳。更新通知是为了告诉Eureka服务器实例仍然存活。如果服务器在90秒内没有看到更新,它会将实例从注册表中删除。建议不要更改更新间隔,因为服务器使用该信息来确定客户机与服务器之间的通信是否存在广泛传播的问题。

2.3. Fetch Registry(抓取注册信息)

Eureka客户端从服务器获取注册表信息并在本地缓存。之后,客户端使用这些信息来查找其他服务。通过在上一个获取周期和当前获取周期之间获取增量更新,这些信息会定期更新(每30秒更新一次)。获取的时候可能返回相同的实例。Eureka客户端自动处理重复信息。

2.4. Cancel(取消)

Eureka客户端在关机时向Eureka服务器发送一个取消请求。这将从服务器的实例注册表中删除实例,从而有效地将实例从流量中取出。

3.Eureka自我保护模式

如果 Eureka 服务器检测到超过预期数量的注册客户端以一种不优雅的方式终止了连接,并且同时正在等待被驱逐,那么它们将进入自我保护模式。这样做是为了确保灾难性网络事件不会擦除eureka注册表数据,并将其向下传播到所有客户端。

任何客户端,如果连续3次心跳更新失败,那么它将被视为非正常终止,病句将被剔除。当超过当前注册实例15%的客户端都处于这种状态,那么自我保护将被开启。

当自我保护开启以后,eureka服务器将停止剔除所有实例,直到:

它看到的心跳续借的数量回到了预期的阈值之上,或者

自我保护被禁用

默认情况下,自我保护是启用的,并且,默认的阈值是要大于当前注册数量的15%

4.Eureka VS Zookeeper

4.1. Eureka保证AP

Eureka服务器节点之间是对等的,只要有一个节点在,就可以正常提供服务。

Eureka客户端的所有操作可能需要一段时间才能在Eureka服务器中反映出来,随后在其他Eureka客户端中反映出来。也就是说,客户端获取到的注册信息可能不是最新的,它并不保证强一致性

4.2. Zookeeper保证CP

Zookeeper集群中有一个Leader,多个Follower。Leader负责写,Follower负责读,ZK客户端连接到任何一个节点都是一样的,写操作完成以后要同步给所有Follower以后才会返回。如果Leader挂了,那么重新选出新的Leader,在此期间服务不可用。

4.3. 为什么用Eureka

分布式系统大都可以归结为两个问题:数据一致性和防止单点故障。而作为注册中心的话,即使在一段时间内不一致,也不会有太大影响,所以在A和C之间选择A是比较适合该场景的。

5.单机Eureka构建步骤

1.创建工程

cloud-eureka-server7001

2.改pom

<?xml version="1.0" encoding="UTF-8"?>  
<project xmlns="http://maven.apache.org/POM/4.0.0"  
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
    <parent>  
        <artifactId>dt-SpringCloud-2020</artifactId>  
        <groupId>com.dt.springcloud</groupId>  
        <version>1.0.0-SNAPSHOT</version>  
    </parent>  
    <modelVersion>4.0.0</modelVersion>  
  
    <artifactId>cloud-eureka-server7001</artifactId>  
  
    <properties>  
        <maven.compiler.source>8</maven.compiler.source>  
        <maven.compiler.target>8</maven.compiler.target>  
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
    </properties>  
  
    <dependencies>  
        <!--Eureka 服务端 -->  
        <dependency>  
            <groupId>org.springframework.cloud</groupId>  
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>  
        </dependency>  
        <!--引入自定义的cloud-api-common包,可以使用其中的实体-->  
        <dependency>  
            <groupId>com.dt.springcloud</groupId>  
            <artifactId>cloud-api-common</artifactId>  
            <version>1.0.0-SNAPSHOT</version>  
        </dependency>  
        <!--用于页面图形化展示-->  
        <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-web</artifactId>  
        </dependency>  
        <!--用于页面图形化展示-->  
        <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-actuator</artifactId>  
        </dependency>  
        <!--热部署用到 -->  
        <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-devtools</artifactId>  
            <scope>runtime</scope>  
            <optional>true</optional>  
        </dependency>  
        <!-- 省去Get/Set方法 -->  
        <dependency>  
            <groupId>org.projectlombok</groupId>  
            <artifactId>lombok</artifactId>  
            <optional>true</optional>  
        </dependency>  
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->  
        <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-test</artifactId>  
            <scope>test</scope>  
        </dependency>  
    </dependencies>  
  
</project>

3.写application.yml

server:  
  port: 7001  
  
eureka:  
  instance:  
    hostname: localhost #Eureka服务端的实例名称  
  client:  
    #false 表示不向服务中心注册自己,因为本工程即服务中心。  
    register-with-eureka: false  
    #flase 表示该端就是注册中心,职责就是维护注册实例,并不需要去检索服务。  
    fetch-registry: false  
    service-url:  
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  #单机版

4.编写主启动类

package com.dt.springcloud;  
  
import org.springframework.boot.SpringApplication;  
import org.springframework.boot.autoconfigure.SpringBootApplication;  
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;  
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;  
  
/**  
 * Eureka服务端主启动类  
 * 若项目不需要连接数据库,需要增加:@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})  
 */@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})  
@EnableEurekaServer  
public class EurekaApplicatin7001 {  
    public static void main(String[] args) {  
        SpringApplication.run(EurekaApplicatin7001.class, args);  
    }  
}

5.支付服务8001入驻Eureka7001

1.pom添加内容

<!--eureka-server-->  
<dependency>  
    <groupId>org.springframework.cloud</groupId>  
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>  
</dependency>

2.application.yml添加内容

#服务注册Eureka配置  
eureka:  
  client:  
    register-with-eureka: true #表示向注册中心注册自己 默认为true  
    fetch-registry: true #是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡  
    service-url:  
      defaultZone: http://localhost:7001/eureka/ # 入驻地址

3. 主启动类增加注解

@EnableEurekaClient

6.订单服务入住Eureka

操作同上。

7.Eureka界面访问

在这里插入图片描述

6.集群Eureka构建步骤

1.新建cloud-eureka-server7002

2.改POM

pom文件同cloud-eureka-server7001。

3.修改映射配置

找到C:\Windows\System32\drivers\etc路径下的hosts文件。
修改映射配置添加hosts文件。

#springcloud Eureka
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com

刷新hosts文件

ipconfig /flushdns

4.写YMl

7001yml:

server:  
  port: 7001  
  
eureka:  
  instance:  
    hostname: cloud-eureka-service #Eureka服务端的实例名称  
  client:  
    #false 表示不向服务中心注册自己,因为本工程即服务中心。  
    register-with-eureka: false  
    #flase 表示该端就是注册中心,职责就是维护注册实例,并不需要去检索服务。  
    fetch-registry: false  
    service-url:  
      # defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  #单机版  
      defaultZone: http://eureka7002.com:7002/eureka/  #集群版

7002yml:

server:  
  port: 7002  
  
eureka:  
  instance:  
    hostname: cloud-eureka-service2 #Eureka服务端的实例名称  
  client:  
    #false 表示不向服务中心注册自己,因为本工程即服务中心。  
    register-with-eureka: false  
    #flase 表示该端就是注册中心,职责就是维护注册实例,并不需要去检索服务。  
    fetch-registry: false  
    service-url:  
      # defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  #单机版  
      defaultZone: http://eureka7001.com:7001/eureka/  #集群版

5.主启动

同cloud-eureka-server7001。

6.启动

访问http://eureka7001.com:7001/
在这里插入图片描述

访问http://eureka7002.com:7002/ 同上。

7.将支付服务8001微服务发布到上面2台Eureka集群配置中

修改application.yml

#服务注册Eureka配置  
eureka:  
  client:  
    register-with-eureka: true #表示向注册中心注册自己 默认为true  
    fetch-registry: true #是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡  
    service-url:  
      # defaultZone: http://localhost:7001/eureka/ # 入驻单机版Eureka地址  
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 入驻集群版Eureka地址

8.将订单服务80微服务发布到上面2台Eureka集群配置中

同上。

9.测试01

先启动Eureka7001 和7002
再启动支付和订单服务。
访问测试地址:http://localhost/consumer/payment/get/1

7.支付服务集群环境构建

1.参考cloud-privoder-payment8001新建cloud-privoder-payment8002

2.改pom

3.yml

4.主启动

5.业务类

直接复制8001.

6.修改8001/8002的controller

8.负载均衡

1.订单调用方式改造

// 通过在eureka上注册过的微服务名称调用
public static final String PAYMENT_URL="http://CLOUD-PAYMENT-SERVICE";

2.使用@LoadBalanced注解赋予RestTemplate负载均衡的能力

@Bean  
@LoadBalanced  
public RestTemplate getRestTemplate() {  
    return new RestTemplate();  
}

3.bug处理

需要在application.yml中配置以下Eureka信息,不然会报以下错误。
在这里插入图片描述

配置:

instance:  
  instance-id: payment8002   # 服务名称  
  prefer-ip-address: true # 访问路径可以显示ip地址

9.actuator微服务信息完善

1.主机名称:服务名称修改

修改cloud-provoder-payment8001/修改cloud-provoder-payment8002的yml文件

#服务注册Eureka配置  
eureka:  
  client:  
    register-with-eureka: true #表示向注册中心注册自己 默认为true  
    fetch-registry: true #是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡  
    service-url:  
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 入驻集群版Eureka地址  
      # defaultZone: http://localhost:7001/eureka/ # 入驻单机版Eureka地址  
  instance:  
    instance-id: payment8001 # 主机名称

2.访问信息增加IP信息提示

修改cloud-provoder-payment8001/修改cloud-provoder-payment8002的yml文件

#服务注册Eureka配置  
eureka:  
  client:  
    register-with-eureka: true #表示向注册中心注册自己 默认为true  
    fetch-registry: true #是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡  
    service-url:  
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 入驻集群版Eureka地址  
      # defaultZone: http://localhost:7001/eureka/ # 入驻单机版Eureka地址  
  instance:  
    instance-id: payment8002   # 服务名称  
    prefer-ip-address: true # 访问路径可以显示ip地址

10.Eureka服务发现

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

1.修改cloud-provider-payment8001的Controller 增加服务发现方法。

@Value("${spring.application.name}")  
private String applicationName;

@Resource  
private DiscoveryClient discoveryClient;

/**  
 * 服务发现  
 * @return  
 */@GetMapping("/payment/discovery")  
public Object discovery() {  
    List<String> instanceList = discoveryClient.getServices();  
    for (String instance : instanceList) {  
        log.info("服务信息: {}", instance);  
    }  
  
    List<ServiceInstance> instances = discoveryClient.getInstances(applicationName.toUpperCase());  
    for (ServiceInstance instance : instances) {  
        log.info("\n========服务实例信息========= \n  instanceId={} \n  host={}  \n  port:{}  \n  uri={}  \n  metaData={}", instance.getInstanceId(), instance.getHost(), instance.getPort(), instance.getUri(), instance.getMetadata());  
    }  
    return this.discoveryClient;  
}

2.启动类增加注解

@EnableDiscoveryClient

3.访问测试

http://localhost:8001/payment/discovery

4.测试效果

在这里插入图片描述

11.eureka自我保护

1.为什么会产生自我保护机制?

为防止EurekaClient可以正常运行,但是与EurekaServer网络不同的情况下,EurekaServer不会立刻将EurekaClient服务剔除。

2.什么是自我保护机制?

默认情况下,当Eureka server在一定时间内没有收到实例的心跳,便会把该实例从注册表中删除(默认是90秒),但是,如果短时间内丢失大量的实例心跳,便会触发eureka server的自我保护机制。

比如在开发测试时,需要频繁地重启微服务实例,但是我们很少会把eureka server一起重启(因为在开发过程中不会修改eureka注册中心),当一分钟内收到的心跳数大量减少时,会触发该保护机制。可以在eureka管理界面看到Renews threshold和Renews(last min),当后者(最后一分钟收到的心跳数)小于前者(心跳阈值)的时候,触发保护机制,会出现红色的警告:

EMERGENCY!EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT.RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEGING EXPIRED JUST TO BE SAFE.

从警告中可以看到,eureka认为虽然收不到实例的心跳,但它认为实例还是健康的,eureka会保护这些实例,不会把它们从注册表中删掉。

在自我保护模式中,EurekaServer会保护服务注册表中的信息,不再注销任何服务实例。

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

署于CAP 的AP分支。

3.一句话概况

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

4.怎么禁止自我保护

默认情况下自我保护是开启的

eureka.server.enable-self-preservation=true

关闭自我保护,在eureka.注册中心7001中配置

server:  
  port: 7001  
  
eureka:  
  instance:  
    hostname: cloud-eureka-service #Eureka服务端的实例名称  
  client:  
    #false 表示不向服务中心注册自己,因为本工程即服务中心。  
    register-with-eureka: false  
    #flase 表示该端就是注册中心,职责就是维护注册实例,并不需要去检索服务。  
    fetch-registry: false  
    service-url:  
      # defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/  #单机版  
      defaultZone: http://eureka7002.com:7002/eureka/  #集群版  
  server:  
    enable-self-preservation: false #关闭自我保护。当服务不可用时直接被注册中心剔除。  
    eviction-interval-timer-in-ms: 2000 #检测服务是否可用的心跳时间。

在服务提供者8001中配置。

#服务注册Eureka配置  
eureka:  
  client:  
    register-with-eureka: true #表示向注册中心注册自己 默认为true  
    fetch-registry: true #是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡  
    service-url:  
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 入驻集群版Eureka地址  
      # defaultZone: http://localhost:7001/eureka/ # 入驻单机版Eureka地址  
  instance:  
    instance-id: payment8001 # 服务名称  
    prefer-ip-address: true # 访问路径可以显示ip地址  
    #以下为关闭自我保护时配置  
    lease-renewal-interval-in-seconds: 1 # eureka客户端向服务端发送心跳的时间间隔 单位秒 默认30  
    lease-expiration-duration-in-seconds: 2 # eureka 服务端在收到最后一次心跳后等待上限,单位为秒,默认90秒,超时将服务剔除。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值