SpringCloud【进阶】02:Eureka服务注册与发现

01、Eureka基础知识

1、什么是服务治理

Spring Cloud封装了Netflix 公司开发的Eureka模块来实现服务治理

在传统的RPC远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。

2、什么是服务注册与发现

Eureka采用了CS的设计架构,Eureka Sever作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用Eureka的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运行。

在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息比如服务地址通讯地址等以别名方式注册到注册中心上。另一方(消费者服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用。RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理概念)。在任何RPC远程框架中,都会有一个注册中心存放服务地址相关信息(接口地址)
在这里插入图片描述

3、Eureka包含两个组件:Eureka ServerEureka Client

3.1、Eureka Server提供服务注册服务

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

3.2、EurekaClient通过注册中心进行访问

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

心跳理解

你(eureka client)租房子,房东(eureka server)会按照默认周期等待你交房租(心跳),如果几个月都没交租(没有接收到心跳),房东就把你被子扔出去了(移除服务节点)。

02、EurekaServer服务端安装

固定操作:

  • 1、建moudle
  • 2、改pom
  • 3、写yaml
  • 4、主启动
  • 5、业务类

2.1、创建名为cloud-eureka-server7001的Maven工程

2.2、修改pom.xml

<?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>springcloud</artifactId>
        <groupId>com.lian.springcloud</groupId>
        <version>1.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>
    </properties>
    <!--eureka-server-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
        <dependency>
            <groupId>com.lian.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--boot web actuator-->
        <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>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>

</project>

2.3、application.yml

server:
  port: 7001

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

2.4、主启动类

package com.lian.springcloud;

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

@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaMain7001.class,args);
    }
}

2.5、测试EurekaMain7001

浏览器输入http://localhost:7001/回车,会查看到Spring Eureka服务主页

在这里插入图片描述

03、支付模块微服务8001入驻进EurekaServer

EurekaClient端cloud-provider-payment8001将注册进EurekaServer成为服务提供者provider

修改cloud-provider-payment8001

3.1、改pom

提供者8001添加spring-cloud-starter-netflix-eureka-client依赖

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

3.2、写YML

server:
  port: 8001

spring:
  application:
    name: cloud-payment-service

  datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驱动包
    url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: root

#mybatis必须要配置mapper映射,有 resources、class、url 或 package 的4种方式
mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.lian.springcloud.entities    # 所有Entity别名类所在包

#-----------------这步所属操作-----------------------
#提供者要入驻eureka注册中心,所以要添加eureka配置
eureka:
  client:
    #表示是否将自己注册进Eurekaserver默认为true
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka

3.3、主启动类

package com.lian.springcloud;

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

@SpringBootApplication
@EnableEurekaClient		//<-----添加该注解
public class PaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8001.class,args);
    }
}

3.4、测试

启动cloud-provider-payment8001和cloud-eureka-server7001工程

浏览器输入 http://localhost:7001/

主页内的Instances currently registered with Eureka会显示cloud-provider-payment8001的配置文件application.yml设置的应用名cloud-payment-service
在这里插入图片描述

3.5、自我保护机制

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARELESSER THAN THRESHOLD AND HENCFT ARE NOT BEING EXPIRED JUST TO BE SAFE.

紧急情况!EUREKA可能错误地声称实例在没有启动的情况下启动了。续订小于阈值,因此实例不会为了安全而过期。

04、订单微服务80入驻进EurekaServer

EurekaClient端cloud-consumer-order80将注册进EurekaServer成为服务消费者consumer

修改cloud-consumer-order80

4.1、改POM

<!--要注入到eureka就必须要导入eureka客户端依赖-->
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

4.2、改yml

server:
  port: 80

#配置应用名称
spring:
  application:
    name: cloud-order-service

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

4.3、主启动

package com.lian.springcloud;

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

@SpringBootApplication
@EnableEurekaClient    //<--- 添加该标签
public class OrderMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderMain80.class,args);
    }
}

4.4、测试

启动cloud-provider-payment8001、cloud-eureka-server7001和cloud-consumer-order80这个三工程

浏览器输入http://localhost:7001 , 在主页的Instances currently registered with Eureka将会看到cloud-provider-payment8001、cloud-consumer-order80两个工程名
在这里插入图片描述

05、Eureka集群原理说明

5.1、Eureka集群原理说明

在这里插入图片描述
服务注册:将服务信息注册进注册中心

服务发现:从注册中心上获取服务信息

实质:存key服务,取value值

  • 1先启动eureka注主册中心
  • 2启动服务提供者payment支付服务
  • 3支付服务启动后会把自身信息(比服务地址L以别名方式注朋进eureka
  • 4消费者order服务在需要调用接口时,使用服务别名去注册中心获取实际的RPC远程调用地址
  • 5消去者导调用地址后,底屋实际是利用HttpClient技术实现远程调用
  • 6消费者实癸导服务地址后会缓存在本地jvm内存中,默认每间隔30秒更新—次服务调用地址

问题:微服务RPC远程服务调用最核心的是什么?

高可用,试想你的注册中心只有一个only one,万一它出故障了,会导致整个为服务环境不可用。

解决办法:搭建Eureka注册中心集群,实现负载均衡+故障容错

互相注册,相互守望。

06、Eureka集群环境构建

6.1、配置hosts文件

目录:C:\Windows\System32\drivers\etc路径下的hosts文件
在这里插入图片描述

6.2、创建cloud-eureka-server7002工程

  1. 改pom
  2. 改yml
  3. 主启动加@EnableEurekaServer注解

6.3、修改cloud-eureka-server7001配置文件

server:
  port: 7001

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

6.4、修改cloud-eureka-server7002配置文件

server:
  port: 7002

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

6.5、测试成功

两个eureka注册中心,你中有我,我中有你,达成联盟啦
在这里插入图片描述

07、订单支付两微服务注册进Eureka集群

7.1、配置提供者8001和消费者80的yaml文件中,defaultZone

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

08、支付微服务集群配置

8.1、新建cloud-provider-payment8002

  • 1.参考cloud-provicer-payment8001
  • 2.改POM
  • 3.写YML - 端口8002
  • 4.主启动
  • 5.业务类
  • 6.修改8001/8002的Controller,添加属性serverPort
package com.lian.springcloud.controller;

import com.lian.springcloud.entities.CommonResult;
import com.lian.springcloud.entities.Payment;
import com.lian.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * @requestBody可以将请求体中的JSON字符串绑定到相应的bean上
 */
@RestController
@Slf4j
public class PaymentController {

    @Resource
    PaymentService paymentService;

    //添加serverPort,目的做客户端的负载均衡
    @Value("${server.port}")
    private String serverPort;  

    @PostMapping(value = "/payment/create")
    public CommonResult create(@RequestBody Payment payment){
        int result = paymentService.create(payment);

        log.info("*****插入结果:"+result);

        if (result > 0){
            return new CommonResult(200,"插入数据库成功,端口号serverPort是"+serverPort,result);
        } else {
            return new CommonResult(444,"插入数据库失败",null);
        }
    }

    @GetMapping(value = "/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
        Payment payment = paymentService.getPaymentById(id);

        if (payment != null){
            return new CommonResult(200,"查询成功,端口号serverport是"+serverPort,payment);
        } else {
            return new CommonResult(444,"查询失败,没有对应记录,查询id:"+id,null);
        }
    }
}

8.2、测试

eureka启动正常,在支付业务里有两个不同端口的机子
在这里插入图片描述
访问端口8001:http://localhost:8001/payment/get/1
在这里插入图片描述
访问端口8002:http://localhost:8002/payment/get/1
在这里插入图片描述
问题

之前提供者只有1个8001,消费者从80端口访问,最后从8001中获取到信息。

现在提供者8001和提供者8002号机器都提供服务,如果消费者从80端口远程调用服务的话,是会调用到8001端口提供的呢?还是会调用到8002端口提供的呢?

通俗讲:

百度有n台不同端口号的服务器提供服务,但客户端访问端口只有1个,但百度后台是知道每个访问者是通过具体哪台服务器访问到消息的。上面在contrler层加端口的目的也是为了区分被访问到的是哪台服务器

测试从80端口访问:http://localhost/consumer/payment/get/1
在这里插入图片描述

8.3、客户端实现负载均衡

目的是消费者们获取数据时,可以从多个服务器中按照设定规则获取,减轻单台服务器压力,提升消费者体验

8.3.1、cloud-consumer-order80订单服务访问地址不能写死
package com.lian.springcloud.controller;

import com.lian.springcloud.entities.CommonResult;
import com.lian.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

@RestController
@Slf4j
public class OrderController {

    @Autowired
    RestTemplate restTemplate;

    //public static final String PAYMENT_URL = "http://localhost:8001";
    //同一个applicationName下可能有n个具体提供者
    public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";

    @GetMapping("/consumer/payment/create")
    public CommonResult<Payment> create(Payment payment){
        return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class);
    }

    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
        return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
    }

}
8.3.2、使用@LoadBalanced注解赋予RestTemplate负载均衡的能力
package com.lian.springcloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ApplicationContextConfig {

    @Bean
    @LoadBalanced  //使用@LoadBalanced注解赋予RestTemplate负载均衡的能力
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}
8.3.3、测试

浏览器输入 http://localhost/consumer/payment/get/1

结果:负载均衡效果达到,8001/8002端口交替出现
在这里插入图片描述
在这里插入图片描述
Ribbon和Eureka整合后Consumer可以直接调用服务而不用再关心地址和端口号,且该服务还有负载功能。

09、actuator微服务信息完善

主机名称:服务名称修改(也就是将IP地址,换成可读性高的名字)

修改cloud-provider-payment8001,cloud-provider-payment8002
在这里插入图片描述

9.1、修改提供者的服务名称和显示id

server:
  port: 8001

spring:
  application:
    name: cloud-payment-service

  datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驱动包
    url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: root

#mybatis必须要配置mapper映射,有 resources、class、url 或 package 的4种方式
mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.lian.springcloud.entities    # 所有Entity别名类所在包

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

启动eureka,服务名已修改
在这里插入图片描述
配置显示ip地址后
在这里插入图片描述

10、服务发现Discovery

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

10.1、修改cloud-provider-payment8001的Controller

package com.lian.springcloud.controller;

import com.lian.springcloud.entities.CommonResult;
import com.lian.springcloud.entities.Payment;
import com.lian.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * @requestBody可以将请求体中的JSON字符串绑定到相应的bean上
 */
@RestController
@Slf4j
public class PaymentController {

    @Resource
    PaymentService paymentService;

    @Autowired
    DiscoveryClient discoveryClient;

    //添加serverPort,目的做客户端的负载均衡
    @Value("${server.port}")
    private String serverPort;

    @PostMapping(value = "/payment/create")
    public CommonResult create(@RequestBody Payment payment){
        int result = paymentService.create(payment);

        log.info("*****插入结果:"+result);

        if (result > 0){
            return new CommonResult(200,"插入数据库成功,端口号serverPort是"+serverPort,result);
        } else {
            return new CommonResult(444,"插入数据库失败",null);
        }
    }

    @GetMapping(value = "/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
        Payment payment = paymentService.getPaymentById(id);

        if (payment != null){
            return new CommonResult(200,"查询成功,端口号serverport是"+serverPort,payment);
        } else {
            return new CommonResult(444,"查询失败,没有对应记录,查询id:"+id,null);
        }
    }

//-------------------此处操作如下-------------------
    /**
     * 测试服务发现
     */
    @GetMapping(value = "/payment/discovery")
    public Object discovery(){
    	//获取服务application name有几个
        List<String> services = discoveryClient.getServices();
        for (String service : services) {
            log.info("server"+service);
        }
        //根据指定微服务名称,获取具体instance-id实例信息
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        for (ServiceInstance instance : instances) {
            log.info(instance.getInstanceId()+"\t",
                        instance.getHost()+"\t",
                        instance.getPort()+"\t",
                        instance.getUri());
        }
        return this.discoveryClient;
    }
}

10.2、主启动类配置

package com.lian.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient     //<-----eureka客户端添加该注解
@EnableDiscoveryClient  //<-----实现服务发现添加该注解
public class PaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8001.class,args);
    }
}

10.3、测试

http://localhost:8001//payment/discovery
在这里插入图片描述
在这里插入图片描述

11、Eureka自我保护理论知识

1、概述

保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,也就是不会注销任何微服务。

如果在Eureka Server的首页看到以下这段提示,则说明Eureka进入了保护模式:

在这里插入图片描述
一句话:某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该微服务的信息进行保存。

CAP:一致性、可用性、分区分区容错性
eureka属于CAP里面的AP分支

2、为什么会产生Eureka自我保护机制?

为了EurekaClient可以正常运行,防止与EurekaServer网络不通情况下,EurekaServer不会立刻将EurekaClient服务剔除

什么是自我保护模式?

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

自我保护机制∶默认情况下EurekaClient定时向EurekaServer端发送心跳包

如果Eureka在server端在一定时间内(默认90秒)没有收到EurekaClient发送心跳包,便会直接从服务注册列表中剔除该服务,但是在短时间( 90秒中)内丢失了大量的服务实例心跳,这时候Eurekaserver会开启自我保护机制,不会剔除该服务(该现象可能出现在如果网络不通但是EurekaClient为出现宕机,此时如果换做别的注册中心如果一定时间内没有收到心跳会将剔除该服务,这样就出现了严重失误,因为客户端还能正常发送心跳,只是网络延迟问题,而保护机制是为了解决此问题而产生的)。

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

它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。一句话讲解:好死不如赖活着

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

比喻

你找了个女朋友,本来你很有钱,后来破产了,女朋友也没有直接就抛弃你,对你还比较仁慈,过几个月你还没钱再和你分手;

12、怎么禁止自我保护

禁止自我保护功能后,后果就好比这时候你没钱了,女朋友立马就会离开你,毫不留情

12.1、在eurekaServer端7001处设置关闭自我保护机制

出厂默认,自我保护机制是开启的

使用eureka.server.enable-self-preservation = false可以禁用自我保护模式

server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com #eureka服务端的实例名称
  client:
    #false表示不向注册中心注册自己
    register-with-eureka: false
    #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
      #设置与Eureka server交互的地址查询服务和注册服务都需要依赖这个地址。
      defaultZone: http://eureka7002.com:7002/eureka/
  server:
    #关闭自我保护机制,保证不可用服务被及时踢除
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 2000

关闭后eureka主页会显示
在这里插入图片描述

12.2、生产者客户端eureakeClient端8001

配置yaml关闭自我保护机制

server:
  port: 8001

spring:
  application:
    name: cloud-payment-service

  datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驱动包
    url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: root

#mybatis必须要配置mapper映射,有 resources、class、url 或 package 的4种方式
mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.lian.springcloud.entities    # 所有Entity别名类所在包

eureka:
  client:
    #表示是否将自己注册进Eurekaserver默认为true
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetch-registry: true
    service-url:
      #defaultZone: http://localhost:7001/eureka  单机版,下面是集群版
      defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
  #服务名称修改
  instance:
    instance-id: payment8001
    prefer-ip-address: true #访问路径可以显示ip地址
    
    #心跳检测与续约时间
    #开发时没置小些,保证服务关闭后注册中心能即使剔除服务
    #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
    lease-renewal-interval-in-seconds: 1
    #Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
    lease-expiration-duration-in-seconds: 2

12.3、测试

CLOUD-PAYMENT-SERVICE服务下有两个服务实例
在这里插入图片描述
因为8001端口的提供者设置了关闭自我保护机制,关闭8001后,eureka立刻就剔除了此服务
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值