SpringCloud 尚硅谷 微服务简介以及Eureka使用

写在前面

该系列博客仅用于本人学习尚硅谷课程SpringCloud笔记,其中的错误在所难免,如有错误恳请指正。
官方源码地址:https://github.com/zzyybs/atguigu_spirngcloud2020

什么是SpringCloud

   Spring Cloud是微服务一站式服务解决方案,微服务全家桶。它是微服务开发的主流技术栈。SpringCloud 和 SpringCloud Alibaba 目前是最主流的微服务框架组合。

   Spring Cloud包含了许多功能强大的组件,例如服务注册与发现、负载均衡、断路器、配置管理、消息总线等,这些组件可以帮助开发者构建弹性、可靠、可扩展的分布式系统。
来源:尚硅谷

   微服务是一种理念。程序员可以将应用程序拆分为多个微服务,每个微服务负责实现一个特定的功能,并通过Spring Cloud提供的组件进行协调和管理。这样,程序员可以更加灵活地组织和扩展应用程序,同时提高系统的可维护性和可靠性。

前期准备

父工程

首先创建一个父工程。maven版本使用3.5,不要使用idea自带的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Java编译版本选择JDK8。
在这里插入图片描述
修改pom:找到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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.atguigu.springcloud</groupId>
    <artifactId>cloud2020</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 统一管理jar包版本 -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <lombok.version>1.16.18</lombok.version>
        <mysql.version>5.1.47</mysql.version>
        <druid.version>1.1.16</druid.version>
        <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
    </properties>

    <!-- 子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version  -->
    <dependencyManagement>
        <dependencies>
            <!--spring boot 2.2.2-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--spring cloud Hoxton.SR1-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--spring cloud alibaba 2.1.0.RELEASE-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.spring.boot.version}</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </dependency>
        </dependencies>
    </dependencyManagement>

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

</project>
  • <properties></properties>:后序需要创建子工程,在父亲工程这统一管理jar包。
  • <dependencyManagement></dependencyManagement>:通过该标签管理子模块的版本号。要注意的是,该标签只是声明了依赖,但是不是实现引入。如果要引入,需要将放到该标签外面,刷新等待引入后再放回该标签里面。
  • <dependencies></dependencies>dependencyManagement只是声明一个依赖,而不实现引入,故需要子模块中也需要对依赖进行声明,倘若不声明子模块自己的依赖,是不会从父模块中继承的;只有子模块中也声明了依赖。并且没有写对应的版本号它才会从父类中继承;并且version和scope都是取自父类;此外要是子模块中自己定义了自己的版本号,是不会继承自父类的。

里面的部分依赖并不是当前需要的,如果发现有的依赖导致了报错,可以先将相关依赖注释。

创建微服务 cloud-provider-payment8001

该微服务用于客户端服务的提供者。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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>cloud2020</artifactId>
        <groupId>com.atguigu.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>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>


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

        <dependency>
            <!-- 引入自己定义的api通用包,可以使用Payment支付Entity 当前不需要,主要注释掉 -->
            <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>
            <!--这个和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.1.10</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.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>
</project>

yml

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

启动类

在这里插入图片描述
可以直接通过spring初始化一步到位。

常规操作

数据库建表

create table `payment`(
    `id` bigint(20) not null auto_increment comment 'ID',
    `serial` varchar(200) default '',
    PRIMARY KEY (`id`)

)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

select * from payment;

数据可以随意添加两条。本人数据如下
在这里插入图片描述
entities

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data   //set/get方法
@AllArgsConstructor //有参构造器
@NoArgsConstructor  //无参构造器
public class Payment implements Serializable {
  private long id;//数据库是bigint
  private String serial;
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

//返回给前端的通用json数据串
@Data   //set/get方法
@AllArgsConstructor //有参构造器
@NoArgsConstructor  //无参构造器
public class CommonResult<T> {
  private Integer code;
  private String message;
  private T data; //泛型,对应类型的json数据

  //自定义两个参数的构造方法
  public CommonResult(Integer code, String message){
      this(code, message, null);
  }
}

dao

@Mapper
public interface PaymentDao {
  
  int create(Payment payment);
  Payment getPaymentById(@Param("id") Long id);
}

resource下创建mapper文件夹,新建PaymentMapper.xml。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.atguigu.springcloud.dao.PaymentDao">
    <resultMap id="BaseResultMap" type="com.atguigu.springcloud.entities.Payment">
        <id column="id" property="id" jdbcType="BIGINT"/>
        <id column="serial" property="serial" jdbcType="VARCHAR"/>
    </resultMap>

    <insert id="create" parameterType="com.atguigu.springcloud.entities.Payment" useGeneratedKeys="true" keyProperty="id">
        insert into payment(serial) values (#{serial})
    </insert>

    <select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">
        select * from payment where id = #{id}
    </select>
</mapper>

Controller && Service

Service层

public interface PaymentService {
  int create(Payment payment);

  Payment getPaymentById(@Param("id") Long id);
}
@Service
public class PaymentServiceImpl implements PaymentService {

    @Autowired
    private PaymentDao paymentDao;

    @Override
    public int create(Payment payment) {
        return paymentDao.create(payment);
    }

    @Override
    public Payment getPaymentById(Long id) {
        return paymentDao.getPaymentById(id);
    }
}

Controller层

@RestController
@Slf4j
public class PaymentController {

    @Resource
    private PaymentService paymentService;

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

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

目录结构如下
在这里插入图片描述

启动项目

   找到启动类,然后点击运行启动。启动过程中出现了异常暂时不要管。打开浏览器,访问http://localhost:8001/payment/31(注意这里的31是本人的id数据)访问已经添加的数据。如果需要插入数据,可以使用postman传入Json。
在这里插入图片描述

创建模块 cloud-api-commons

后面的80需要和前面的8001相同的内容。为了方便管理,将相同的类放在该模块并进行打包。

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>cloud2020</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-api-commons</artifactId>

    <dependencies>
        <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>

        <!-- hutool 工具包 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.1.0</version>
        </dependency>
    </dependencies>
</project>

将8001中entities包下的类复制到该模块,删除8001下的entities包。
在这里插入图片描述
在这里插入图片描述
等待成功后,找到8001,7001中的该依赖然后加载。
在这里插入图片描述

创建微服务 cloud-consumer-order80

该微服务用于客户端服务的消费者。

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>cloud2020</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-consumer-order80</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- <dependency>&lt;!&ndash; 引入自己定义的api通用包,可以使用Payment支付Entity &ndash;&gt; -->
        <!--     <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>
</project>

yml

server:
  port: 80 # 默认 80 端口,只需要输入网址即可

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

spring:
  application:
    name: cloud-order-service

controller && config

config

@Configuration
public class ApplicationContextConfig {
	// RestTemplate是Spring框架提供的一个用于发送HTTP请求的类。它简化了与RESTful服务的交互,可以方便地发送GET、POST、PUT、DELETE等请求,并且支持处理响应结果。
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

controller

@RestController
@Slf4j
public class OrderController {

    //远程调用的 地址
    public static final String PAYMENY_URL = "http://localhost:8001";

    @Resource
    private RestTemplate restTemplate;

    @PostMapping("customer/payment/create")
    public CommonResult<Payment> create (Payment payment){

        return restTemplate.postForObject(PAYMENY_URL + "/payment/create",//请求地址
                                          payment,//请求参数
                                          CommonResult.class);//返回类型
    }

    @GetMapping("customer/payment/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id")Long id){
        return restTemplate.getForObject(PAYMENY_URL + "/payment/" + id,//请求地址
                                         CommonResult.class);//返回类型
    }
}

   整个过程,通过浏览器调用order中的controller层,然后order80微服务发送http请求给payment8001微服务获取相关信息后返回。

到这里,所有的准备工作就完成了,接下来,进行eureka的正式使用。

Eureka

是什么

   Eureka用于服务的注册与发现,用于管理和监控各个微服务。

   比如,使用微服务后,不同的微服务在不同的机器上,为了简单方便管理,可以使用Eureka进行注册。

机制简介

   Eureka包括两个组件:Eureka ServerEureka Client

  • Eureka Server:服务器,里面有一个注册表,保存了不同的服务所在的机器和端口号。
  • Eureka Client:客户端,负责将服务注册到Eureka Server中。

   Eureka Client组件告诉Eureka Server自己在哪台机器上,监听着哪个端口;Eureka Client需要调用其他微服务的时候,通过Eureka Server寻找其他服务客户端,然后将这些相关信息从Eureka Server的注册表中缓存到自己的本地。

服务在Eureka上注册,然后定期发送心跳来更新它们的续约。如果客户端不能多次续订,那么它将在大约90秒内从服务器注册表中剔除。

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

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

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

使用Eureka

   刚刚我们创建了一个微服务 cloud-provider-payment8001。当前的项目比较简单,管理起来不困难。但是如果项目比较多,而且分布在不同的机器上,管理就比较麻烦了,可以使用eureka进行服务的注册。现在将该微服务进行注册。

   eureka有两个组件;server和client。将cloud-provider-payment8001作为client,那么,需要一个server,为此,需要再写一个微服务cloud-eureka-server7001,表示eureka的服务中心,端口号是7001。

   按照上述方式,新建模块,选择maven工程。

创建微服务cloud-eureka-server7001

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>cloud2020</artifactId>
        <groupId>com.atguigu.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>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <!-- <dependency> -->
        <!--     <groupId>com.atguigu.springcloud</groupId> -->
        <!--     <artifactId>cloud-api-commons</artifactId> -->
        <!--     <version>${project.version}</version> -->
        <!-- </dependency> -->

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>
</project>

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/

启动类

// exclude :启动时不启用 DataSource的自动配置检查
// 依赖中存在数据源,如果启动会提示找不到数据源
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaServer   // 表示它是服务注册中心
public class EurekaServerMain7001 {
    public static void main(String[] args){
        SpringApplication.run(EurekaServerMain7001.class, args);
    }
}

   启动类中需要格外注意的一个注解@EnableEurekaServer,用于在Spring Boot应用程序中启用Eureka服务器。通过使用@EnableEurekaServer注解,我们可以将 cloud-eureka-server7001 标记为Eureka服务器,以便其他微服务可以进行注册和发现。
   服务中心有了,使用@EnableEurekaClient注解在 cloud-provider-payment8001 的启动类上。通过@EnableEurekaClient可以将微服务标记为Eureka客户端,以便注册到Eureka服务器。同时要配置8001的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
    url: jdbc:mysql://localhost:3306/cloud2020?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.dkf.springcloud.entities  # 所有Entity 别名类所在包

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

启动该微服务,访问。
在这里插入图片描述
启动 cloud-provider-payment8001,cloud-consumer-order80
在这里插入图片描述
刷新7001网页,可以看到新注册了两个微服务。
在这里插入图片描述
   现在看这两个微服务后面的状态信息。我们想要知道该微服务来自哪个ip,来自哪个机器,可以进行配置来显示。

微服务信息完善

order80和payment8001分别修改yml,添加

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
      # 新增部分
  instance: 
    instance-id: payment8001 # 提供者的id
    prefer-ip-address: true # 显示ip地址

就可以显示提供者的id和ip地址。
在这里插入图片描述

微服务发现Discovery

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

   先在8001的主启动类上添加@EnableDiscoveryClient,然后添加代码。

@Resource
private DiscoveryClient discoveryClient;

@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-ORDER-SERVICE");
    for(ServiceInstance serviceInstance:instances){
        log.info(serviceInstance.getServiceId() + "\t" + serviceInstance.getHost()
                 + "\t" + serviceInstance.getPort() + "\t" + serviceInstance.getUri());
    }
    return this.discoveryClient;
}

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

Eureka自我保护

在这里插入图片描述
   看到该信息,说明eureka进入了自我保护。为了防止Eureka Client可以正常运行但是与Eureka Server网络不通情况下,Eureka Server不会立刻将Eureka Client服务剔除。

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

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

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

禁止使用自我保护

修改yml。
server:

eureka:
  instance:
    hostname: eureka7001.com  # eureka 服务端的实例名称
  client:
    # false 代表不向服务注册中心注册自己,因为它本身就是服务中心
    register-with-eureka: false
    # false 代表自己就是服务注册中心,自己的作用就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
      defaultZone: http://localhost:7001/eureka/
#  server:
#    # 关闭自我保护机制,保证不可用该服务被及时剔除
#    enable-self-preservation: false
#    # eureka server清理无效节点的时间间隔
#    eviction-interval-timer-in-ms: 2000 

client:

eureka:
  client:
    service-url:
       defaultZone: http://localhost:7001/eureka
    # 将自己注册进去 true
    register-with-eureka: true
    #是否从Eureka server抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetch-registry: true
  instance:
    instance-id: payment8001 # 提供者的id
    prefer-ip-address: true # 显示ip地址
      # Eureka客户端像服务端发送心跳的时间间隔,单位s,默认30s
    least-renewal-interval-in-seconds: 1
      # Eureka服务端在收到最后一次心跳后等待时间上线,单位为s,默认90s,超时将剔除服务
    least-expiration-duration-in-seconds: 2

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Segment Anything(SAM) 计算过程

给定输入图像 I ∈ R 3 H W I \in R^{3 \times H \times W} I∈R3HW。给定需要的prompts&#xff1a; M ∈ R 1 H W M \in R^{1 \times H \times W} M∈R1HW&#xff0c;代表图片的前背景信息。 P ∈ R N 2 P \in R^{N \times 2} P∈RN2&#xff0c;其中 N N N 是点的个数…

活动发布会邀请媒体6步走

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 邀请媒体参加活动发布会对信息的传播&#xff0c;企业品牌建设有诸多的好处&#xff0c;今天就与大家分享下邀请媒体参加活动报道的6个步骤&#xff1a; 1. 策划与准备&#xff1a; -明…

vue3 - 使用reactive定义响应式数据进行列表赋值时,视图没有更新的解决方案

文章目录 1&#xff0c;问题2&#xff0c;原因3&#xff0c;解决方案一、再封装一层数据&#xff0c;即定义属性名&#xff0c;在后期赋值的时候&#xff0c;对此属性进行直接赋值三、使用数组的splice来直接更改原数组三、使用 ref 来定义数据 1&#xff0c;问题 在Vue 3.0 中…

ThreadLocal

# ThreadLocal # ThreadLocal 有什么用&#xff1f; 通常情况下&#xff0c;我们创建的变量是可以被任何一个线程访问并修改的。如果想实现每一个线程都有自己的专属本地变量该如何解决呢&#xff1f; JDK 中自带的ThreadLocal类正是为了解决这样的问题。 ThreadLocal类主要…

Vue+Vue Router+TailwindCss+Daisyui部署

一、构建Vue项目 > npm init vuelatest > cd <your-project-name> > npm install > npm run dev 二、设置IDEA JS版本 三、安装Tailwindcss Install Tailwind CSS with Vite - Tailwind CSS npm install -D tailwindcss postcss autoprefixer npx tai…

Titanic细节记录一

目录 chunker header index_col names Series与DataFrame的区别 df.columns del和drop的区别 reset_index loc与iloc的区别 不同的排序方式 sort_values sort_index DataFrame相加 describe函数查看数据基本信息 查看多个列的数据时使用列表 处理缺失值的几种思路 …

【Kubernetes】Kubernetes之kubectl详解

kubectl 一、陈述式资源管理1. 陈述式资源管理方法2. 基本信息查看3. 项目周期管理3.1 创建 kubectl create 命令3.2 发布 kubectl expose命令3.3 更新 kubectl set3.4 回滚 kubectl rollout3.5 删除 kubectl delete 4. kubectl 的发布策略4.1 蓝绿发布4.2 红黑发布4.3 灰度发布…

代码随想录算法训练营第24天| 第七章 回溯算法part01 理论基础、leetcode 77

Part I : 回溯算法基础 背景&#xff1a;一直以来都是半懂不懂的&#xff0c;在逻辑上不难&#xff0c;毕竟属于暴力搜索&#xff1b;在代码上就开始缠绕起来了&#xff0c;自己研究的时候对N皇后问题老是理不清。这次终于在Carl这开始前进啦&#xff01;何为回溯算法&#xf…

爬虫012_字典高级操作_查询_修改_添加_删除和清空_遍历---python工作笔记031

然后来看字典高级,首先 打印某个元素 然后打印的时候注意,如果直接打印的值,在字典中没有就报错 这里要注意不能用点访问

Redis类型检查与命令多态

Redis中用于操作键的命令基本上可以分为两种类型。 其中一种命令可以对任何类型的键执行&#xff0c;比如说DEL命令、EXPIRE命令 、RENAME命令、TYPE命令、OBJECT命令等。 举个例子&#xff0c;以下代码就展示了使用DEL命令来删除三种不同类型的键: # 字符串键 redis> SE…

基于亚奈奎斯特采样和SOMP算法的平板脉冲响应空间插值matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ...................................................................... %fine regular gr…

ApplicationContextInitializer

目录 在何处执行&#xff1f;何时初始化&#xff1f;自己写一个ApplicationContextInitializer 那这个类的设计具体有什么作用呢&#xff1f;&#xff1f;1. DelegatingApplicationContextInitializer2. SharedMetadataReaderFactoryContextInitializer3. ContextIdApplication…

灰度均衡变换之c++实现(qt + 不调包)

1.基本原理 灰度均衡是以累计分布函数变换为基础的直方图修正法&#xff0c;它可以产生一副灰度级分布概率均匀的图像。也就是说&#xff0c;经过灰度均衡后的图像在没一级灰度上像素点的数量相差不大。公式见下图&#xff0c;为灰度值为x的像素点的个数&#xff0c;n为总像素点…

方法区——元空间概述

方法区 不同版本具体实现 标准层面&#xff1a;方法区&#xff08;Method Area&#xff09;具体实现层面&#xff1a; ≤JDK1.6 永久代JDK1.7 永久代仍然存在&#xff0c;但是已经开始提出&#xff1a;去永久代≥JDK1.8元空间&#xff08;Meta Space&#xff09; 永久代概念辨…

Linux6.34 Kubernetes yaml文件详解

文章目录 计算机系统5G云计算第三章 LINUX Kubernetes yaml文件详解一、yaml文件概述1.查看 api 资源版本标签2.写一个yaml文件demo 计算机系统 5G云计算 第三章 LINUX Kubernetes yaml文件详解 一、yaml文件概述 Kubernetes 支持 YAML 和 JSON 格式管理资源对象 JSON 格式…

【网站搭建】开源社区Flarum搭建记录

环境 服务器系统&#xff1a;腾讯云 OpenCloudOS 宝塔版本&#xff1a;免费版8.0.1 Nginx&#xff1a;1.24.0 MySQL&#xff1a;5.7.42 PHP&#xff1a;8.1.21 萌狼蓝天 2023年8月7日 PHP设置 1.安装扩展&#xff1a;flieinfo、opcache、exif 2.解除禁用函数&#xff1a;putenv…

安卓:LitePal操作数据库

目录 一、LitePal介绍 常用方法&#xff1a; 1、插入数据&#xff1a; 2、更新数据&#xff1a; 3、删除数据&#xff1a; 4、查询数据&#xff1a; 二、LitePal的基本用法&#xff1a; 1、集成LitePal&#xff1a; 2、创建LitePal配置文件&#xff1a; 3、创建模型类…

【图像分类】CNN + Transformer 结合系列.4

介绍两篇利用Transformer做图像分类的论文&#xff1a;CoAtNet&#xff08;NeurIPS2021&#xff09;&#xff0c;ConvMixer&#xff08;ICLR2022&#xff09;。CoAtNet结合CNN和Transformer的优点进行改进&#xff0c;ConvMixer则patch的角度来说明划分patch有助于分类。 CoAtN…

音视频基础:分辨率、码率、帧率之间关系

基础 人类视觉系统 分辨率 像素&#xff1a; 是指由图像的小方格组成的&#xff0c;这些小方块都有一个明确的位置和被分配的色彩数值&#xff0c;小方格颜色和位置就决定该图像所呈现出来的样子&#xff1b;可以将像素视为整个图像中不可分割的单位或者是元素&#xff1b;像素…

RabbitMQ 发布确认机制

发布确认模式是避免消息由生产者到RabbitMQ消息丢失的一种手段 发布确认模式 原理说明实现方式开启confirm&#xff08;确认&#xff09;模式阻塞确认异步确认 总结 原理说明 生产者通过调用channel.confirmSelect方法将信道设置为confirm模式&#xff0c;之后RabbitMQ会返回Co…