Spring Cloud 快速入门(二)微服务中心Eureka

1. Eureka 概述

1.1 Eureka 简介

Eureka 是 Netflix 开发的服务发现框架,本身是一个基于 REST 的服务,主要用于定位运行在 AWS(Amazon Web Services,亚马逊网络服务,亚马逊云)域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,实现 SpringCloud 的服务发现功能。

其实,Eureka 就是一个专门用于服务发现的服务器,一些服务注册到该服务器,而另一些服务通过该服务器查找其所要调用执行的服务。可以充当服务发现服务器的组件很多,例如 Zookeeper、Consul、Eureka 等。

1.2 Eureka 体系架构

官网有个架构图:
在这里插入图片描述

在这里插入图片描述

1.3 CAP 定理

(1) 概念

CAP 定理指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

  • 一致性(C):分布式系统中多个主机之间是否能够保持数据一致的特性。即,当系统数据发生更新操作后,各个主机中的数据仍然处于一致的状态。
  • 可用性(A):系统提供的服务必须一直处于可用的状态,即对于用户的每一个请求,系统总是可以在有限的时间对用户做出响应
  • 分区容错性(P):分布式系统在遇到任何网络分区故障时,仍能够保证对外提供满足一致性和可用性的服务。

(2) 定理

CAP 定理的内容是:对于分布式系统,网络环境相对是不可控的,出现网络分区是不可避免的,因此系统必须具备分区容错性。但系统不能同时保证一致性与可用性。即要么 CP,要么 AP。

(3) base理论

BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent(最终一致性)三个短语的简写。是 CAP 定理对于一致性与可用性权衡的结果。

1.4 Eureka 与 Zookeeper 对比

在这里插入图片描述

Eureka 与 Zookeeper 都可以充当服务中心,那么它们有什么区别呢?它们的区别主要体现在对于 CAP 原则的支持的不同。

  • Eureka:AP (高可用)
    每个Eureka Server都是平等的关系,每个Eureka Server随时可用,甚至全部挂了也没关系…客户端会用本地的注册表
  • zk:CP (强一致性)
    ZK集群中分Leader,Follower,Leader负责数据更新和同步,数据同步完成后才能对外服务,对于使用者来说,在有限时间内返回结果也可以认为可用(Base理论,基本可用、最终一致性、软状态)

1.5 Eureka 的闭源谣言

Eureka 官网的 wiki 中公布了如下内容:
在这里插入图片描述

【原文】The existing open source work on eureka 2.0 is discontinued(终止). The code base(代码库) and artifacts(工程) that were released as part of the existing repository of work on the 2.x branch is considered use at your own risk(被认为在自己的风险中使用).

Eureka 1.x is a core part of Netflix’s service discovery system and is still an active project. Additionally(另外), extension work(扩展工作) on eureka 1.x has moved(推进) internally(内部) within Netflix.

【翻译】现在的关于 eureka 2.0 的开源工作已经终止。已经发布的现存库中的关于 2.x 分支部分的代码库与工程,你的使用将自负风险。

Erueka 1.x 是 Netflix 服务发现系统的核心部分,其仍是一个活跃项目。另外,在 Eureka 1.x 上的扩展工作已经在 Netflix 内部推进。

2. 应用环境搭建

2.1 创建 Eureka 服务中心 00-eurekaserver-8000

这里创建的 Eureka 服务中心,即服务发现服务器。

总步骤:

  • 添加 Eureka Server 依赖
  • 在配置文件中配置 Eureka Server
  • 在启动类上添加@EnableEurekaServer 注解,启动 Eureka Server 功能

2.1.1 创建工程

创建一个 Spring Initializr 工程,命名为 00-eurekaserver-8000,仅导入 Eureka Server 依赖即可。
在这里插入图片描述

工程创建完毕后,在 pom 文件中可以看到如下的版本信息:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.1.2 导入依赖

若你使用的是 JDK6、7、8,那么这些依赖无需导入。而 JDK9 及其以上版本需要导入。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.2.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.abc</groupId>
<artifactId>00-eurekaserver-8000</artifactId>
<version>0.0.1-SNAPSHOT</version>

<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>

<dependencies>

    <!--若你使用的是JDK6、7、8,那么这些依赖无需导入。而JDK9及其以上版本需要导入。
        JAXB,Java Architecture for XML Binding,XML绑定的Java技术。其可以根据
        XML Schema生成Java类。
        JDK9以后,被移到JavaEE了。
    -->
    <!--<dependency>-->
        <!--<groupId>javax.xml.bind</groupId>-->
        <!--<artifactId>jaxb-api</artifactId>-->
        <!--<version>2.2.11</version>-->
    <!--</dependency>-->
    <!--<dependency>-->
        <!--<groupId>com.sun.xml.bind</groupId>-->
        <!--<artifactId>jaxb-core</artifactId>-->
        <!--<version>2.2.11</version>-->
    <!--</dependency>-->
    <!--<dependency>-->
        <!--<groupId>com.sun.xml.bind</groupId>-->
        <!--<artifactId>jaxb-impl</artifactId>-->
        <!--<version>2.2.11</version>-->
    <!--</dependency>-->
    <!--<dependency>-->
        <!--<groupId>javax.activation</groupId>-->
        <!--<artifactId>activation</artifactId>-->
        <!--<version>1.1.1</version>-->
    <!--</dependency>-->


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

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

2.1.3 创建并配置 yml 文件

(1) 配置内容

server:
  port: 8000

eureka:
  instance:
    hostname: localhost    # 指定当前实例主机名
  client:
    register-with-eureka: false  # 指定当前主机是否需要向Eureka Server注册自己
    							 # 因为自己就是注册中心所以不需要
    fetch-registry: false   # 指定当前主机是否需要从Eureka Server下载服务注册表
    						# 因为自己就是注册中心所以不需要
    service-url:
      # 指定当前Client所要连接的eureka Server
      #(单机的时候配不配都没关系,集群的时候需要配置所有Eureka Server地址)
      # 写法一:
      # defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
      # 写法二:
      defaultZone: http://localhost:8000/eureka

这里是Eureka Server,为什么需要配置eureka.client相关配置?
首先从依赖中可以看到有eureka-client的依赖:
在这里插入图片描述
考虑如果是集群的情况,Server和Server之间进行数据同步时,总有一个Server向另一个Server发起同步请求,那么发起请求的这个Server对于另一个Server来说就是客户端,这就是Eureka Server配置client相关的参数的意义所在。(后面配置Eureka集群的时候可以详细看到)

而client和server区别就是server自己就是注册中心,所以不需要往里面注册和下载注册表。

2.1.4 定义 spring boot 启动类

@EnableEurekaServer   // 开启Eureka服务
@SpringBootApplication
public class ApplicationEuerkaServer8000 {
    
     //更换类名,方便区分

    public static void main(String[] args) {
    
    
        SpringApplication.run(ApplicationEuerkaServer8000.class, args);
    }

}

2.1.5 启动测试

在这里插入图片描述

2.2 创建提供者工程 02-provider-8081

总步骤

  • 添加 Eureka Client 依赖
  • 在配置文件中指定要注册的 Eureka Server 地址,指定自己微服务名称

2.2.1 创建工程

复制上一章的 01-provider-8081工程,并重命名为 02-provider-8081。

2.2.2 添加依赖管理及依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.2.RELEASE</version><!-- 修改版本 -->
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<groupId>com.abc</groupId>
<artifactId>02-provider-8081</artifactId>
<version>0.0.1-SNAPSHOT</version>

<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!--eureka客户端依赖-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
    <!-- ...省略了01-provider-8081工程中已经配置的依赖 -->
    ...

</dependencies>

2.2.3 修改 yml 文件

  • 应用名称对于Spring Cloud来说,就是微服务名称:
    在这里插入图片描述

  • 配置当前Client所要连接的eureka Server地址:
    在这里插入图片描述

server:
  port: 8081

spring:
  # 配置spring data jpa
  jpa:
    # 指定是否在spring容器启动时创建表,默认false
    generate-ddl: true
    # 指定在控制台是否显示SQL语句,默认false
    show-sql: true
    # 指定应用重启后不重新更新表内容
    hibernate:
      ddl-auto: none
  # 配置数据源
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql:///test?useUnicode=true&amp;characterEncoding=utf8
    username: root
    password: 111

  # 指定当前微服务名称
  application:
    name: abcmsc-provider-depart

# 配置日志
logging:
  pattern:
    console: level-%level %msg%n

  level:
    root: info
    org.hibernate: info
    # 在show-sql为true时显示SQL中的动态参数值
    org.hibernate.type.descriptor.sql.BasicBinder: trace
    # 在show-sql为true时显示查询结果
    org.hibernate.hql.internal.ast.exec.BasicExecutor: trace
    com.abc: debug

eureka:
  client:
    service-url:
      # 指定当前Client所要连接的eureka Server
       defaultZone: http://localhost:8000/eureka
  instance:
	# 指定当前客户端在注册中心的实例名称
    instance-id: abcmsc-provider-8081

2.2.4 启动类

如果是SpringBoot工程,没有导入spring-cloud-starter-netflix-eureka-client,是需要@EnableEurekaClient注解的,但这里我们是不需要的:

// @EnableEurekaClient     // 仅限于注册中心是Eureka
// @EnableDiscoveryClient  // 注册中心可以是任意的类型,通用性更强
@SpringBootApplication
public class ApplicationProvider8081 {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(ApplicationProvider8081.class, args);
    }

}

在这里插入图片描述

2.2.5 测试

在这里插入图片描述

可以看到如果不指定instance-id的话,默认生成规则是:ip:微服务名:port

2.2.6 actuator 完善微服务 info

在这里插入图片描述

在这里插入图片描述

(1) 提供者工程添加依赖
在提供者工程的 pom 中添加 actuator 监控依赖。

<!--actuator依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

(2) 修改配置文件

info:
  version: 1.0
  app.auth: Reythor
  app.name: abcmsc
  company.name: www.lejia.com
  company.addr: 杭州乐佳国际

(3) 效果
在这里插入图片描述

2.3 创建消费工程 02-consumer-8080

消费者将使用提供者暴露的服务名称(spring.application.name)来消费服务。

总步骤

  • 添加 Eureka Client 依赖
  • 在配置文件中指定要注册的 Eureka Server 地址,指定自己微服务名称
  • 在 JavaConfig 类中为 RestTemplate 添加@LoadBalance 注解,实现负载均衡(主要是想通过负载均衡进行服务发现,自己代码实现服务发现也可以)
  • 修改处理器,将“主机名:端口” -> “提供者微服务名称”

2.3.1 创建工程

复制上一章的 01-consumer-8080工程,并重命名为 02-consumer-8080。

2.3.2 添加依赖管理及依赖

<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>
<!-- 没有做成父工程,每次都要加这个,进行版本管理 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!--actuator依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <!--eureka客户端依赖-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    ...<!-- ...省略了01-consumer-8080工程中已经配置的依赖 -->
</dependencies>

2.3.3 修改 yml 文件

spring:
  # 指定当前微服务对外暴露的名称
  application:
    name: abcmsc-consumer-depart

eureka:
  # 指定eureka服务中心
  client:
    service-url:
      defaultZone: http://localhost:8000/eureka

2.3.4 修改处理器

将原来直连地址“主机名+端口号”,修改为提供者的微服务名称:
在这里插入图片描述

@RestController
@RequestMapping("/consumer/depart")
public class SomeController {
    
    
    @Autowired
    private RestTemplate restTemplate;
    // 直连提供者
    // private static final String SERVICE_PROVIDER = "http://localhost:8081";
    // 要使用微服务名称来从eureka server查找提供者
    private static final String SERVICE_PROVIDER = "http://abcmsc-provider-depart";
    
    @PostMapping("/save")
    public boolean saveHandler(@RequestBody Depart depart) {
    
    

        String url = SERVICE_PROVIDER + "/provider/depart/save";
        return restTemplate.postForObject(url, depart, Boolean.class);
    }
    ...
}

在这里插入图片描述

2.3.5 修改 JavaConfig 类

即使一个提供者,也要负载均衡,否则访问消费者controller会发现报错,主要是因为负载均衡底层会进行服务发现(下载注册表,并通过注册表进行访问),配了这个就不用自己实现下载注册表:
在这里插入图片描述

@Configuration
public class DepartCodeConfigure {
    
    

    // 负载均衡
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
    
    
        return new RestTemplate();
    }
}

负载均衡用的Ribbon后面讲。
在这里插入图片描述

2.3.6 测试

在这里插入图片描述

3. 服务发现 Discovery

在这里插入图片描述

无论是消费者和提供者,对于Eureka来说都是客户端,这里Application代表的是微服务,Status显示的是该微服务的提供者实例状态信息。

现在我们用代码,实现服务发现,即下载注册表,看一下注册表中都有什么东西

在消费者端还是提供者端都一样,对于Eureka都是客户端,我们改提供者:

开启服务发现客户端,修改启动类(之前说过导入对应的依赖后这里可以不用注解):

// 开启服务发现客户端
// @EnableEurekaClient     // 仅限于注册中心是Eureka
// @EnableDiscoveryClient  // 注册中心可以是任意的类型,通用性更强
@SpringBootApplication
public class ApplicationProvider8081 {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(ApplicationProvider8081.class, args);
    }

}

在controller中添加一个方法,进行服务发现:

@RestController
@RequestMapping("/provider/depart")
public class DepartController {
    
    

    // 声明服务发现客户端
    @Autowired
    private DiscoveryClient client;
	...
    @GetMapping("/discovery")
    public List<String> discoveryHandler() {
    
    
	    // 获取服务列表中所有服务名称,即spring.application.name的值
        List<String> services = client.getServices();
        for (String name : services) {
    
    
            // 根据微服务名称获取对应的所有提供者实例主机信息
            List<ServiceInstance> instances = client.getInstances(name);
            // 遍历所有提供者实例主机的详情
            for(ServiceInstance instance : instances) {
    
    
                // 获取当前提供者的唯一标识,service id
                String serviceId = instance.getServiceId();
                String instanceId = instance.getInstanceId();
                // 获取当前提供者主机的host
                String host = instance.getHost();
                Map<String, String> metadata = instance.getMetadata();
                System.out.println("serviceId = " + serviceId);
                System.out.println("instanceId = " + serviceId);
                System.out.println("host = " + host);
                System.out.println("metadata = " + metadata);
            }
        }
        return services;
    }
}

访问:
在这里插入图片描述

看到返回的是所有的微服务名称:
在这里插入图片描述

遍历获取对应微服务的提供者实例主机信息:
在这里插入图片描述

4. Eureka 的自我保护机制

4.1 自我保护机制

在 Eureka 服务页面中看到如下红色字体内容,表示当前 EurekaServer 启动了自我保护机制,进入了自我保护模式。

在这里插入图片描述

【原文】Emergency (紧急情况) ! Eureka may be incorrectly claiming(判断) instances(指微服务主机) are up when they’re not. Renewals(续约,指收到的微服务主机的心跳) are lesser than threshold(阈值) and hence(从此) the instances are not being expired(失效) just to be(只是为了)safe.

【翻译】紧急情况!当微服务主机联系不上时,Eureka 不能够正确判断它们是否处于 up 状态。当续约数量(指收到的微服务主机的心跳)小于阈值时,为了安全,微服务主机将不再失效。

阈值:默认为 正常每分钟应该收到的所有客户端的续约总量 * 85%
图中Renews threshold就是期望每分钟收到续约数的阈值
Renews(last min)是当前最后一分钟实际收到的续约数

默认情况下,EurekaServer 在 90 秒内没有收到到服务列表中某微服务续约心跳,则会自动将该微服务从服务列表中删除。但很多情况下并不是该微服务节点(主机)出了问题,而是由于网络抖动等原因使该微服务无法被 EurekaServer 发现,即无法检测到该微服务主机的心跳。若在短暂时间内网络恢复正常,但由于 EurekaServer 的服务列表中已经没有该微服务,所以该微服务已经无法提供服务了。

在短时间内若 EurekaServer 丢失较多微服务,即 EurekaServer 收到的心跳数量小于阈值,为了保证系统的可用性(AP),给那些由于网络抖动而被认为宕机的客户端“重新复活”的机会,Eureka 会自动进入自我保护模式:服务列表只可读取、写入,不可执行删除操作。当EurekaServer 收到的心跳数量恢复到阈值以上时,其会自动退出 Self Preservation 模式。

4.2 默认值修改

启动自我保护的阈值因子默认为 0.85,即 85%。即 EurekaServer 收到的心跳数量若小于应该收到数量的 85%时,会启动自我保护机制。

自我保护机制默认是开启的,可以通过修改 EurekaServer 中配置文件来关闭。但不建议关闭。

eureka:
  server:
    # 关闭自我保护机制,默认为true代表启动
    enable-self-preservation: false
    # 指定自我保护机制的开启阈值,默认0.85
    # renewal-percent-threshold: 0.75

关闭以后启动查看:

在这里插入图片描述

4.3 自我保护机制属性设置

(1) 演示提供者挂了,Eureka对应的注册信息立马消失

  • 设置Eureka Server端剔除不可用服务的时间窗
    默认60秒,Eureka Server端每60秒检查一次注册表,把所有失效的都删除,是一个定时任务
    eureka:
      server:
        # 关闭自我保护机制
        enable-self-preservation: false
        # 指定自我保护机制的开启阈值
        # renewal-percent-threshold: 0.75
        # 设置server端剔除不可用服务的时间窗,单位毫秒
        eviction-interval-timer-in-ms: 4000
    
  • 修改02-provider-8081工程中的心跳周期
    eureka:
      client:
        service-url:
          # 指定当前Client所要连接的eureka Server
           defaultZone: http://localhost:8000/eureka
      instance:
        instance-id: abcmsc-provider-8081
        # 设置当前Client每1秒向Server发送一次心跳,单位秒,默认30秒
        lease-renewal-interval-in-seconds: 1
        # 指定让Server认定当前Client已经失效的时间,将来可以从注册表中剔除了,单位秒,默认90秒
        lease-expiration-duration-in-seconds: 3
    
  • 演示效果
    效果就是提供者挂了以后4秒后刷新发现注册信息已经删除

(2) 关于Eureka相关配置属性从哪看

  • 从Eureka官网可以找到相关文档,注意不是Spring Cloud Eureka的官网,不过是以类的表现形式
    在这里插入图片描述

  • Client相关配置可以看这个接口:com.netflix.discovery.EurekaClientConfig
    在这里插入图片描述
    每个方法都是Eureka client的相关属性,上面有描述。
    Spring Cloud专门实现该接口,并设置了默认值,在EurekaClientConfigBean这个类:
    在这里插入图片描述

  • Server相关配置可以看:com.netflix.eureka.EurekaServerConfig
    在这里插入图片描述
    SpringCloud的默认实现是EurekaServerConfigBean
    在这里插入图片描述

  • Client相关配置看com.netflix.appinfo.EurekaInstanceConfig
    SpringCloud默认实现是org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean

(3) GUI上的属性值
在这里插入图片描述

查看前面 Eureka 的启动界面,可以看到 Renews threshold 与 Renews(last min)两个数值。这两个值都是瞬时值,而非平均值。就像汽车的瞬时速度与平均速度一样。

  • Renews threshold:Eureka Server 期望每分钟收到客户端的续约总数。

    怎么算的呢?后面分析源码的时候会看到,先简单说一下:
    (注册的客户端数量 * (60 / 预期客户端发送续约心跳的时间间隔)) * 阈值因子
    (注册的客户端数量 * 每分钟每个客户端发送的续约数) * 阈值因子
    每分钟所有客户端的续约总数 * 阈值因子

  • Renews (last min):Eureka Server 实际在最后一分钟收到客户端的续约数量。
  • 说明:若 Renews (last min) < Renews threshold ,就会启动自我保护

5. 服务离线

服务离线,即某服务不能对外提供服务了。服务离线的原因有两种:服务下架与服务下线。这两种方案都是基于 Actuator 监控器实现的。

  • 服务下架:将注册到 Eureka Server 中的 Eureka Client 从 Server 的注册表中移除,这样其他 Client 就无法发现该 Client 了。(就是直接把应用关闭了
  • 服务下线:Client并没有从Eureka Server的注册表中移除(其它Client仍可发现该服务),而是通过修改服务的状态来到达其它 Client 无法调用的目的。(Ribbon负载均衡,底层只会找UP状态的provider)

5.1 准备工作

为 Eureka Client 添加 actuator 依赖。

<!--actuator依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

5.2 服务下架/关闭服务

(1) 修改配置文件
开启shutdown监控终端:

management:
  # 开启所有监控终端
  endpoints:
    web:
      exposure:
        include: "*"
  # 开启shutdown监控终端
  endpoint:
    shutdown:
      enabled: true

(2) 运行测试
启动后,看到服务是OK的:
在这里插入图片描述

在 Restlet 中提交如下 POST 请求即可关闭该应用。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

想要再次上线需要重新启动应用。

5.3 服务平滑上下线

前面的“关闭服务”方式存在一个不足是,若还需要再启用该服务,则必须再次启动该应用。我们也可以通过修改服务的状态为 UP 或 DOWN 来设置提供者是否可用,而无需重启应用。这种方式通常称为服务的平滑上下线

(1) 修改配置文件
这种方式不需要shutdown终端,可以把配置注释掉:

management:
  # 开启所有监控终端
  endpoints:
    web:
      exposure:
        include: "*"
  # 开启shutdown监控终端
#  endpoint:
#    shutdown:
#      enabled: true

(2) 运行测试

  • 在 Restlet 中提交如下 POST 请求,然后再查看 Eureka 页面,发现服务状态已经变为了DOWN。
    在这里插入图片描述
    在这里插入图片描述

  • 改变了状态只是说消费者负载均衡的时候找不到了,如果我们直接访问这个服务,还是可以的。
    访问消费者:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 平滑上线
    在这里插入图片描述
    在这里插入图片描述

6. EurekaServer 集群

这里要搭建的 EurekaServer 集群中包含三个 EurekaServer 节点,其端口号分别为 8100、8200 与 8300。

6.1 设置域名

在 C:\Windows\System32\drivers\etc 的 host 文件中添加如下域名映射信息。
在这里插入图片描述

6.2 创建 00-eurekaserver-8100

(1) 复制工程
复制 00-eurekaserver-8000 工程,并重命名为 00-eurekaserver-8100。
(2) 修改 pom

<groupId>com.abc</groupId>
<artifactId>00-eurekaserver-8100</artifactId>
<version>0.0.1-SNAPSHOT</version>

(3) 修改启动类,更名

@EnableEurekaServer   // 开启Eureka服务
@SpringBootApplication
public class ApplicationEuerkaServer8100 {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(ApplicationEuerkaServer8100.class, args);
    }

}

(4) 修改配置文件
在这里插入图片描述

server:
  port: 8100

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      # 这里配置的是当前集群中所有eureka server地址
      # Server端配置client,意义在于Server之间进行数据同步时的相互访问依赖client
      defaultZone: http://eureka8100.com:8100/eureka,http://eureka8200.com:8200/eureka,http://eureka8300.com:8300/eureka
  instance:
    # 当前主机实例的主机名
    hostname: eureka8100.com

6.3 创建 00-eurekaserver-8200

再以相同的方式再复制出 00-eurekaserver-8200。

6.4 创建 00-eurekaserver-8300

再以相同的方式再复制出 00-eurekaserver-8300。

6.5 修改客户端配置文件

修改客户端工程的配置文件,指定 Eureka 集群的各个主机即可。这里以提供者工程02-provider-8081 为例。
在这里插入图片描述

eureka:
  client:
    service-url:
      # 指定当前Client所要连接的eureka Server
#       defaultZone: http://localhost:8000/eureka
      defaultZone: http://eureka8100.com:8100/eureka,http://eureka8200.com:8200/eureka,http://eureka8300.com:8300/eureka

6.6 效果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41947378/article/details/109012201