Springcloud 介绍 和 Eureka的使用

  • 第一章 Springcloud 基础理论
    • 什么是微服务?
    • SpringCloud介绍
    • SpringCloud版本选择
    • Cloud组件停更说明
    • 父工程项目搭建
      • 父工程pom文件
      • 复习DependencyManager和Dependencied
    • Rest微服务工程构建
      • 1. 微服务提供者支付module模块cloud-provider-payment8001
        • 1. 新建模块
        • 2. 在pom中添加依赖
        • 3. 写yml
        • 4. 主启动
        • 5.业务类
        • 6.测试
      • 2.热部署Devtools (只能在开发阶段使用)
      • 3.微服务消费订单module模块cloud-consumer-order81
        • 1.新建模块
        • 2.改pom:
        • 3.写yml
        • 4.主启动
        • 5.业务类
        • 6.测试
        • 7.RestTemplate介绍
      • 3. 遗留问题
      • 4. 工程重构
        • 1.新建module
        • 2.POM
        • 3. entity
        • 4. maven重新打包
        • 5. 引入cloud-api-commons包
        • 6.测试
    • Eureka服务注册与发现
      • Eureka 基础知识
        • 服务治理
        • 服务注册
      • Eureka两组件
    • 单机Eureka构建步骤
      • IDEA生成EurekaServer端服务注册中心
        • 1.建module
        • 2.改pom
        • 3.写yml
        • 4.主启动
        • 5.测试
      • 将EurekaClient端8001注册进EurekaServer成为服务提供者provider
        • 1. 修改cloud-provider-payment8001
        • 2. 改pom
        • 3.写yml
        • 4.主启动
        • 5.测试
        • 6. 自我保护机制
      • 将EurekaClient端81注册进EurekaServer成为服务消费者consumer
        • 1.引入依赖
        • 2.在yml文件中添加
        • 3.主启动
        • 4.启动项目 刷新页面
    • Eureka集群原理说明
      • 构建eurekaServer集群环境
      • 将将支付服务8001和订单服务81微服务发布到集群配置中
    • 支付微服务集群配置
    • actuator微服务信息完善
    • 服务发现Discovery
      • 修改提供者集群的Controller
        • 修改cloud-provider-payment8001的主启动
        • 修改cloud-provider-payment8001的Controller
        • 测试
    • Eureka自我保护理论知识
      • 概述
      • 导致原因
      • 什么是自我保护机制
    • 怎么禁止自我保护
    • Eureka停更说明

第一章 Springcloud 基础理论

视频来源:Spring-cloud 1 1-27

什么是微服务?

微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间相互协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务之间采用轻量级的通行机制相互协作(通常是基于HTTP协议的RestFul API)。每个服务都围绕着具体本业务进行构建,并且能够被独立部署到生成环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

拆分来理解就是:

  • 微服务是一种架构风格
  • 每个服务运行在自己独立的机器中,也就是可以单独的部署和升级
  • 服务之间使用轻量级的HTTP交互
  • 每个服务都提供各自的业务功能
  • 可以由全自动部署机制独立部署
  • 每个服务可以使用不同的语言、不同的存储过程

主题词01:现代数字化生活-落地维度

  • 手机
  • PC
  • 智能家居
  • VR
  • 笔记本

主题词02:分布式微服务架构-落地维度

  • 服务调用
  • 服务降级
  • 服务注册与发现
  • 服务熔断
  • 负载均衡
  • 服务消息队列
  • 服务网关
  • 配置中心管理
  • 自动化构建部署
  • 服务监控
  • 全链路追踪
  • 服务定时任务
  • 调度操作

SpringCloud介绍

Spring Cloud是什么? 什么是微服务架构

springcloud官方文档(Hoxton SR5):https://cloud.spring.io/spring-cloud-static/Hoxton.SR5/reference/htmlsingle/
springcloud中文文档:https://www.springcloud.cc/
springcloud中国社区文档:http://docs.springcloud.cn/
https://www.bookstack.cn/read/spring-cloud-docs/docs-index.md

SpringCloud=分布式微服务架构的一站式解决方案,是多种微服务架构落地的技术框架的集合体,俗称微服务全家桶

SpringCloud 包含的技术组件?

SpringCloud版本选择

Spring Boot 源码地址

  • 源码地址

Spring Cloud 源码地址

  • 源码地址
  • 官网

Spring Boot 与 Spring Cloud 兼容性查看

  • 文档
  • JSON接口

2022年3月27日20:05:45查看版本对应的选择

接下来开发用到的组件版本

  • Cloud-Hoxton.SR1
  • Boot- 2.2.2.RELEASE
  • Cloud Alibaba-2.1.0.RELEASE
  • JAVA -JAVA8
  • Maven -3.5及以上
  • MySQL -5.7及以上

Cloud组件停更说明

停更引发的升级惨案

  • 停更不停
  • 被动修复bugs
  • 不再接受合并请求
  • 不再发布新版本

Cloud升级

服务注册中心

  • × Eureke
  • √ Zookeeper
  • √ Consul
  • √ Nacos

服务调用

  • √ Ribbon
  • √ LoadBalancer
  • × Fegin
  • √ OpenFegin

服务降级

  • × HyStrix
  • √ resilience4j
  • √ sentinel

服务网关

  • × Zuul
  • !Zuul2
  • √ gateway

服务配置

  • × Config
  • √ Nacos

服务总线

  • × Bus
  • √ Nacos

父工程项目搭建

约定 -> 配置 -> 编码

创建微服务cloud整体聚合父工程Project ,有8个关键步骤:

1.New Project-maven工程

2.聚合功总工程名称

3.Maven版本(使用3.5.2)

4.工程名称

5.字符编码 - Setting -File encoding(选择UTF-8)

6.注解生效激活 -Setting-Annotation Processors

7.Java编译版本选8

8.File Type过滤 -Setting -File Type

父工程pom文件

<!--统一管理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><lombok.version>1.18.10</lombok.version><log4j.version>1.2.17</log4j.version><mysql.version>8.0.18</mysql.version><druid.version>1.1.20</druid.version><mybatis.spring.boot.version>1.3.2</mybatis.spring.boot.version></properties><!--子模块继承之后,提供作用:锁定版本+子module不用写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--><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><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version><scope>runtime</scope></dependency><!-- druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${druid.version}</version></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.spring.boot.version}</version></dependency><!--junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version></dependency><!--log4j--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>${log4j.version}</version></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><fork>true</fork><addResources>true</addResources></configuration></plugin></plugins></build>

复习DependencyManager和Dependencied

Maven使用dependencyManagement元素来提供了一种管理依赖版本号的方式。

通常会在一个项目的最顶层的父POM中看到DependencyManager元素

使用pom.xml中的dependencyManagement元素能让所有的子项目中引用个依赖而不用显示的列出版本量。

Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用这个dependencyManagement元素中的指定的版本号。

然后子元素可以添加父引入的依赖可以不携带版本号方便统一管理。

  • dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖
  • 如果子项目中的声明依赖,是不会从父项目中继承下来的;只有子项目中写了该依赖,并且没有指定具体版本,才会从父工程中继承该项,并且version和scope都读取自父pom。
  • 如果子项目指定了对应的版本号,那么会使用子项目中指定的jar版本

IDEA右侧有maven插件有Toggle Skip Test’s Mode按钮 ,这样maven可以跳过单元测试


父工程创建完成执行 mvn:install 将会把父工程发布到仓库方面子工程继承。

Rest微服务工程构建

最开始的订单模块

模块构建:

  1. 建module
  2. 改pom
  3. 写yml
  4. 主启动
  5. 业务类
  6. 测试

1. 微服务提供者支付module模块cloud-provider-payment8001

1. 新建模块

2. 在pom中添加依赖

    <dependencies><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.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.20</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>

3. 写yml

#微服务建议一定要写服务端口号和微服务名称
server:#端口号port: 8001spring:application:#微服务名称name: cloud-payment-service#数据库配置datasource:type: com.alibaba.druid.pool.DruidDataSource#mysql5.x的没有cjdriver-class-name: com.mysql.cj.jdbc.Driver#记得先创建数据库url: jdbc:mysql://localhost:3306/db2020?useUnicode=true&characterEncoding=utf-8&useSSL=falseusername: rootpassword: 200088lx#mybatis配置
mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.zero.entity  #所有Entity别名类所在包

4. 主启动

在java包下创建主启动类com.angenin.springcloud.PaymentMain8001

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

5.业务类

  1. 建标SQL
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;INSERT INTO payment(`serial`)VALUES("张三");

2.entity

在对应自己创建的entity包下面创建出对应实体

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment implements Serializable {private Long id;private String serial;
}

在entity包下新建CommonResult(json封装体 ,传给前端的)

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T>{private Integer code;private String message;private T data;public CommonResult(Integer code, String message){this(code, message, null);}
}

3.dao

在对应包下新建Dao.PaymentDao接口

@Mapper
//@Repository不用Spring的
public interface PaymentDao
{public int create(Payment payment);public Payment getPaymentById(@Param("id") Long id);
}

4.mapper

在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.zero.mapper.PaymentDao"><insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">insert into payment(serial)  values(#{serial});</insert><resultMap id="BaseResultMap" type="com.zero.entity.Payment"><id column="id" property="id" jdbcType="BIGINT"/><id column="serial" property="serial" jdbcType="VARCHAR"/></resultMap><select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">select * from payment where id=#{id};</select></mapper>

5.service

在springcloud包下新建service.PaymentService接口

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

在service包下新建impl.PaymentServiceImpl实现下

@Service
public class PaymentServiceImpl implements PaymentService
{@Resourceprivate PaymentDao paymentDao;@Overridepublic int create(Payment payment){return paymentDao.create(payment);}@Overridepublic Payment getPaymentById(Long id){return paymentDao.getPaymentById(id);}
}
  1. controller

在springcloud包下新建controller.PaymentController

@RestController
@Slf4j
public class PaymentController{@Resourceprivate PaymentService paymentService;@PostMapping(value = "/payment/create")public CommonResult create(Payment payment){int result = paymentService.create(payment);log.info("*****插入结果:"+result);if(result > 0){return new CommonResult(200,"插入数据库成功",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,"查询成功",payment);}else{return new CommonResult(444,"没有对应记录,查询ID: "+id,id);}}
}

6.测试

  1. 浏览器-http://localhost:8001/payment/get/1
  2. Postman - http://localhost:8001/payment/create?serial=lun2 (post接口实现postman测试)

2.热部署Devtools (只能在开发阶段使用)

  1. 在cloud-provider-payment8001项目中添加热部署依赖
        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency>

2.添加一个插件到父类工程的pom.xml里

<build><!--<finalName>你的工程名</finalName>(单一工程时添加)--><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><fork>true</fork><addResources>true</addResources></configuration></plugin></plugins>
</build>
  1. Enabling automatic build

File -> Settings(New Project Settings->Settings for New Projects) ->Complier

  1. 热注册开启

组合键 Shift+Ctrl+Alt+/ ,选中Registry

  • compiler.automake.allow.when.app.running
  • actionSystem.assertFocusAccessFromEdt

  1. 重启IDEA

3.微服务消费订单module模块cloud-consumer-order81

1.新建模块

cloud-consumer-order81

2.改pom:

往pom中添加:

<?xml version="1.0" encoding="UTF-8"?><dependencies><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>

3.写yml

在resouce目录下新建application.yml

#访问一个网站时,默认是80端口,给用户80端口,用户就可以不用加端口直接访问页面
server:port: 81

4.主启动

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @Auther: lixiang* @Date: 2022/03/30/22:57* @Description:*/
@SpringBootApplication
public class OrderMain81
{public static void main( String[] args ){SpringApplication.run(OrderMain81.class, args);}
}

5.业务类

  1. 编写实体类:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment implements Serializable {private Long id;private String serial;
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T>{private Integer code;private String message;private T data;public CommonResult(Integer code, String message){this(code, message, null);}
}
  1. 在包下面新建config.ApplicationContextConfig
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class ApplicationContextConfig {@Beanpublic RestTemplate getRestTemplate(){return new RestTemplate();}}
  1. 在包下新建controller.OrderController
import com.lun.springcloud.entities.CommonResult;
import com.lun.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;@Slf4j
@RestController
public class OrderController {public static final String PAYMENT_URL = "http://localhost:8001";@Resourceprivate RestTemplate restTemplate;@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);}
}

6.测试

运行cloud-consumer-order80与cloud-provider-payment8001两工程

浏览器 - http://localhost:81/consumer/payment/get/1

7.RestTemplate介绍

RestTemplate提供了多种便捷访问远程Http服务的方法,是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集

官网地址

使用:

使用restTemplate访问restful接口非常的简单粗暴无脑。

(url, requestMap, ResponseBean.class)这三个参数分别代表。

REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。

3. 遗留问题

浏览器 - http://localhost:81/consumer/payment/create?serial=lun3

虽然,返回成功,但是观测数据库中,并没有创建serial为lun3的行。

解决方法:在cloud-provider-payment8001工程的PaymentController中添加@RequestBody注解。

public class PaymentController
{@PostMapping(value = "/payment/create")public CommonResult create(@RequestBody/*添加到这里*/ Payment payment){...}
}
  • 开启Run DashBoard

打开工程路径下的.idea文件夹的workspace.xml

在中修改或添加以下代码:

<option name="configurationTypes"><set><option value="SpringBootApplicationConfigurationType"/></set>
</option>

4. 工程重构

观察cloud-consumer-order81与cloud-provider-payment8001两工程有重复代码(entity)(公共代码),重构。

1.新建module

cloud-api-commons

2.POM

   <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><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.1.0</version></dependency></dependencies>

3. entity

将cloud-consumer-order81与cloud-provider-payment8001两工程的公有entities包移至cloud-api-commons工程下。

4. maven重新打包

  • maven clean、install

  • cloud-api-commons工程,以供给cloud-consumer-order81与cloud-provider-payment8001两工程调用。

5. 引入cloud-api-commons包

  • 将cloud-consumer-order81与cloud-provider-payment8001两工程的公有entities包移除
  • 引入cloud-api-commons依赖
        <dependency><groupId>com.zero</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></dependency>

6.测试

Eureka服务注册与发现

Eureka 基础知识

服务治理

什么是服务治理

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

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

服务注册

什么是服务注册与发现

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

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

Eureka两组件

Eureka包含两个组件:Eureka Server和Eureka Client

Eureka Server提供服务注册服务

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

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

单机Eureka构建步骤

IDEA生成EurekaServer端服务注册中心

1.建module

cloud-eureka-server7001的Maven工程

2.改pom

server端依赖对比:

dependencies><!--eureka-server--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --><dependency><groupId>com.zero</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>

3.写yml

在resource目录下新建application.yml文件

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

4.主启动

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);}
}

5.测试

测试运行EurekaMain7001,浏览器输入http://localhost:7001/回车,会查看到Spring Eureka服务主页。

将EurekaClient端8001注册进EurekaServer成为服务提供者provider

1. 修改cloud-provider-payment8001

2. 改pom

添加spring-cloud-starter-netflix-eureka-client依赖

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

3.写yml

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

4.主启动

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication
@EnableEurekaClient//<-----添加该注解
public class PaymentMain001 {public static void main(String[] args) {SpringApplication.run(PaymentMain001.class, args);}
}

5.测试

  • 启动cloud-provider-payment8001和cloud-eureka-server7001工程。
  • 浏览器输入 - http://localhost:7001/ 主页内的Instances currently registered with Eureka会显示cloud-provider-payment8001的配置文件application.yml设置的应用名cloud-payment-service

6. 自我保护机制

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可能错误地声称实例在没有启动的情况下启动了。续订小于阈值,因此实例不会为了安全而过期。

将EurekaClient端81注册进EurekaServer成为服务消费者consumer

EurekaClient端cloud-consumer-order81将注册进EurekaServer成为服务消费者consumer,类似来上课消费的同学

1.引入依赖

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

2.在yml文件中添加

server:port: 81spring:application:name: cloud-order-serviceeureka:client:#表示是否将自己注册进Eurekaserver默认为true。register-with-eureka: true#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡fetchRegistry: trueservice-url:defaultZone: http://localhost:7001/eureka

3.主启动

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication
@EnableEurekaClient//<--- 添加该标签
public class OrderMain81
{public static void main( String[] args ){SpringApplication.run(OrderMain80.class, args);}
}

4.启动项目 刷新页面

  • 启动cloud-provider-payment8001、cloud-eureka-server7001和cloud-consumer-order80这三工程。
  • 浏览器输入 http://localhost:7001 , 在主页的Instances currently registered with Eureka将会看到cloud-provider-payment8001、cloud-consumer-order81两个工程名。

Eureka集群原理说明

搭建Eureka注册集群,实现负载均衡+故障容错。

构建eurekaServer集群环境

  1. 参照cloud-eureka-server7001新建cloud-eureka-server7002和cloud-eureka-server7003。
  2. 修改hosts文件(路径在C:\Windows\System32\drivers\etc路径中找到hosts文件。)
127.0.0.1       eureka7001.com
127.0.0.1       eureka7002.com
127.0.0.1       eureka7003.com
  1. 修改7001的yml文件
eureka:instance:hostname: eureka7001.com  #eureka服务端的实例名称client:register-with-eureka: falsefetch-registry: falseservice-url:
#      单机
#      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/#集群版  相互注册,相互守望defaultZone: http://eureka7002.com:7002/eureka/, http://eureka7003.com:7003/eureka/ #    defaultZone是固定写法,如果想自定义,需要按以下写法才行:
#    region: eureka-server
#    availability-zones:
#      eureka-server: server1,server2
#    service-url:
#      server1: http://eureka7002.com:7002/eureka/
#      server2: http://eureka7003.com:7003/eureka/
  1. 修改7002的yml文件
eureka:instance:hostname: eureka7002.com  #eureka服务端的实例名称client:register-with-eureka: falsefetch-registry: falseservice-url:#集群版  相互注册,相互守望defaultZone: http://eureka7001.com:7001/eureka/, http://eureka7003.com:7003/eureka/ #相互注册,相互守望
  1. 修改7003的yml文件
eureka:instance:hostname: eureka7003.com  #eureka服务端的实例名称client:register-with-eureka: falsefetch-registry: falseservice-url:#集群版  相互注册,相互守望defaultZone: http://eureka7001.com:7001/eureka/, http://eureka7002.com:7002/eureka/ #相互注册,相互守望
  1. 分别启动该cloud-eureka-server7001, cloud-eureka-server7002和cloud-eureka-server7003

将将支付服务8001和订单服务81微服务发布到集群配置中

把两个项目的yml文件中的defaultZone改为:

#集群版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka

启动5个项目进行测试:(先启动集群,再启动8001,最后启动81)

支付微服务集群配置

  1. 按照8001新建8002。(除了要yml文件中需要改端口号和主配置类,其他直接复制8001的,yml文件中的应用名不需要改,因为是集群,所以应用名需要一致)
  2. 分别在所有的提供者的PaymentController中加入:(这个@Value是spring的注解)
@RestController
@Slf4j
public class PaymentController{@Resourceprivate PaymentService paymentService;@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);}}
}
  1. 修改消费者OrderController,把写死的地址改为服务器名称
     public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
  1. 然后在消费者的ApplicationContextConfig里的restTemplate方法上加上@LoadBalanced,开启RestTemplate开启负载均衡功能。
@Configuration
public class ApplicationContextConfig {@Bean@LoadBalancedpublic RestTemplate getRestTemplate(){return new RestTemplate();}}
  1. 测试

先启动EurekaServer , 7001/70025服务

在启动服务提供者Provider , 8001/8002服务

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

结果:负载均衡效果达到,8001/8002端口交替出现。

actuator微服务信息完善

主机名称:服务名称修改(也就是将IP地址,换成可读性比较高的名字)
访问信息有IP信息提示(鼠标移至服务名称下面 , 会显示对应的IP地址显示)

修改cloud-provider-payment8001,cloud-provider-payment8002,consumer81 名称

#######8001#######
# client:
#    ...    instance要和client对齐instance:instance-id: payment8001prefer-ip-address: true   #访问路径可以显示ip地址#######8002#######instance:instance-id: payment8002   #修改显示的主机名prefer-ip-address: true   #访问路径可以显示ip地址#######80#######instance:instance-id: consumer80   #修改显示的主机名prefer-ip-address: true   #访问路径可以显示ip地址

服务发现Discovery

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

修改提供者集群的Controller

  1. 在主配置类上加上@EnableDiscoveryClient注解,启用发现客户端。
  2. 在两个提供者的PaymentController中加入:

修改cloud-provider-payment8001的主启动

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

修改cloud-provider-payment8001的Controller

@Resourceprivate DiscoveryClient discoveryClient;@GetMapping("/payment/discovery")public Object discovery(){//获取服务列表的信息List<String> services = discoveryClient.getServices();for (String element : services) {log.info("*******element:" + element);}//获取CLOUD-PAYMENT-SERVICE服务的所有具体实例List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");for (ServiceInstance instance : instances) {//getServiceId服务器id getHost主机名称 getPort端口号  getUri地址log.info(instance.getServiceId() + "\t" + instance.getHost() + "\t" + instance.getPort() + "\t" + instance.getUri());}return this.discoveryClient;}

测试

  1. 重启cloud-provider-payment8001服务
  2. 浏览器输入:http://localhost:8001/payment/discovery

浏览器输出:

{"services":["cloud-payment-service","cloud-order-service"],"order":0}

后台输出:

2022-04-03 22:18:50.754  INFO 2820 --- [nio-8001-exec-1] com.zero.controller.PaymentController    : *******element:cloud-payment-service
2022-04-03 22:18:50.754  INFO 2820 --- [nio-8001-exec-1] com.zero.controller.PaymentController    : *******element:cloud-order-service
2022-04-03 22:18:50.758  INFO 2820 --- [nio-8001-exec-1] com.zero.controller.PaymentController    : CLOUD-PAYMENT-SERVICE   192.168.56.1    8002    http://192.168.56.1:8002

Eureka自我保护理论知识

概述

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

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

导致原因

某时刻某一个微服务不可用了,Eureka不会立即清除,依旧会对该服务的信息进行保存。

属于CAP里面的AP分支。

为了EurekaClient端可以正常运行,防止了网络通信不良的情况下,server端不会立即把Client端给剔除掉。

什么是自我保护机制

默认情况下如果在 Server在一定时间内没有介绍到某个Client端没有接受到某个微服务实例的心跳,server端将会注销该实例(默认90秒)。但是当网络分区故障发生 ,client与server之间正常无法通行,本身client端是很健康的本不应该立马去注销这个微服务,Eureka通过自我保护模式来解决这个问题。

自我保护机制:默认情况下client定时向server端发送心跳包(默认间隔90秒),便会直接从服务注册列表中剔除该服务,但是在短时间内丢失了大量的服务实例心跳,这时候server会开启自我保护机制,不会剔除该服务。

怎么禁止自我保护

在EurekaServer端7001处设置关闭自我保护机制

默认配置是开启的

#  client
#   ...     server与client对齐server:#关闭自我保护,默认为trueenable-self-preservation: false#心跳的间隔时间,单位毫秒eviction-interval-timer-in-ms: 2000

关闭效果:

THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.

在EurekaClient端8001

cloud-provider-payment8001的yml文件:

  instance:instance-id: payment8001prefer-ip-address: true   #访问路径可以显示ip地址#Eureka客户端向服务端发送心跳的时间间隔,单位秒(默认30秒)lease-renewal-interval-in-seconds: 1#Eureka服务端在收到最后一次心跳后等待的时间上限,单位秒(默认90秒),超时剔除服务lease-expiration-duration-in-seconds: 2

测试:
* 7001和8001都配置完成
* 先启动7001再启动8001

结果:先关闭8001,马上被删除了

Eureka停更说明

Eureka 2.0 (Discontinued)
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.

Springcloud 介绍 和 Eureka的使用相关推荐

  1. SpringCloud介绍(一)

    1.1         SpringCloud介绍 1.1.1      微服务架构演化 简而言之,微服务就是开发一组小型服务的方式来开发一个独立的应用系统,每个小型服务都运行在自己的进程中,并采用H ...

  2. SpringCloud系列研究---Eureka服务消费Feign

    转载自:https://www.cnblogs.com/chxuyuan/p/8358998.html SpringCloud系列研究---Eureka服务消费Feign 一.Feign简介 Feig ...

  3. 深圳Java培训:springCloud介绍

    深圳Java培训:springCloud介绍 SOA:更注重于相同功能的重用,来构建一条企业功能的主线,其他的功能在这条主线上进行开发和扩展.有点类似于EJB的功能. 微服务:将整个功能拆分成若干个服 ...

  4. 01,什么是微服务和springcloud介绍

    1.什么是微服务 1.1. 微服务介绍 官网: https://www.martinfowler.com/articles/microservices.html 官方定义:微服务就是由一系列围绕自己业 ...

  5. SpringCloud组件:Eureka的服务发现与消费

    在之前的章节我们已经把服务注册到Eureka Server,那么我们该怎么调用已经注册后的服务呢? 我们本章来简单的介绍我们具体该怎么调用服务节点请求内容. 本章目标 消费Eureka注册的服务节点的 ...

  6. 【过程记录】springcloud配置使用Eureka作服务发现组件并进行微服务注册

    Eureka介绍 工具准备 步骤 编写eureka server 编写微服务应用: 查询指定微服务在Eureka上的实例列表 Eureka的自我保护模式 Eureka介绍 Eureka是Netflix ...

  7. springcloud 入门 10 (eureka高可用)

    eureka高可用: 说白了,就是加一个实例作为原实例的备份,然后一起对外提供服务.这样可以保证在一台机器宕机的时候,整个系统不会死掉.保证其继续对外服务. eureka的集群化: 服务注册中心Eur ...

  8. SpringCloud 如何搭建Eureka注册中心

    导语   在之前的分享中介绍了SpringCloud相关的内容,那么如何去搭建一个Spring Cloud Eureka 的注册中心.作为微服务中最为重要的一个组件,怎么去搭建一个服务注册中心称为关键 ...

  9. SpringCloud实战与原理分析--第二章:SpringCloud介绍

    我准备向他提出一个他不可能拒绝的条件.--<教父> 1.引言 首先,我们来看看一般的微服务架构需要的功能或使用场景: (1)我们把整个系统根据业务拆分成几个子系统. (2)每个子系统可以部 ...

最新文章

  1. 一切都是问题,一切都着落在自身
  2. 1.10 instanceof关键字
  3. 新人与三年经验的交互设计师有多大的差距?
  4. 如何处理SAP Fiori Launchpad KPI tile点击后出现的错误消息
  5. hadoop2.7.3+spark2.1.0+scala2.12.1环境搭建(4)SPARK 安装
  6. Objective-C的内省(Introspection)小结
  7. QT编程之——使用全局变量
  8. Stream篇(2)【TextReader】
  9. WPF ControlTemplate 仿QQ概念版CheckBox
  10. ubntu系统克隆到其他计算机的方法
  11. 一般人我不告诉的bug
  12. php快递地址填写,智能识别快递地址api接口实现(PHP示例)
  13. 【隧道应用-3】Cobalt Strike正向连接多层内网
  14. C语言字符串笔试题含答案
  15. 正则表达式——python对字符串的查找匹配
  16. HNUST OJ 2295 嘉嘉的队伍配置
  17. Keil MDK编译出现..\USER\stm32f10x.h(428): error: #67: expected a “}“错误的解决办法
  18. 80后站长建站的经验总结
  19. 一款可以对接多用户商城系统的客服系统
  20. 每周读书#7 - 《三体》

热门文章

  1. Room框架学习、使用
  2. 计算机的供电方式,电脑主板电源供电方式
  3. 口腔菌群想要突破?这一方法潜力无限
  4. Global Industry Analysts称全球MSS市场在2017年达到112亿美元
  5. 【UVA1723】Intervals
  6. 2018-2019 ICPC, NEERC, Northern Eurasia Finals K. King Kog's Reception 线段树
  7. 关于MTTF、MTBF、MTRF
  8. 第二篇 第三章防火防烟分区检查(一)
  9. WIFI 认证 测试
  10. GitHub 上100个优质前端项目整理,非常全面!