• 2--SpringCloud 和 Eureka 周阳老师


    2021:2--SpringCloud 和 Eureka

    https://www.cnblogs.com/coderD/p/14350076.html SpringCloud

    https://www.cnblogs.com/coderD/p/14350073.html SpringCloud 和 Eureka

    https://www.cnblogs.com/coderD/p/14350082.html SpringCloud 和 Zookeeper

    https://www.cnblogs.com/coderD/p/14350086.html SpringCloud-Ribbon/OpenFeign

    https://www.cnblogs.com/coderD/p/14350091.html SpringCloud:Hystrix 断路器

    https://www.cnblogs.com/coderD/p/14350097.html SpringCloud:服务网关 gateway

    https://www.cnblogs.com/coderD/p/14350099.html SpringCloud:Config/Bus

    https://www.cnblogs.com/coderD/p/14350103.html SpringCloud:Stream/Sleuth

    https://www.cnblogs.com/coderD/p/14350110.html SpringCloud Alibaba:Nacos

    https://www.cnblogs.com/coderD/p/14350114.html SpringCloud Alibaba:Sentinel

    https://www.cnblogs.com/coderD/p/14350119.html SpringCloud Alibaba:Seata

    代码:https://gitee.com/xue--dong/spring-cloud

    阳哥脑图:https://gitee.com/xue--dong/spring-cloud

    主要内容

    Eureka服务注册与发现
    单机Eureka构建
    集群Eureka构建
    复制代码
    

    1 Eureka 基础知识

        前面我们没有服务注册中心,也可以服务间调用,为什么还要服务注册?
    
        当服务很多时,单靠代码手动管理是很麻烦的,需要一个公共组件,统一管理多服务之间的相互调用。
    
        Eureka用于服务注册,目前官网已经停止更新。
    复制代码
    

    1.1 什么是服务治理

        SpringCloud 封装了 Netflix 公司开发的Eureka模块来实现服务治理
        
        在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,所以需要使用服务治理,
        管理服务与服务之间依赖关系,可以实现服务调用,负载均衡,容错等,实现服务发现与注册。
        
        n个生产者和n个消费者之间相互调用。
    复制代码
    

    1.2 什么是服务注册与发现

        如果你的服务注册中心只有一台机器,那么只要它一宕机,就会产生单点故障。
        所以一般服务注册中心能配多个就配多个,主要就是为了避免单点故障。
    复制代码
    

    img

    img

    1.3 Eureka 的两个组件

        1.  Eureka Server:提供服务注册的服务。
        
            各个微服务节点通过配置启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册
            表将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。
        
        2.  Eureka Client:微服务通过其和Eureka Server保持通信。
        
            它是一个Java客户端,用于简化微服务和EurekaServer的交互。客户端同时也具备一个内置的,
            使用轮询(round-robin)负载算法的负载均衡器。
            在应用启动后,将会向EurekaServer发送心跳(默认周期30s)。如果EurekaServer在多个心跳
            周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90s)。
    复制代码
    

    2 单机 Eureka 构建步骤

    img

    2.1 建 module:cloud-eureka-server7001

    img

    2.2 改 pom

    1.  1.x和2.x的Eureka依赖对比说明
    
        1.x:
    复制代码
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
    复制代码
        2.x
    复制代码
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    复制代码
    2.  添加依赖
    复制代码
        <dependencies>
            <!--eureka server-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
    
            <!--引入我们自定义的公共api jar包-->
            <dependency>
                <groupId>com.atguigu.springcloud</groupId>
                <artifactId>cloud-api-commons</artifactId>
                <version>${project.version}</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>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    复制代码
    

    2.3. 写 yml

            Eureka服务器 请求地址:
            http://${eureka.instance.hostname}:${server.port}/eureka/
            http:/localhost:7001/eureka/
    复制代码
        server:
          port: 7001
        
        eureka:
          instance:
            hostname: localhost
          client:
            # false表示不向注册中心注册自己(中介不用注册了)
            register-with-eureka: false
            # false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
            fetch-registry: false
        
            service-url: 
              # 设置Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
              defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    复制代码
    

    2.4 主启动类

        注意开启注解:@EnableEurekaServer
        指明该模块作为Eureka注册中心的服务器。
    复制代码
        @EnableEurekaServer
        @SpringBootApplication
        public class EurekaMain7001 {
            public static void main(String[] args) {
                SpringApplication.run(EurekaMain7001.class, args);
            }
        }
    复制代码
    

    2.5 service 类

      Eureka Server不需要写service类
    复制代码
    

    2.6 测试

        启动,发送http://localhost:7001/ 请求
    复制代码
    

    img

        测试成功
    
        只是目前还没有任何实例(微服务)注册尽进来。
    复制代码
    

    img

    3. 微服务注册

    3.1 生产者微服务 8001 注册 EurekaServer

    1.  改POM
        
        添加一个Eureka-Client依赖:
    复制代码
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    复制代码
    2.  改yml:添加如下配置
    复制代码
    eureka:
      client:
        # 表示将自己注册进EurekaServer默认为true
        register-with-eureka: true
        # 表示可以从Eureka抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
        fetch-registry: true
        service-url: 
          defaultZone: http://localhost:7001/eureka
    复制代码
    3.  修改主启动类
    
        添加注解:@EnableEurekaClient。
        指明这是一个Eureka客户端,要注册进EurekaServer中。
    复制代码
        @SpringBootApplication
        @EnableEurekaClient
        public class PaymentMain8001 {
            public static void main(String[] args) {
                SpringApplication.run(PaymentMain8001.class, args);
            }
        }
    复制代码
    4.  测试
    
        启动Payment8001模块:
    复制代码
    

    img

        发现我们的8001服务注册进来了。
        
        红色字体是Eureka的自我保护机制,后面再详细说。
        
        注意:注册进来的服务名,就是我们在该服务yml文件中配置的微服务名
    复制代码
    

    img

    3.2 消费者微服务 80 注册进 EurekaServer

    1.  改POM
        
        添加Eureka Client 依赖
    复制代码
            <!--eureka client-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    复制代码
    2.  改yml
    复制代码
        # 微服务名称
        spring:
          application:
            name: cloud-order-service
            
        eureka:
          client:
            # 表示将自己注册进EurekaServer默认为true
            register-with-eureka: true
            # 表示可以从Eureka抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
            fetch-registry: true
            service-url:
              defaultZone: http://localhost:7001/eureka 
    复制代码
    3.  修改主启动类
    
        添加:@EnableEurekaClient
    
    4.  测试:
        启动消费者80微服务。
        
        刷新http://localhost:7001/页面:消费者80微服务也注册进来了。
    复制代码
    

    img

    5.  测试微服务调用
    复制代码
    

    img

    6.  不想将那个服务注册,就在yml中配置
    复制代码
        eureka:
          client:
            register-with-eureka: false
    复制代码
        重启服务再刷新EurekaServer主页
    复制代码
    

    img

    小结:单机Eureka构建步骤到此就创建完成了。
    复制代码
    

    img

    4 集群 Eureka 构建步骤

        单机版Eureka构建到这就结束了,但是企业中不可能有谁敢说它的服务注册中心是单机版。
        因为没有集群的高可用,就会带来一个严重的问题,单点故障。
        
        1.  Eureka集群原理说明
        2.  EurekaServer集群环境构建步骤
        3.  将支付服务8001微服务发布到上面2台Eureka集群配置中
        4.  将订单服务80微服务发布到上面2台Eureka集群配置中
        5.  测试01
        6.  支付服务提供者8001集群环境构建。
        7.  负载均衡
        8.  测试02
    复制代码
    

    4.1 Eureka 集群原理说明

        Eureka流程原理:
    复制代码
    

    img

        Eureka集群原理:互相注册,相互守望
    复制代码
    

    img

    4.2 EurekaServer 集群环境构建步骤

    4.2.1 新建一个 cloud-eureka-server7002 模块
        1.  新建一个cloud-eureka-server7002模块
    复制代码
    
    4.2.4 pom 依赖
        2.  pom依赖同cloud-eureka-server7001
    复制代码
    
    4.2.4 修改两个 EurekaServer 的 yml 配置
        4.  yml
            
            现在有多台Eureka服务器,所以没台Eureka服务器都要有自己的主机名。
            
            同时Eureka7001和Eureka7002要互相注册。
            
            我们先修改映射配置文件:第3步
            
            1.  Eureka7001的yml
    复制代码
            server:
              port: 7001
            
            eureka:
              instance:
                hostname: eureka7001.com  #eureka服务端的实例名称
              client:
                # false表示不向注册中心注册自己(中介不用注册了)
                register-with-eureka: false
                # false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
                fetch-registry: false
            
                service-url:
                  # 以7001作为服务提供者,向该指定的服务注册中心的位置注册7001服务
                  defaultZone: http://eureka7002.com:7002/eureka/
    复制代码
            2.  Eureka7002的yml
    复制代码
                server:
                  port: 7002
                
                eureka:
                  instance:
                    hostname: eureka7002.com  #eureka服务端的实例名称
                  client:
                    # false表示不向注册中心注册自己(中介不用注册了)
                    register-with-eureka: false
                    # false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
                    fetch-registry: false
                
                    service-url:
                      # 以7002作为服务提供者,向该指定的服务注册中心的位置注册7002服务
                      defaultZone: http://eureka7001.com:7001/eureka/
    复制代码
    
    4.2.3 修改域名映射配置文件
        3.  修改映射配置文件
        
            修改:C:WindowsSystem32driversetc 路径下的host文件
            
            受限于我们只有一台物理机器,我们用不同的端口号来映射同一个地址。
    复制代码
    

    img

            这样修改是是什么意思:
                由于我只有一台电脑,而且将这台电脑也作为服务器。每次我们发送localhost,就会被域名解析器
            解析成127.0.0.1,也就是我们本机的ip回送地址,访问我们本机。
                
                现在我们将eureka7001.com和eureka7002.com作为域名映射到127.0.0.1,那么我们就可以
            模拟请求不同的服务器名。实际上都会解析到我们本机。
            
            注意这个映射修改了不意味着localhost 127.0.0.1之间的映射关系没有,还有。
            即localhost/eureka7001.com/eureka7002.com 都会被域名解析器解析成127.0.0.1
                
            例子1:
                之前的单机的EurekaServer的yml配置:
                server.port=7001
                eureka.instance.hostname=localhost
                eureka.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
                
                那么我通过发送http://localhost:7001/eureka能访问到服务器在本地主机的EurekaServer。
                
            例子2:以两个集群为例
                现在集群的EurekaServer的yml配置
                server.port=7001
                eureka.instance.hostname=eureka7001.com
                eureka.service-url.defaultZone=http://eureka7002.com:7002/eureka/
                
                server.port=7002
                eureka.instance.hostname=eureka7002.com
                eureka.service-url.defaultZone=http://eureka7001.com:7001/eureka/ 
                
                那么这样配置后,我们就可以通过:
                    http://eureka7001.com:7001和http://eureka7002.com:7002来
                    分别访问这两个EurekaServer。
                    同时这两个EurekaServer实现了互相注册。
    复制代码
    
    4.2.5 主配置类
            @SpringBootApplication
            @EnableEurekaServer
            public class EurekaMain7002 {
                public static void main(String[] args) {
                    SpringApplication.run(EurekaMain7002.class, args);
                }
            }
    复制代码
    
    4.2.6 测试
        开启eureka7002 和 eureka7001 这两个服务
        
        测试:  http://localhost:7001/ 和 http://localhost:7002/ 
                
                都成功连接。        
    复制代码
    

    img

        测试:  http://eureka7002.com:7002/ 和 http://eureka7001.com:7001/
      
                都成功连接。
    复制代码
    

    img

        并且实现了两个Euraka服务器的相互注册:
    复制代码
    

    img

    img

    4.2.7 我又测试一个 eureka7003
    server:
      port: 7003
    
    eureka:
      instance:
        hostname: eureka7003.com  #eureka服务端的实例名称
      client:
        # false表示不向注册中心注册自己(中介不用注册了)
        register-with-eureka: false
        # false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
        fetch-registry: false
    
        service-url:
          # 以7001作为服务提供者,向该指定的服务注册中心的位置注册7001服务
          defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7001.com:7001/eureka/
    复制代码
    将其注册到eureka7002和eureka7001中。
    复制代码
    

    img

    5 注册提供者微服务和消费者微服务

    5.1 将提供者服务 8001 微服务发布到上面的 3 台 Eureka 集群配置中

        1.  修改yml
    复制代码
    defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
        2.  其他不改
    复制代码
    

    5.2 将消费者服务 80 微服务发布到上面的 3 台 Eureka 集群配置中

        1.  修改yml
    复制代码
    defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
        2.  其他不改
    复制代码
    

    5.3 测试

        1.  启动顺序
            先启动Eureka 7001/7002/7003
            在启动payment8001,order80
            
        2.  测试:http://eureka7003.com:7003/  成功
    复制代码
    

    img

        3.  测试:http://eureka7001.com:7001/和http://eureka7002.com:7002/
            
            略...
        
        4.  测试order80微服务
    复制代码
    

    img

    img

    6 生产者微服务集群构建

        一个提供者微服务不可能应付所有的消费者微服务。
    复制代码
    

    img

    6.1 新建 cloud-provider-payment8002 微服务

    1.  POM和cloud-provider-payment8001一致
        
        此处有差别:
    复制代码
    

    img

    2.  写yml:
    
        和payment8001一致,只改一个端口。
    复制代码
        # 微服务端口号
        server:
          port: 8002
    复制代码
    3.  主启动类
    复制代码
        @SpringBootApplication
        @EnableEurekaClient
        public class PaymentMain8002 {
            public static void main(String[] args) {
                SpringApplication.run(PaymentMain8002.class, args);
            }
        }
    复制代码
    4.  其他业务类和payment8001一致一致。
    
        其他业务类controller/service/dao 直接复制。
        注意:报错的话,重新alt+enter导下包。
        
        mapper映射文件直接复制
        
        entities通过cloud-api-commons引入。
    复制代码
    

    6.2 修改 controller

    1.  注意:两个生产者微服务在注册中心中的注册名是一样的
        
        这两个微服务对外暴露的都是同一个名字。
    复制代码
    

    img

    2.  消费者微服务调用的是cloud-payment-service这个服务,但是在这个名字下面可能有多台机器。
        那么怎么确定消费者微服务调用哪台机器上的cloud-payment-service服务?
        
        看端口号!
        
    3.  修改两个生产者微服务的controller方法
    
        两个生产者微服务的controller都改成这样。
    复制代码
        public class PaymentController {
        
            @Resource
            private PaymentService paymentService;
        
            @Value("${server.port}") //Value绑定单一的属性值
            private String serverPort;
            
            //传给前端JSON
            @PostMapping(value = "/payment/create")    //写操作POST
            public CommonResult create(@RequestBody Payment payment){
        
                //由于在mapper.xml配置了useGeneratedKeys="true" keyProperty="id",会将自增的id封装到实体类中
                int result = paymentService.create(payment);
        
                log.info("*****插入结果:" + result);
        
                if(result > 0){
                    //restful风格:对象以json串返回到页面
                    return new CommonResult(200, "插入数据库成功,serverPort:"+serverPort, result);
                }else {
                    return new CommonResult(444,"插入数据库失败", null);
                }
            }
            
            //传给前端JSON
            @GetMapping(value = "/payment/get/{id}")    //写操作POST
            public CommonResult getPaymentById(@PathVariable("id") Long id){
        
                Payment payment = paymentService.getPaymentById(id);
        
                log.info("*****查询结果:" + payment);
        
                if(payment != null){
                    return new CommonResult(200, "查询数据库成功,serverPort:"+serverPort, payment);
                }else {
                    return new CommonResult(444,"查询ID:"+id+"没有对应记录", null);
                }
            }
        }
    复制代码
    4.  启动测试:EurekaServer
    
        两个生产者微服务都注册进来了。
    复制代码
    

    img

    5.  测试:生产者微服务
    复制代码
    

    img

    img

    6.  测试:消费者微服务
    复制代码
    

    img

        发现测试若干次不同请求,但是走的都是8001端口的生产者微服务。
    
    7.  原因是我们在消费者微服务中将地址写死了
    复制代码
    

    img

        所以在访问消费者微服务后,消费者微服务再去调用生产者中的方法。
        调用发送的请求一直都是http://localhost:8001/...
        所以一直调用了8001端口的微服务。
        
        那么现在我们不指明具体的微服务端口,指定一个这两个生产者微服务共有的指向:
        即微服务名:CLOUD-PAYMENT-SERVICE
    复制代码
    

    img

        那么消费者再去调用生产者中的方法时,就没有指定具体的端口(具体的微服务)。那么哪一个微服务
        被调用有其他方式来决定。
        
        注意这个说法:
            这个程序的使用者会知道这些微服务的端口或者地址吗?
            消费者使用时,他们根本不想知道具体哪个微服务对应哪个端口或者具体的地址。他只关心微服务的名称。
            他们只想通过看到的微服务名,来使用这些微服务。
            也就是说,我们对外暴露的只能是微服务名,来供使用者
            
    8.  再次测试:
    
        发现报错:
    复制代码
    

    img

        原因:
            这个微服务下面对应着多个微服务,这个微服务名下的多个微服务到底是哪个出来响应,没有办法识别。
    复制代码
    

    6.3 使用 @LoadBlanced 注解赋予 RestTemplate 负载均衡的能力

        1.  以前我们把生产者微服务写死,没关系,因为只有一个生产者微服务,只认一个。
        
        但是现在不能写死了,因为这个微服务名下对应有多个微服务,那么调用时,必须得说明
        哪一个被调用了。
        
        需要规定一种默认的负载均衡机制:@LoadBlanced
    复制代码
    

    img

        我们在这里通过@LoadBlanced赋予了RestTemplate负载均衡的能力
        
        2.  测试:
    复制代码
    

    img

            开启了默认的轮询的负载机制,8001和8002交替出现(循环交替)
            
            提前说一下这就是Ribbon的负载均衡功能默认就是轮询。
            
            即:Ribbon和Eureka整合后Consumer可以直接调用服务而不用再关心地址和端口号,
            且该服务还有负载功能了。
        
            消费者只关注生产者微服务名称,生产者微服务一定是一个集群,那就要有一个默认的
            负载均衡。
    复制代码
    

    7 actuator 微服务信息完善

    7.1 主机名称:服务名称的规范和修改

    img

        1.  按照规范的要求只暴露服务名,不带有主机名。
        
        2.  修改生产者微服务的yml
    复制代码
    

    img

        3.  测试:只暴露服务名
    复制代码
    

    img

        4.  actuator:监测检查
        
            1. 	显示应用的基本信息
    复制代码
    

    img

            2.  显示应用的健康状态(健康检查)
    复制代码
    

    img

    7.2 访问信息有 IP 信息提示

    img

        1.  我现在点击这个微服务的链接,没有ip信息提示。
        
            实际工作中,我们都会说这个微服务是部署在几号机器上面的几号端口。我们要让访问信息
            有ip信息提示。
            
        2.  在每个微服务的yml中添加如下
    复制代码
    

    img

        3.  实现
    复制代码
    

    img

    8 服务发现 Discovery

        1. 我们现在已经实现了这6个微服务的调用。
    复制代码
    

    img

            不排除我们微服务自身,想对外提供功能。那么我们就要拿到在微服务中注册了的微服务的信息。
            比如:主机名称,端口号。
            
        2.  服务发现:
            
            对于注册进eureka里面的微服务,可以通过服务发现来获得这些微服务的信息。
        
        3.  修改cloud-provider-payment8001的controller:写好提供给外部的信息
    复制代码
    

    注意写在 80 和 8002 中也都可以获得所有的微服务信息,这里只是在 8001 上进行测试。

            @Resource  //发现自己的服务信息
            protected DiscoveryClient discoveryClient;
            
            //服务发现Discovery
            @GetMapping(value = "/payment/discovery")
            public Object discovery(){
                //得到服务清单列表
                List<String> services = discoveryClient.getServices();
                for (String service : services) {
                    log.info("*********service: "+ service);
                }
        
                //根据微服务的具体服务名称:得到微服务实例
                List<ServiceInstance> instances = discoveryClient.getInstances("cloud-payment-service");
                for (ServiceInstance instance : instances) {
                    log.info(instance.getServiceId()+"	"+instance.getHost()+"	"+instance.getPort()+"	"+instance.getUri());
                }
        
                return this.discoveryClient;
            }
    复制代码
            注入一个DiscoveryClient类,可以通过其中的两个方法得到我们注册了的服务的信息
                
            3.1 得到服务清单:    
                discoveryClient.getServices();
            
            3.2 根据微服务的具体服务名称:得到微服务实例
                discoveryClient.getInstances("cloud-payment-service");
                
        4.  在8001主启动类开启注解:@EnableDiscoveryClient
        
        5.  测试
            发型请求:http://localhost:8001/payment/discovery
            页面返回的是discoveryClient的json传:
    复制代码
    

    img

            控制台打印的信息:
    复制代码
    

    img

        6.  所以我们今后只要对外暴露这样的一个rest服务接口地址。
            
            调用者就可以访问这个地址获取微服务的信息。
    复制代码
    

    img

    9 eureka 自我保护

    9.1 自我保护

    1.  概述:
        保护模式主要用于一组客户端和EurekaServer之间存在网络分区场景下的保护。一旦进入保护模式,
        EurekaServer将会尝试保护其服务注册表中的信息,不在删除服务注册表中的数据,也就是不会注销
        任何微服务。
        
        
        如果在EurekaServer的首页看到以下这段提示,则说明Eureka进入了保护模式:
    复制代码
    

    img

        一句话:某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该微服务的信息进行保存。
        
        属于CAP里面的AP分支。
        
        Eureka它的设计思想:
        分布式CAP里面的AP分支,某时刻某一个微服务不可用了,Eureka不会立刻清理,
        依旧会对该微服务的信息进行保存。
        
    2.  为什么会产生Eureka自我保护机制
    
        因为可能存在这样的情况:
            EurekaClient可以正常运行,但是与EurekaServer网络不通。
        
        此时EurekaServer不会立刻将EurekaClient服务剔除。
    
    3.  自我保护
    复制代码
    

    img

        如果一定时间内丢失大量该微服务的实例,这时Eureka就会开启自我保护机制,不会剔除该服务。
        因为这个现象可能是因为网络暂时不通,出现了Eureka的假死,拥堵,卡顿。
        稍等会客户端还能正常发送心跳。
        
        这就是CAP里面的AP分支思想。
        
    4.  设计哲学
    
        宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。
    复制代码
    

    9.2 怎么禁止自我保护

        默认是开启自我保护。
        
        禁止自我保护:只要掉线了,立马删掉该服务实例
    
        1.  注册中心:7001
        
            出厂默认,自我保护机制是开启的
            eureka.server.enable-self-preservation=true
            
            默认服务实例掉线9s后删掉
            eviction-interval-timer-in-ms: 9000
            
        2.  修改一下yml
        
            关闭自我保护,并且掉线2s就删除。
    复制代码
    

    img

        3.  启动7001
            
            自我保护已关闭。
    复制代码
    

    img

        4.  修改eurekaClient端8001
        
            它有两个默认的配置
            # Eureka客户端向服务端发送心跳的时间间隔默认30秒
            eureka.instance.lease-renewal-interval-in-seconds: 30       单位秒
            # Eureka服务端在收到最后一次心跳后,90s没有收到心跳,剔除服务
            eureka.instance.lease-expiration-duration-in-seconds: 90    单位秒
            
        5.  测试:
            
            8001能正常注册
    复制代码
    

    img

        6.  模拟发生故障:
                
            关闭8001
            
            如果是默认的话,由于Eureka自我保护机制,会在90s后剔除该服务。
            
            现在关闭了自我保护机制,并且在7001设置了掉线两秒就会剔除。
    复制代码
    

    img

            迅速刷新几下后:该服务被剔除了。
    复制代码
    

    img

  • 相关阅读:
    poj-2376 Cleaning Shifts (排序+贪心)
    AOJ 0525
    POJ -3050 Hopscotch
    POJ-2718 Smallest Difference
    AOJ 0121: Seven Puzzle (BFS DP STL 逆向推理)(转载)
    POJ-3187 Backward Digit Sums (暴力枚举)
    POJ-3669 Meteor Shower(bfs)
    分布式消息系统Kafka初步
    nginx源码学习----内存池
    def文件格式
  • 原文地址:https://www.cnblogs.com/coderD/p/14350073.html
Copyright © 2020-2023  润新知