微服务+springcloud+springcloud alibaba学习笔记【Eureka服务注册中心】(3/9)

news2025/6/13 20:50:56

Eureka服务注册中心 3/9

    • 1、服务注册与发现
      • 1.1 什么是服务治理:
      • 1.2 什么是服务注册与发现:
      • 1.3 Eureka服务注册与发现
    • 2、单机版eureka
      • 2.1 创建module
      • 2.2改pom依赖
      • 2.3写yml配置文件:
      • 2.4主启动类
      • 2.5 修改服务提供者 cloud-provider-payment8001 模块,
      • 2.6 修改消费者 cloud-customer-order80 模块
      • 2.7 启动三个服务:
    • 3、集群版eureka
      • 3.1 集群原理
      • 3.2 构建Eureka集群
      • 3.3 将Cloud-consumer-order80,Cloud-provider-payment8001模块注册到eureka集群中
    • 4、将Cloud-provider-payment模块也配置为集群模式
      • 4.1 创建新模块Cloud-provider-payment8002
      • 4.2 pom文件,复制8001的
      • 4.3 配置文件复制8001的
      • 4.4 主启动类,复制8001的
      • 4.5 mapper,service,controller都复制一份
      • 4.6 RestTemplate开启负载均衡注解
      • 4.7 修改服务主机名和ip在eureka的web上显示
    • 5、eureka服务发现
      • 5.1 首先添加一个注解,在controller中
      • 5.2 在主启动类上添加一个注解
    • 6、Eureka自我保护
      • 6.1 在 Eureka Server 的模块中的 yml 文件进行配置:
      • 6.2 服务提供者配置
      • 6.3 eureka配置项

1、服务注册与发现

当服务很多时,单靠代码手动管理是很麻烦的,需要一个公共组件,统一管理多服务,包括服务是否正常运行等

上面只有两个微服务,通过 RestTemplate ,是可以相互调用的,但是当微服务项目的数量增大,就需要服务注册中心。目前没有学习服务调用相关技术,使用 SpringCloud 自带的 RestTemplate 来实现RPC。

1.1 什么是服务治理:

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

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

1.2 什么是服务注册与发现:

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

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

在这里插入图片描述

1.3 Eureka服务注册与发现

Eureka 官方停更不停用,以后可能用的越来越少。

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

Eureka 分为 Eureka Server 和 Eureka Client及服务端和客户端。Eureka Server为注册中心,是服务端,而服务提供者和消费者即为客户端,消费者也可以是服务者,服务者也可以是消费者。同时Eureka Server在启动时默认会注册自己,成为一个服务,所以Eureka Server也是一个客户端,这是搭建Eureka集群的基础。

==Eureka Client:==一个Java客户端,用于简化与 Eureka Server 的交互(通常就是微服务中的客户端和服务端)。通过注册中心进行访问。是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(roundrobin)负载算氵去的负载均衡器
在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)

==Eureka Server:==提供服务注册服务,各个微服务节,通过配置启动后,会在Eureka Serverc中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点信息,服务节点的信息可以在界面中直观看到。
服务在Eureka上注册,然后每隔30秒发送心跳来更新它们的租约。如果客户端不能多次续订租约,那么它将在大约90秒内从服务器注册表中剔除。注册信息和更新被复制到集群中的所有eureka节点。来自任何区域的客户端都可以查找注册表信息(每30秒发生一次)来定位它们的服务(可能在任何区域)并进行远程调用。

服务提供者向注册中心注册服务,并每隔30秒发送一次心跳,就如同人还活着存在的信号一样,如果Eureka在90秒后还未收到服务提供者发来的心跳时,那么它就会认定该服务已经死亡就会注销这个服务。这里注销并不是立即注销,而是会在60秒以后对在这个之间段内“死亡”的服务集中注销,如果立即注销,势必会对Eureka造成极大的负担。这些时间参数都可以人为配置。

Eureka还有自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,所以不会再接收心跳,也不会删除服务。

客户端消费者会向注册中心拉取服务列表,因为一个服务器的承载量是有限的,所以同一个服务会部署在多个服务器上,每个服务器上的服务都会去注册中心注册服务,他们会有相同的服务名称但有不同的实例id,所以拉取的是服务列表。我们最终通过负载均衡来获取一个服务,这样可以均衡各个服务器上的服务。

在这里插入图片描述

2、单机版eureka

  • 消费者端口80,提供者端口8001。

  • Eureka端口7001
    在这里插入图片描述

2.1 创建module

Cloud_eureka_server_7001

在这里插入图片描述

2.2改pom依赖

eureka版本说明:

<!--新版本2020.02-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>


<!--旧版本2018-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

pom文件:

在这里插入代码片

2.3写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主启动类

@EnableEurekaServer
最后写主启动类,如果启动报错,说没有配置 DataSource ,就在 主启动类的注解加上 这样的配置:

package com.tigerhhzz.springcloud;

import lombok.extern.slf4j.Slf4j;
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;

@Slf4j
// exclude :启动时不启用 DataSource的自动配置检查
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaServer   // 表示它是服务注册中心
public class EurekaServerMain7001 {
    public static void main(String[] args){
        SpringApplication.run(EurekaServerMain7001.class, args);
        log.info("EurekaServerMain7001启动成功~~~~~~~~~~~~~~~~~~~");
    }
}

启动测试,访问 7001 端口
在这里插入图片描述

2.5 修改服务提供者 cloud-provider-payment8001 模块,

  1. 在 pom 文件的基础上引入 eureka 的client包,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>springcloud2023</artifactId>
        <groupId>com.tigerhhzz.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>Cloud-provider-payment8001</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>

        <!-- 服务注册中心的客户端端 eureka-client -->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!-- 引入自己定义的api通用包 -->
        <dependency>
            <groupId>com.tigerhhzz.springcloud</groupId>
            <artifactId>Cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <!--这个和web要写到一块-->
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>
        <!--mysql-connector-java-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--jdbc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </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>

</project>
  1. 主启动类 加上注解 :@EnableEurekaClient
package com.tigerhhzz.springcloud;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

import java.io.Console;


/**
 * @author Administrator
 */
@Slf4j
@SpringBootApplication
@EnableEurekaClient
public class PaymentMain8001 {
    public static void main(String[] args){
        SpringApplication.run(PaymentMain8001.class, args);
        log.info("PaymentMain8001启动成功~~~~~~~~~~~~~~~~~~~");
    }
}
  1. yml 文件添加关于 Eureka 的配置:
server:
  port: 8001

spring:
  application:
    name: Cloud-provider-payment8001
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springcloud-tigerhhzz?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.tigerhhzz.springcloud.entities  # 所有Entity 别名类所在包


eureka:
  client:
    # 注册进 Eureka 的服务中心
    register-with-eureka: true
    # 检索 服务中心 的其它服务
    fetch-registry: true
    service-url:
      # 设置与 Eureka Server 交互的地址
      defaultZone: http://localhost:7001/eureka/

2.6 修改消费者 cloud-customer-order80 模块

  1. 在 pom 文件的基础上引入 eureka 的client包,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>springcloud2023</artifactId>
        <groupId>com.tigerhhzz.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>Cloud-consumer-order80</artifactId>



    <dependencies>

        <!-- 服务注册中心的客户端端 eureka-client -->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!-- 引入自己定义的api通用包 -->
        <dependency>
            <groupId>com.tigerhhzz.springcloud</groupId>
            <artifactId>Cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </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.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>

</project>
  1. 主启动类 加上注解 :@EnableEurekaClient
package com.tigerhhzz.springcloud;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@Slf4j
@SpringBootApplication
@EnableEurekaClient
public class OrderMain80{
    public static void main(String[] args){
        SpringApplication.run(OrderMain80.class,args);
        log.info("OrderMain80启动成功~~~~~~~~~~~~~~~~~~~");
    }
}

  1. yml 文件添加关于 Eureka 的配置:
server:
  port: 80

spring:
  application:
    name: Cloud-consumer-order80

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka/



2.7 启动三个服务:

在这里插入图片描述
在这里插入图片描述

3、集群版eureka

3.1 集群原理

  1. 就是pay模块启动时,注册自己,并且自身信息也放入eureka
  2. order模块,首先也注册自己,放入信息,当要调用pay时,先从eureka拿到pay的调用地址
  3. 通过HttpClient调用 ,并且还会缓存一份到本地,每30秒更新一次

在这里插入图片描述

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

高可用,试想你的注册中心只有一个。onlyone,它出故障了那就呵呵了,会导致整个为服务环境不可用,所以要搭建Eureka注册中心集群,实现负载均衡+故障容错

Eureka 集群的原理:

== 相互注册,互相守望。== 每台Eureka服务器都有集群里其他Eureka服务器地址的信息

在这里插入图片描述

3.2 构建Eureka集群

在写配置文件前,修改一下主机的hosts文件

模拟多个 为了不用输出C:\Windows\System32\drivers\etc\hosts 添加如下:

127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
  1. 创建 Cloud-eureka-server7002模块
    这也就是第二个 Eureka 服务注册中心,pom 文件和 主启动类,与第一个Cloud-eureka-server7002一致。

     pom文件:
    
      粘贴7001的即可
    
<?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>springcloud2023</artifactId>
        <groupId>com.tigerhhzz.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>Cloud-eureka-server7002</artifactId>

    <dependencies>
        <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-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- 引入自己定义的api通用包 -->
        <dependency>
            <groupId>com.tigerhhzz.springcloud</groupId>
            <artifactId>Cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

</project>
	配置文件:
  1. 修改7001项目的application.yml配置文件

首先修改之前的7001的eureka项目,因为多个eureka需要互相注册

7001项目的application.yml配置文件

server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com  # eureka 服务器的实例地址  # eureka 服务端的实例名称

  client:
    # false 代表不向服务注册中心注册自己,因为它本身就是服务中心
    register-with-eureka: false
    # false 代表自己就是服务注册中心,自己的作用就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
      ## 一定要注意这里的地址,这是搭建集群的关键。反过来写,写的是集群中其他Eureka服务器的地址
      defaultZone: http://eureka7002.com:7002/eureka/

  1. 修改7002项目的application.yml配置文件

         7002也是一样的,只不过端口和地址改一下
    

7002项目的application.yml配置文件

server:
  port: 7002

eureka:
  instance:
    hostname: eureka7002.com  # eureka 服务端的实例名称

  client:
    # false 代表不向服务注册中心注册自己,因为它本身就是服务中心
    register-with-eureka: false
    # false 代表自己就是服务注册中心,自己的作用就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
      ## 一定要注意这里的地址,这是搭建集群的关键。反过来写,写的是集群中其他Eureka服务器的地址
      defaultZone: http://eureka7001.com:7001/eureka/

eureka.instance.hostname 才是启动以后 本 Server 的注册地址,而 service-url 是 map 类型,只要保证 key:value 格式就行,它代表 本Server 指向了那些 其它Server 。利用这个,就可以实现Eureka Server 相互之间的注册,从而实现集群的搭建。

  1. 主启动类:

复制7001的即可

7001主启动类:

package com.tigerhhzz.springcloud;

import lombok.extern.slf4j.Slf4j;
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;

@Slf4j
// exclude :启动时不启用 DataSource的自动配置检查
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaServer   // 表示它是服务注册中心
public class EurekaServerMain7001 {
    public static void main(String[] args){
        SpringApplication.run(EurekaServerMain7001.class, args);
        log.info("EurekaServerMain7001启动成功~~~~~~~~~~~~~~~~~~~");
    }
}

7002主启动类:

package com.tigerhhzz.springcloud;

import lombok.extern.slf4j.Slf4j;
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;

@Slf4j
// exclude :启动时不启用 DataSource的自动配置检查
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaServer   // 表示它是服务注册中心
public class EurekaServerMain7002 {
    public static void main(String[] args){
        SpringApplication.run(EurekaServerMain7002.class, args);
        log.info("EurekaServerMain7002启动成功~~~~~~~~~~~~~~~~~~~");
    }
}


  1. 然后启动7001,7002即可

在这里插入图片描述

3.3 将Cloud-consumer-order80,Cloud-provider-payment8001模块注册到eureka集群中

  1. 只需要修改Cloud-consumer-order80,Cloud-provider-payment8001模块的配置文件即可:

Cloud-consumer-order80配置文件

server:
  port: 80

spring:
  application:
    name: Cloud-consumer-order80

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
#      defaultZone: http://localhost:7001/eureka/   #单机版
      defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/   #集群版


,Cloud-provider-payment8001模块配置文件

server:
  port: 8001

spring:
  application:
    name: Cloud-provider-payment8001
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springcloud-tigerhhzz?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.tigerhhzz.springcloud.entities  # 所有Entity 别名类所在包


eureka:
  client:
    # 注册进 Eureka 的服务中心
    register-with-eureka: true
    # 检索 服务中心 的其它服务
    fetch-registry: true
    service-url:
      # 设置与 Eureka Server 交互的地址
#      defaultZone: http://localhost:7001/eureka/  #单机版
       defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/ #集群版
  1. 两个模块都修改上面的都一样即可

然后启动两个模块

要先启动7001,7002,然后是pay模块8001,然后是order(80)
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4、将Cloud-provider-payment模块也配置为集群模式

4.1 创建新模块Cloud-provider-payment8002

4.2 pom文件,复制8001的

Cloud-provider-payment8002模块的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>springcloud2023</artifactId>
        <groupId>com.tigerhhzz.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>Cloud-provider-payment8002</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>

        <!-- 服务注册中心的客户端端 eureka-client -->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!-- 引入自己定义的api通用包 -->
        <dependency>
            <groupId>com.tigerhhzz.springcloud</groupId>
            <artifactId>Cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <!--这个和web要写到一块-->
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>
        <!--mysql-connector-java-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--jdbc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </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>

</project>

4.3 配置文件复制8001的

端口修改一下,改为8002

Cloud-provider-payment8001模块的配置文件

server:
  port: 8001

spring:
  application:
#    name: Cloud-provider-payment8001
     name: cloud-provider-service  # 这次重点是这里,两个要写的一样,这是这个集群的关键
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springcloud-tigerhhzz?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.tigerhhzz.springcloud.entities  # 所有Entity 别名类所在包


eureka:
  client:
    # 注册进 Eureka 的服务中心
    register-with-eureka: true
    # 检索 服务中心 的其它服务
    fetch-registry: true
    service-url:
      # 设置与 Eureka Server 交互的地址
#      defaultZone: http://localhost:7001/eureka/  #单机版
       defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/ #集群版

Cloud-provider-payment8002模块的配置文件

server:
  port: 8002

spring:
  application:
#    name: Cloud-provider-payment8002
    name: cloud-provider-service  # 这次重点是这里,两个要写的一样,这是这个集群的关键
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springcloud-tigerhhzz?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.tigerhhzz.springcloud.entities  # 所有Entity 别名类所在包


eureka:
  client:
    # 注册进 Eureka 的服务中心
    register-with-eureka: true
    # 检索 服务中心 的其它服务
    fetch-registry: true
    service-url:
      # 设置与 Eureka Server 交互的地址
#      defaultZone: http://localhost:7001/eureka/  #单机版
       defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/ #集群版

服务名称不用改,用一样的

4.4 主启动类,复制8001的

package com.tigerhhzz.springcloud;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;


/**
 * @author Administrator
 */
@Slf4j
@SpringBootApplication
@EnableEurekaClient
public class PaymentMain8002 {
    public static void main(String[] args){
        SpringApplication.run(PaymentMain8002.class, args);
        log.info("PaymentMain8002启动成功~~~~~~~~~~~~~~~~~~~");
    }
}

4.5 mapper,service,controller都复制一份

然后就启动服务即可

此时访问order模块,发现并没有负载均衡到两个pay,模块中,而是只访问8001

虽然我们是使用RestTemplate访问的微服务,但是也可以负载均衡的

4.6 RestTemplate开启负载均衡注解

注意这样还不可以,需要让RestTemplate开启负载均衡注解,还可以指定负载均衡算法,默认轮询

修改Cloud-consumer-order80模块中的config包下面的ApplicationContextConfig类:

package com.tigerhhzz.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;

/**
 * @author tigerhhzz
 * @date 2023/4/8 22:52
 */
@Configuration
public class ApplicationContextConfig {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
        /*
        RestTemplate提供了多种便捷访问远程http服务的方法,
        是一种简单便捷的访问restful服务模板类,是spring提供的用于rest服务的客户端模板工具集
        */
    }
}

4.7 修改服务主机名和ip在eureka的web上显示

actuator让Eureka显示ip
为了在微服务Eureka控制台能看到我们的某个具体服务是在哪台服务器上部署的,我们需要配置一些内容。

修改 提供者在Eureka 注册中心显示的 主机名:即修改eureka:instance:instance-id:和eureka:instance:prefer-ip-address:

修改Cloud-provider-payment8001模块的配置文件:

server:
  port: 8001

spring:
  application:
#    name: Cloud-provider-payment8001
     name: cloud-provider-service  # 这次重点是这里,两个要写的一样,这是这个集群的关键
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springcloud-tigerhhzz?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.tigerhhzz.springcloud.entities  # 所有Entity 别名类所在包


eureka:
  client:
    # 注册进 Eureka 的服务中心
    register-with-eureka: true
    # 检索 服务中心 的其它服务
    fetch-registry: true
    service-url:
      # 设置与 Eureka Server 交互的地址
#      defaultZone: http://localhost:7001/eureka/  #单机版
       defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/ #集群版
       
  instance: #重点,和client平行
    instance-id: payment8001 # 每个提供者的id不同,显示的不再是默认的项目名
    prefer-ip-address: true # 访问路径可以显示ip地址

修改Cloud-provider-payment8002模块的配置文件:

server:
  port: 8002

spring:
  application:
#    name: Cloud-provider-payment8002
    name: cloud-provider-service  # 这次重点是这里,两个要写的一样,这是这个集群的关键
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springcloud-tigerhhzz?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.tigerhhzz.springcloud.entities  # 所有Entity 别名类所在包


eureka:
  client:
    # 注册进 Eureka 的服务中心
    register-with-eureka: true
    # 检索 服务中心 的其它服务
    fetch-registry: true
    service-url:
      # 设置与 Eureka Server 交互的地址
#      defaultZone: http://localhost:7001/eureka/  #单机版
       defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/ #集群版
       
  instance: #重点,和client平行
    instance-id: payment8002 # 每个提供者的id不同,显示的不再是默认的项目名
    prefer-ip-address: true # 访问路径可以显示ip地址

在这里插入图片描述

5、eureka服务发现

对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息。(即我们前面可视化页面的信息)

5.1 首先添加一个注解,在controller中

package com.tigerhhzz.springcloud.controller;

import com.tigerhhzz.springcloud.entities.CommonResult;
import com.tigerhhzz.springcloud.entities.Payment;
import com.tigerhhzz.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
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;

@RestController   //必须是这个注解,因为是模拟前后端分离的restful风格的请求,要求每个方法返回 json
@Slf4j
public class PaymentController {

  @Resource
  private PaymentService paymentService;

    //服务发现
    @Resource
    private DiscoveryClient discoveryClient;


    @Value("${server.port}")
    private String serverPort;

  @PostMapping(value = "/payment/create")
  //	    注意这里的 @RequestBody  是必须要写的,虽然 MVC可以自动封装参数成为对象,
  //      但是当消费者项目调用,它传参是 payment 整个实例对象传过来的, 即Json数据,因此需要写这个注解
  //
  public CommonResult create(@RequestBody Payment payment){
      int result = paymentService.create(payment);
      log.info("****插入结果:" + result);
      if(result > 0){
          return new CommonResult(200, "插入数据库成功", result);
      }
      return new CommonResult(400, "插入数据库失败", null);
  }

  @GetMapping(value = "/payment/{id}")
  public CommonResult getPaymentById(@PathVariable("id")Long id){
      Payment result = paymentService.getPaymentById(id);
      log.info("****查询结果:" + result);
      if(result != null){
          return new CommonResult(200, "查询成功", result);
      }
      return new CommonResult(400, "没有对应id的记录", null);
  }

    @GetMapping("queryAllByLimit")
    public CommonResult<List<Payment>> queryAllByLimit(@RequestParam(defaultValue = "0") int offset,
                                                       @RequestParam(defaultValue = "10") int limit) {
        List<Payment> payment = this.paymentService.queryAllByLimit(offset, limit);

        return new CommonResult<>(200, "select success, serverPort:" + serverPort, payment);
    }

    @GetMapping("/customer/discovery")
    public Object discovery(){
        //获得服务清单列表
        List<String> services = discoveryClient.getServices();
        for(String service: services){
            log.info("*****service: " + service);
        }
        // 根据具体服务进一步获得该微服务的信息
        List<ServiceInstance> instances = discoveryClient.getInstances("cloud-provider-service");
        for(ServiceInstance serviceInstance:instances){
            log.info(serviceInstance.getServiceId() + "\t" + serviceInstance.getHost()
                    + "\t" + serviceInstance.getPort() + "\t" + serviceInstance.getUri());
        }
        return this.discoveryClient;
    }
}


5.2 在主启动类上添加一个注解

  • 在主启动类上添加注解:@EnableDiscoveryClient
package com.tigerhhzz.springcloud;

import lombok.extern.slf4j.Slf4j;
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;

import java.io.Console;


/**
 * @author Administrator
 */
@Slf4j
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class PaymentMain8001 {
    public static void main(String[] args){
        SpringApplication.run(PaymentMain8001.class, args);
        log.info("PaymentMain8001启动成功~~~~~~~~~~~~~~~~~~~");
    }
}

打印输出:
在这里插入图片描述

6、Eureka自我保护

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

禁止自我保护:(如果想)

6.1 在 Eureka Server 的模块中的 yml 文件进行配置:

Cloud-eureka-server7001配置文件:

server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com  # eureka 服务器的实例地址  # eureka 服务端的实例名称

  client:
    # false 代表不向服务注册中心注册自己,因为它本身就是服务中心
    register-with-eureka: false
    # false 代表自己就是服务注册中心,自己的作用就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
      ## 一定要注意这里的地址,这是搭建集群的关键。反过来写,写的是集群中其他Eureka服务器的地址
      defaultZone: http://eureka7002.com:7002/eureka/

  server: # 与client平行
    # 关闭自我保护机制,保证不可用该服务被及时剔除
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 2000

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服务器的地址
      defaultZone: http://eureka7001.com:7001/eureka/

  server: # 与client平行
    # 关闭自我保护机制,保证不可用该服务被及时剔除
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 2000

6.2 服务提供者配置

修改 Eureka Client —Cloud-provider-payment8001模块的 心跳间隔时间:

server:
  port: 8001

spring:
  application:
#    name: Cloud-provider-payment8001
     name: cloud-provider-service  # 这次重点是这里,两个要写的一样,这是这个集群的关键
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springcloud-tigerhhzz?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.tigerhhzz.springcloud.entities  # 所有Entity 别名类所在包


eureka:
  client:
    # 注册进 Eureka 的服务中心
    register-with-eureka: true
    # 检索 服务中心 的其它服务
    fetch-registry: true
    service-url:
      # 设置与 Eureka Server 交互的地址
#      defaultZone: http://localhost:7001/eureka/  #单机版
       defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/ #集群版

  instance: #重点,和client平行
    instance-id: payment8001 # 每个提供者的id不同,显示的不再是默认的项目名
    prefer-ip-address: true # 访问路径可以显示ip地址
    # Eureka客户端像服务端发送心跳的时间间隔,单位s,默认30s
    least-renewal-interval-in-seconds: 1
    # Rureka服务端在收到最后一次心跳后等待时间上线,单位为s,默认90s,超时将剔除服务
    least-expiration-duration-in-seconds: 2

修改 Eureka Client —Cloud-provider-payment8002模块的 心跳间隔时间:

server:
  port: 8002

spring:
  application:
#    name: Cloud-provider-payment8002
    name: cloud-provider-service  # 这次重点是这里,两个要写的一样,这是这个集群的关键
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springcloud-tigerhhzz?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.tigerhhzz.springcloud.entities  # 所有Entity 别名类所在包


eureka:
  client:
    # 注册进 Eureka 的服务中心
    register-with-eureka: true
    # 检索 服务中心 的其它服务
    fetch-registry: true
    service-url:
      # 设置与 Eureka Server 交互的地址
#      defaultZone: http://localhost:7001/eureka/  #单机版
       defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/ #集群版

  instance: #重点,和client平行
    instance-id: payment8002 # 每个提供者的id不同,显示的不再是默认的项目名
    prefer-ip-address: true # 访问路径可以显示ip地址
    # Eureka客户端像服务端发送心跳的时间间隔,单位s,默认30s
    least-renewal-interval-in-seconds: 1
    # Rureka服务端在收到最后一次心跳后等待时间上线,单位为s,默认90s,超时将剔除服务
    least-expiration-duration-in-seconds: 2

6.3 eureka配置项

在注册服务之后,服务提供者会维护一个心跳用来持续高速Eureka Server,“我还在持续提供服务”,否则Eureka Server的剔除任务会将该服务实例从服务列表中排除出去。我们称之为服务续约。
面是服务续约的两个重要属性:

(1)eureka.instance.lease-expiration-duration-in-seconds
leaseExpirationDurationInSeconds,表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance。
默认为90秒
如果该值太大,则很可能将流量转发过去的时候,该instance已经不存活了。
如果该值设置太小了,则instance则很可能因为临时的网络抖动而被摘除掉。
该值至少应该大于leaseRenewalIntervalInSeconds

(2)eureka.instance.lease-renewal-interval-in-seconds

  • leaseRenewalIntervalInSeconds,表示eureka client发送心跳给server端的频率。如果在leaseExpirationDurationInSeconds后,server端没有收到client的心跳,则将摘除该instance。除此之外,如果该instance实现了HealthCheckCallback,并决定让自己unavailable的话,则该instance也不会接收到流量。
    默认30秒

  • eureka.client.registry-fetch-interval-seconds :表示eureka client间隔多久去拉取服务注册信息,默认为30秒,对于api-gateway,如果要迅速获取服务注册状态,可以缩小该值,比如5秒

  • eureka.server.enable-self-preservation
    是否开启自我保护模式,默认为true。

默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。

Eureka通过“自我保护模式”来解决这个问题——当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。

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

eureka.server.eviction-interval-timer-in-ms
eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒

Eureka停更说明:2.0后停更了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/412199.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件测试工作主要做什么

随着信息技术的发展和普及&#xff0c;人们对软件的使用越来越普及。但是在软件的使用过程中&#xff0c;软件的效果却不尽如人意。为了确保软件的质量&#xff0c;整个软件业界已经逐渐意识到测试的重要性&#xff0c;也有越来越多的小伙伴加入了软件测试这个行业中来。软件测…

微积分——极值定理的证明

1. 提出问题 极值定理(The Extreme Value Theorem)最初是由捷克数学家波尔查诺(Bernard Bolzano(1781年10月5号-1848年11月18号), 他是一位意大利血统的波希米亚数学家、逻辑学家、哲学家、神学家和天主教神父&#xff0c;也以其自由主义观点而闻名)证明&#xff0c;在1830年代…

基于t-SNE的Digits数据集降维与可视化

基于t-SNE的Digits数据集降维与可视化 描述 t-SNE(t-分布随机邻域嵌入)是一种基于流形学习的非线性降维算法&#xff0c;非常适用于将高维数据降维到2维或者3维&#xff0c;进行可视化观察。t-SNE被认为是效果最好的数据降维算法之一&#xff0c;缺点是计算复杂度高、占用内存…

高效时间管理日历 DHTMLX Event Calendar 2.0.3 Crack

DHTMLX Event Calendar用于高效时间管理的轻量级 JavaScript 事件日历 DHTMLX 可帮助您开发类似 Google 的 JavaScript 事件日历&#xff0c;以高效地组织约会。 用户可以通过拖放来管理事件&#xff0c;并以六种不同的模式显示它们。 JavaScript 事件日历功能 轻的简单的 Java…

UDP/TCP的相关性你知道几个?

TCP/IP网络原理——主要围绕UDP/TCP进行讲解 文章目录TCP/IP网络原理——主要围绕UDP/TCP进行讲解应用层传输层UDP/TCPTCP丢包总结应用层 网络协议的五层协议分别是应用层&#xff0c;传输层&#xff0c;网络层&#xff0c;数据链路层&#xff0c;物理层&#xff0c;这五层构成…

【STL十】关联容器——set容器、multiset容器

【STL十】关联容器——set容器、multiset容器一、set简介二、头文件三、模板类四、set的内部结构五、成员函数1、迭代器2、元素访问3、容量4、修改操作~~5、操作~~5、查找6、查看操作六、demo1、查找find2、修改操作insert3、修改操作erase、clear七、multisetset和multiset会根…

linux四剑客 grep awk sed find

Grep 过滤来自一个文件或标准输入匹配模式内容。 除了grep外&#xff0c;还有egrep、fgrep。egrep是grep的扩展&#xff0c;相当于grep -E。fgrep相当于grep -f&#xff0c;用的少。 Usage: grep [OPTION]… PATTERN [FILE]… 支持的正则描述-E&#xff0c;–extended-regexp…

爱智EdgerOS之深入解析VSCode的EdgerOS插件

一、安装插件 EdgerOS 插件是一个专门为应用开发者提供的在 EdgerOS 下提供应用构建、应用部署、应用更新等功能的插件&#xff0c;同时它还可以监视爱智应用的执行状态&#xff0c;方便开发者更好地调试应用。EdgerOS 插件需要在 VSCode 的 “拓展” 中下载安装&#xff0c;如…

vue-vue2和vue3的diff算法

核心要点 数据变化时&#xff0c;vue如何更新节点虚拟DOM 和 真实DOM 的区别vue2 diff 算法vue3 diff 算法 一、 数据变化时&#xff0c;vue如何更新节点 首先渲染真实DOM的开销是很大&#xff0c;比如有时候我们修改了某个数据且修改的数据量很大时&#xff0c;此时会频繁的…

自学编程的5大误区,早知道早避坑,过来人的宝贵经验

前言 有的人自学很快&#xff0c;几乎一个多月就能掌握一门技术&#xff0c;而有的人苦苦坚持&#xff0c;最后还是半途而废&#xff0c;很大的原因就在于在学习的时候掉进了一些误区没能走出来。 今天我们就来讲讲自学编程常见的5大误区&#xff0c;避开这些误区我们定能在自…

【Java Web】014 -- SpringBoot原理(配置优先级、Bean管理、SpringBoot原理)

目录 一、配置优先级 1、配置&#xff08;3种&#xff1a;.properties、yml、yaml&#xff09; ①、配置文件优先级 ②、如何指定Java系统属性和命令行参数 ③、5种配置文件的优先级 二、Bean管理 1、获取bean&#xff08;3种方法&#xff09; 2、bean作用域&#xff08;5种&am…

Arduino开发之如何连接超声波模块?

文章目录0、引言1、超声波模块说明2、代码编写3、功能演示0、引言 在利用Arduino开发过程中&#xff0c;若需知道设备与周围环境的距离&#xff0c;可利用超声波模块测量短程距离&#xff0c;使运动设备感知周围环境。本文在【Arduino如何进行开发&#xff1f;】基础上&#xf…

探索树形数据结构,通识树、森林与二叉树的基础知识(专有名词),进一步利用顺序表和链表表示、遍历和线索树形结构

树与二叉树 1.树 1.树形结构(非线性结构) 结点之间有分支&#xff0c;具有层次关系 树的定义&#xff1a; 树(tree)是n(n≥0)个有限集。 若n 0&#xff0c;则称为空树&#xff1b; 若n > 0&#xff0c;则它满足如下两个条件&#xff1a; 有且仅有一个特定的称为根(Ro…

NIFI大数据进阶_Json内容转换为Hive支持的文本格式_实际操作_02---大数据之Nifi工作笔记0032

然后首先我们来看一下hdfs中的数据的格式可以看到,还是json的格式对吧 而且也没有回行 然后我们来操作,首先添加一个evaluateJsonPath处理器 可以看到找到这个处理器 添加以后,我们去配置 ​​​​​​​ 点击去配置evaluateJsonPath处理器 可以看到首先我们destination这里配…

Rancher部署K8s集群

一、集群配置 服务器CPU内存磁盘操作系统k8s-master16核16G60GCentOS Linux release 7.5.1804k8s-node-116核16G60GCentOS Linux release 7.5.1804k8s-node-216核16G60GCentOS Linux release 7.5.1804 Rancher version : 2.6.3 二、环境初始化 所有服务器均执行一遍 1、将…

如何在矩池云上部署 Carla,模拟自动驾驶

简介 Carla 是一款基于 Python 编写和 UE&#xff08;虚幻引擎&#xff09;的开源仿真器&#xff0c;用于模拟自动驾驶车辆在不同场景下的行为和决策。它提供了高度可定制和可扩展的驾驶环境&#xff0c;包括城市、高速公路和农村道路等。Carla 还提供了丰富的 API 和工具&…

vscode中的配置

首先&#xff0c;运行或调试某文件&#xff0c;需要该文件是活动文件&#xff08;当前打开的文件&#xff09;。 下面依次介绍tasks.json和launch.json的配置参数。 tasks.json 1.tasks.json的用途 用于指定编译器和链接文件等。默认路径在.vscode下面。 2.如何打开一个tas…

springboot+Mybatis项目搭建教学(controller、service、dao、entity),并写一个简单的接口

创建一个springboot的项目 首先我们需要新建一个文件夹对吧&#xff0c;这里就不展示了&#xff0c;然后我们用IDEA打开这个文件夹&#xff0c;是这样的 新建一个模块 然后按照这里的进行选择 模块名字是自己随便起的&#xff0c;命名在这里时无关紧要的&#xff0c;然后我…

Python实现Imagenet数据集的合并和拆分

Python实现Imagenet数据集的合并和拆分 1. 合并Imagenet 任务需求 文件夹形式为一个数据集MyImagenet&#xff0c;路径为/home/lihuanyu/code/03AdaBins/img_data/MyImagenet/val&#xff0c;val文件夹又有若干的类别子文件夹&#xff0c;子文件夹是每一个类别的图片&#xf…

数据结构_第十一关:二叉树的链式结构

目录 1.二叉树链式结构的实现 1.1前置说明 1.2二叉树的遍历 1.3二叉树遍历的实现&#xff1a; 1&#xff09;先序遍历、中序遍历、后续遍历代码如下 2&#xff09;层序遍历&#xff1a; 1.4结点个数以及高度的计算 1&#xff09;求二叉树的总节点&#xff1a; 2&#…