SpringCloud起步笔记教程

SpringCloud起步笔记教程

1. 微服务架构和SpringCloud

多维度下的数字化生活

定义:

  • 微 狭义来讲就是单个应用的体积小
  • 微服务架构风格是一种使用一套小服务来开发单个应用的方式途径
  • 提高扩展性,可靠性,降低维护成本

优势:

  • 单体架构的问题:

    主要有以下几点:

    1.复杂性逐渐变高

    • 比如有的项目有几十万行代码,各个模块之间区别比较模糊,逻辑比较混乱,代码越多复杂性越高,越难解决遇到的问题。

    2.技术债务逐渐上升

    • 公司的人员流动是再正常不过的事情,有的员工在离职之前,疏于代码质量的自我管束,导致留下来很多坑,由于单体项目代码量庞大的惊人,留下的坑很难被发觉,这就给新来的员工带来很大的烦恼,人员流动越大所留下的坑越多,也就是所谓的技术债务越来越多。

    3.部署速度逐渐变慢

    • 这个就很好理解了,单体架构模块非常多,代码量非常庞大,导致部署项目所花费的时间越来越多,曾经有的项目启动就要一二十分钟,这是多么恐怖的事情啊,启动几次项目一天的时间就过去了,留给开发者开发的时间就非常少了。

    4.阻碍技术创新

    • 比如以前的某个项目使用struts2写的,由于各个模块之间有着千丝万缕的联系,代码量大,逻辑不够清楚,如果现在想用spring mvc来重构这个项目将是非常困难的,付出的成本将非常大,所以更多的时候公司不得不硬着头皮继续使用老的struts架构,这就阻碍了技术的创新。

    5.无法按需伸缩

    • 比如说电影模块是CPU密集型的模块,而订单模块是IO密集型的模块,假如我们要提升订单模块的性能,比如加大内存、增加硬盘,但是由于所有的模块都在一个架构下,因此我们在扩展订单模块的性能时不得不考虑其它模块的因素,因为我们不能因为扩展某个模块的性能而损害其它模块的性能,从而无法按需进行伸缩。

而微服务每个模块就相当于一个单独的项目,代码量明显减少,遇到问题也相对来说比较好解决。

SpringCloud

主题词:基于分布式的微服务架构

  • SpringCloud=分布式微服务架构的一站式解决方案,是多种微服务架构落地技术的集合体,俗称微服务全家桶
    • 通常是一个整体
  • SpringBoot是一种服务开发技术(技术栈)
    • 服务注册与发现:EUREKA
    • 服务负载均衡与调用:NETFLIX OSS RIBBON
    • 服务负载与调用:NETTFLIX
    • 服务熔断降级:HYSTRIX
    • 服务网关:Zuul
    • 服务分布式配置:SpringCloud Config
    • 服务开发:SpingBoot

2 Project工作空间

2.1 总父工程

  • 约定>配置>编码

  • IDEA新建project工作空间

  • Rest微服务工作架构

2.1.1 IDEA新建project工作空间
  1. new Project

  2. 聚合总父工程名字

  3. Maven选版本

  4. 工程名字

  5. 字符编码

请添加图片描述

  1. 注册生效激活

    * [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q1adMMm2-1662018234740)(C:\Users\86130\AppData\Roaming\Typora\typora-user-images\image-20220320152024882.png)]

    • 表示支持我们的注解
  2. java编译版本选8

  3. File Type过滤(可不做)

2.2.2 父工程的pom配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mnZLd0M6-1662018234740)(C:\Users\86130\AppData\Roaming\Typora\typora-user-images\image-20220320152344554.png)]

加  <packaging>pom</packaging>
<?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>org.example</groupId>
  <artifactId>springcloud</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>


  <!--统一管理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>8.0.18</mysql.version>
    <druid.verison>1.1.16</druid.verison>
    <mybatis.spring.boot.verison>1.3.0</mybatis.spring.boot.verison>
  </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.2.0.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <!-- MySql -->
      <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.version}</version>
      </dependency>
      <!-- Druid -->
      <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>${druid.verison}</version>
      </dependency>
      <!-- mybatis-springboot整合 -->
      <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>${mybatis.spring.boot.verison}</version>
      </dependency>
      <!--lombok-->
      <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.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>
        <version>2.6.4</version>
        <configuration>
          <fork>true</fork>
          <addResources>true</addResources>
        </configuration>
      </plugin>
    </plugins>
  </build>


</project>

dependencyManagement 中定义版本号,如果子项目不写不会从父项目中导入,类似与Java中的接口

2.2.3mvn install

用来打包

2.2Rest微服务工作架构

消费者80调用8001支付模块

微服务模块
  1. 建module
  2. 改pom
  3. 写yml
  4. 主启动
  5. 业务类

代码:D:\java笔记\SpringCloud\Project032001

2.3 自动热部署devtools

2.3.1 子工程pom插入

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

2.3.2 父工程中插入plugin

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

2.3.3 Enabling automatic build

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tvJiEOPl-1662018234741)(C:\Users\86130\AppData\Roaming\Typora\typora-user-images\image-20220321000717152.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JWnLjcpF-1662018234741)(C:\Users\86130\AppData\Roaming\Typora\typora-user-images\image-20220321000901142.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iVBd7Ai8-1662018234742)(C:\Users\86130\AppData\Roaming\Typora\typora-user-images\image-20220321000943420.png)]

2.4 RestTemplate

80端对8001的远程调用

public class OrderController {
    public static final String PAYMENT_URL = "http://localhost:8001";

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/consumer/payment/create")
    public CommonResult<Payment> creat(Payment payment) {
        return restTemplate.postForObject(PAYMENT_URL + "payment/add", 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);
    }

}

3.Eureka 基础知识

Eureka服务注册与发现

  1. 什么是服务注册
    • Eureka采用CS的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册中心,而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接,这样系统的维护人员就可以通过Eureka Server来监控各个微服务是否正常运行
    • 在服务注册于发现中,有一个注册中心,当服务器启动的时候,会把当前自己服务器的信息 比如 服务地址通讯地址等以别名方式注册到注册中心上。另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际的通讯地址,然后在实现本地RPC调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理理念)。在任何RPC远程框架中,都会有一个注册中心
  2. Eureka包含两个组件:Eureka Server和Eureka Client
    • Eureka Server提供服务注册服务
      • 各个微服务节点通过配置启动后,会在EurekaServer中注册,这样EurekaServer中的服务注册表中将会存储所有 可用服务节点的信息,服务节点的信息可以在界面中直观看到
    • Eureka Client通过注册中心进行访问
      • 是一个java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期30s)。如果Eureka Server在多个心跳周期内没有接受到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90s)
      • 类比物业

pom的配置

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>3.0.2</version>
        </dependency>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>cloud-api-common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!--监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

yml配置

server:
  port: 7001

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

主启动类

package com.atguigu.springcloud;

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

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

启动localhost7001后

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qlrAX8Wy-1662018234743)(C:\Users\86130\AppData\Roaming\Typora\typora-user-images\image-20220321221054937.png)]

还未有入住

client端!!!!!!!!!!!!!!!!!

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

启动测试

先Eureka 再Client

出现以下信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QRYaWheA-1662018234743)(C:\Users\86130\AppData\Roaming\Typora\typora-user-images\image-20220321223725013.png)]

Eurake集群原理说明

互相注册,相互调用

eureka7001 <----相互调用----> eureka7002

修改eureka的yml

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yf1Ug2k2-1662018234744)(C:\Users\86130\AppData\Roaming\Typora\typora-user-images\image-20220322142640752.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H3ZDas0U-1662018234744)(C:\Users\86130\AppData\Roaming\Typora\typora-user-images\image-20220322142656239.png)]

DiscoveryClient

@Resource
private DiscoveryClient discoveryClient;

使用方法

@GetMapping("/discovery")
public Object discovery(){
    List<String> services = discoveryClient.getServices();
    for(String element:services)
    {
        log.info("*****element:"+element);
    }
    List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");

    for(ServiceInstance instance:instances)
    {
        log.info(instance.getServiceId()+"\t"+instance.getHost()+"\t"+instance.getPort()+"\t"+instance.getUri());
    }

    return  this.discoveryClient;
}
CLOUD-PAYMENT-SERVICE	10.162.51.222	8002	http://10.162.51.222:8002
CLOUD-PAYMENT-SERVICE	10.162.51.222	8001	http://10.162.51.222:8001

Eureka停更说明

停更不停用

4 zookeeper

  • 是一个分布式协调工具,可以实现注册中心功能
  • Eureka的替代品

提供的服务包括:

  • 分布式消息同步和协调机制
  • 服务器节点动态上下线
  • 统一配置管理
  • 负载均衡
  • 集群管理

依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
        </dependency>

zookeeper命令行:

在服务器中打开zookeeper安装目录

打开bin目录

  1. ls /列出
  2. create /node ‘name’ 新建node
  3. get /node 获取文件:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d4G4IVGz-1662018234744)(C:\Users\86130\AppData\Roaming\Typora\typora-user-images\image-20220630135311520.png)]

配置zookeeper

application.yml

server:
  port: 8006

spring:
  application:
    name: cloud-provider-payment
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/premission?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
    username: root
    password: '010213'
  cloud:
    zookeeper:
      connect-string: 121.4.111.212:2181
package com.example;

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

@SpringBootApplication
@EnableDiscoveryClient //该注解用于向使用consul或者zookeeper作为注册中心时注册服务
public class PaymentMain8006 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8006.class,args);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bhirImFK-1662018234745)(C:\Users\86130\AppData\Roaming\Typora\typora-user-images\image-20220630140115117.png)]

出现service

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QVy0Bxwg-1662018234745)(C:\Users\86130\AppData\Roaming\Typora\typora-user-images\image-20220630140238446.png)]

907996bd-6a91-4d86-aef2-442ffc6622be内部编码流水号

获得基本信息

临时还是持久结点?

(Eureka的自我保护机制,会相对保存)

zookeeper会不断更新id

报错:

	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)

ps: zookeeper和log4j不能重复调用

5. Consul注册

与zookeeper和Eureka相同

主要功能;

  • 服务发现:
    提供HTTP和DNS两种发现方式

  • 健康检测:

    支持多种方式:

    HTTP、TCP、Docker、Shell脚本定制化

  • KV存储:

    Key、Value存储方式

  • 多数据中心:
    Consul支持多数据中心

  • 可视化Web界面

三个注册中心的异同点

在这里插入图片描述

AP、CP、CP的值:

C:强一致

A:可用性

P:分区容错性

AP:奔溃了还能存活

Cp:奔溃了就没了

6. Ribbon

负载均衡服务调用

基于Nerflix Ribbon 实现的一套客户端,负载均衡的工具

主要功能是提供客户端的软件负载均衡算法和服务调用

Ribbon客户端组件提供了一系列完善的配置项:

  • 连接超时
  • 重试等

简单来说:就是在配置文件中列出Load Balancer(简称LB)后面所有的及其

Ribbon会自动的帮助你基于某种规则(如简单轮询、随机连接等)去连接及其

我们很容易使用Ribbon来实现自定义的负载均衡算法

LB负载均衡(Load Balance)是什么

简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用)。常见的负载均衡有软件Nginx,LVS,硬件F5等。

Ribbon本地负载均衡客户端 VS Nginx服务端负载均衡区别

  • Nginx是服务器负载均衡,客户端所有请求都会交给nginx,然后由nginx实现转发请求。即负载均衡是由服务端实现的。

    集中式LB
    即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5,也可以是软件,如nginx)由该设施负责把访问请求通过某种策略转发至服务的提供方;

  • 本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到 JVM本地,从而在本地实现RPC远程服务调用技术。

    进程内LB
    将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。
    Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址

负载均衡算法:

  1. 随机,通过随机选择服务进行执行,一般这种方式使用较少;
  2. 轮训,负载均衡默认实现方式,请求来之后排队处理;
  3. 加权轮训,通过对服务器性能的分型,给高配置,低负载的服务器分配更高的权重,均衡各个服务器的压力;
  4. 地址Hash,通过客户端请求的地址的HASH值取模映射进行服务器调度。
  5. 最小链接数;即使请求均衡了,压力不一定会均衡,最小连接数法就是根据服务器的情况,比如请求积压数等参数,将请求分配到当前压力最小的服务器上。
  6. 其他若干方式。

Ribbon 其实是一个软负载均衡的客户端组件

它可以和其他所需请求的客户端结合需求

依赖

eruka框架已经使用了Ribbon的依赖,引入eruka 的依赖则不需要引入ribbon

RestTemplate的使用

常用Get、Post

  • getForObject():可以理解为返回json
  • getForEntity():返回的是对象

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

    @GetMapping("/consumer/payment/getForEntity/{id}")
    public CommonResult<Payment> getPayment2(@PathVariable("id") Long id) {
        ResponseEntity<CommonResult> entity=restTemplate.getForEntity(PAYMENT_URL + "payment/get/" + id, CommonResult.class);

        if(entity.getStatusCode().is2xxSuccessful()){
            return entity.getBody();
        }
        else{
            return new CommonResult<>(444,"操作失败");
        }
    }

Ribbon负载均衡演示

IRule:

根据特定算法中选择其中一个

如何替换

自定义配置类不能放在@ComponentScan所扫描的及其子包下,以达到定制的目的

创建MySelfRule规则类

需要单独创建一个myrule,要和OrderMain81类分开(@SpringApplication注解会自动扫描子包)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值