什么是Spring Clould

Spring Cloud是由Spring提供的一套能够快速搭建微服务架构程序的框架集

框架集表示Spring Cloud不是一个框架,而是很多框架的统称

Spring Cloud就是为了搭建微服务架构项目出现的

Spring Cloud侠义上就成为"Spring全家桶"。

Spring Cloud主要功能上的分类

  • 微服务的注册中心
  • 微服务间的调用
  • 微服务的分布式事务
  • 微服务的限流
  • 微服务的网关

注册中心Nacos

什么是Nacos

Nacos是Spring Cloud Alibaba提供的一个软件

这个软件主要具有注册中心和配置中心的功能在本文,我们先学习它注册中心的功能

微服务中所有项目都必须注册到注册中心才能成为微服务的一部分

当前微服务项目中所有的模块,在启动前,必须添加注册到Nacos的配置所谓注册

就是将自己的信息,提交到Nacos来保存。

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_服务器

 Nacos的下载地址

https://github.com/alibaba/nacos/releases/download/1.4.3/nacos-server-1.4.3.zip

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_权重_02

https://github.com/alibaba/nacos/releases/download/1.4.3/nacos-server-1.4.3.zip

Nacos的启动

默认已完成Java的开发环境配置。

文件下载后,文件显示如下

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_spring cloud_03

 cmd结尾的文件是windows版本的

sh结尾的文件是linux和mac版本的

startup是启动文件,shutdown是停止文件

  Windows下启动Nacos

在dos窗口运行,并进去Nacos文件解压后的bin文件夹,输入如下命令

D:\tools\nacos\bin>startup.cmd -m standalone

 (或者)在Idea环境下运行

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_微服务_04

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_spring cloud_05

 

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_微服务_06

 Nacos运行成功的标记

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_微服务_07

 默认端口8848

在浏览器输入地址http://localhost:8848/nacos  可以进去Nacos页面

如果是首次访问,会出现这个界面

登录系统

用户名:nacos

密码:nacos

登录之后可以进入后台列表

不能关闭启动nacos的dos窗口

我们要让我们编写的项目注册到Nacos,才能真正是微服务项目

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_spring_08

 把项目添加入Nacos

创建项目

以此项目为载体展示 https://gitee.com/wingxu8859_admin/csmall

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_权重_02

https://gitee.com/wingxu8859_admin/csmall

此项目主要实现的需求为,把每一个项目(主要分为订单,购物车,库存三个大类),进行统一管理端口从而实现:新增一个订单=>同时需要减少购物车和减少库存 。

整体实现的逻辑如下图:

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_微服务_10

 上图各个色块的代码设置可以参考下面各图。

csmall项目:

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_spring cloud_11

csmall-business项目:

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_spring cloud_12

 csmall-commons项目:

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_spring_13

csmall-order项目及其2个子项目csmall-order-service和csmall-order-webapi:

 

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_微服务_14

 csmall-cart项目及其2个子项目csmall-cart-service和csmall-cart-webapi:

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_服务器_15

 csmall-order项目及其2个子项目csmall-order-service和csmall-order-webapi:

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_spring cloud_16

 gateway项目:

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_spring_17

 Nacos心跳机制

项目配置完成启动后,输入http://localhost:8848/nacos可以进入Nacos页面。

在服务管理=>服务列表里面,可以看到在Nacos注册了的项目。

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_spring_18

 项目名称写在yml文件里面。

spring:
  application:
    #  为当前项目起名,这个名字会被Nacos记录并使用
    name: nacos-business
  cloud:
    nacos:
      discovery:
        # 配置Nacos所在的位置,用于注册时提交信息
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8722

Dubbo概述

什么是RPC

RPC是Remote Procedure Call的缩写 翻译为:远程过程调用

目标是为了实现两台(多台)计算机\服务器,相互调用方法\通信的解决方案

RPC只是实现远程调用的一套标准

该标准主要规定了两部分内容

1.通信协议

2.序列化协议

这个流程可以理解为项目内的功能的调用,类似面向对象编程实例化对象,调用方法的过程

但是这个调用关系如果是远程的

为了方便大家理解RPC,下面的图片帮助理解:

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_服务器_19

通讯协议

通信协议指的就是远程调用的通信方式

实际上这个通知的方式可以有多种

例如:写信,飞鸽传书,闪送等等

在程序中,通信方式也有多种

序列化协议

序列化协议指通信内容的格式,双方都要理解这个格式

上面的图片中,老婆给老公发信息,一定是双方都能理解的信息

发送信息是序列化过程,接收信息需要反序列化

程序中,序列化的方式也是多种的

什么是Dubbo

上面对RPC有基本认识之后,再学习Dubbo就简单了

Dubbo是一套RPC框架。既然是框架,我们可以在框架结构高度,定义Dubbo中使用的通信协议,使用的序列化框架技术,而数据格式由Dubbo定义,我们负责配置之后直接通过客户端调用服务端代码。

可以说Dubbo就是RPC概念的实现

Dubbo是SpringCloudAlibaba提供的框架

能够实现微服务相互调用的功能!

Dubbo对协议的支持

RPC框架分通信协议和序列化协议

Dubbo框架支持多种通信协议和序列化协议,可以通过配置文件进行修改

Dubbo支持的通信协议

  • dubbo协议(默认)
  • rmi协议
  • hessian协议
  • http协议
  • webservice
  • .....

支持的序列化协议

  • hessian2(默认)
  • java序列化
  • compactedjava
  • nativejava
  • fastjson
  • dubbo
  • fst
  • kryo

Dubbo默认情况下,支持的协议有如下特征

  • 采用NIO单一长链接
  • 优秀的并发性能,但是处理大型文件的能力差

Dubbo方便支持高并发和高性能

Dubbo服务的注册与发现

在Dubbo的调用过程中,必须包含注册中心的支持

注册中心推荐阿里自己的Nacos,兼容性好,能够发挥最大性能

但是Dubbo也支持其它软件作为注册中心(例如Redis,zookeeper等)

服务发现,即消费端自动发现服务地址列表的能力,是微服务框架需要具备的关键能力,借助于自动化的服务发现,微服务之间可以在无需感知对端部署位置与 IP 地址的情况下实现通信。

上面RPC的示例中,老婆就是服务的消费端,她能发现老公具备的服务

如果老婆调用了老公的服务,就是完成了Dubbo调用

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_服务器_20

consumer服务的消费者,指服务的调用者(使用者)也就是老婆的位置

provider服务的提供者,指服务的拥有者(生产者)也就是老公的位置

在Dubbo中,远程调用依据是服务的提供者在Nacos中注册的服务名称

一个服务名称,可能有多个运行的实例,任何一个空闲的实例都可以提供服务

我们当前csmall项目的远程调用关系如下:

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_服务器_21

 Dubbo实现微服务调用

  • order模块调用stock模块的减少库存的功能
  • order模块调用cart模块的删除购物车的功能
  • business模块调用order新增订单的功能

要想实现Dubbo调用

必须按照Dubbo规定的配置和行业标准的结构来实现

Dubbo调用的好处是直接将要消费的目标(例如order模块中消费stock的方法)编写在当前消费者的业务逻辑层中,无需编写新的代码结构,开发流程不会因为Dubbo而变化

@DubboService //为business提供服务
@Service
@Slf4j
public class OrderServiceImpl implements IOrderService {

    @Autowired
    private OrderMapper orderMapper;
    // 添加@DubboReference注解,表示当前业务逻辑层代码,要消费其它模块的服务
    // 可以编写当前Nacos中注册的其它模块的业务逻辑层接口
    // 因为在Nacos中注册的是接口的实现类,可以实现自动装配实现类的效果
    // 先添加stock模块的业务对象,有些公司要求dubbo引用的对象使用dubbo开头
    @DubboReference
    private IStockService dubboStockService;
    @DubboReference
    private ICartService dubboCartService;

    @Override
    public void orderAdd(OrderAddDTO orderAddDTO) {
        // 1.减少订单中商品的库存数(要调用stock模块的方法)
        // 实例化减少订单业务的DTO对象
        StockReduceCountDTO countDTO=new StockReduceCountDTO();
        countDTO.setCommodityCode(orderAddDTO.getCommodityCode());
        countDTO.setReduceCount(orderAddDTO.getCount());
        // dubbo调用stock模块减少库存数的方法
        dubboStockService.reduceCommodityCount(countDTO);
        // 2.删除订单中选中的购物车的商品(要调用cart模块的方法)
        dubboCartService.deleteUserCart(orderAddDTO.getUserId(),
                                        orderAddDTO.getCommodityCode());
        // 3.执行将orderAddDTO中的信息新增到订单表中的功能
        // 实例化一个Order对象
        Order order=new Order();
        BeanUtils.copyProperties(orderAddDTO,order);
     
        orderMapper.insertOrder(order);
        log.info("新增的订单信息为{}",order);
    }
}

负载均衡

什么是负载均衡

在实际项目中,一个服务基本都是集群模式的,也就是多个功能相同的项目在运行,这样才能承受更高的并发

这时一个请求到这个服务,就需要确定访问哪一个服务器

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_权重_22

Dubbo框架内部支持负载均衡算法,能够尽可能的让请求在相对空闲的服务器上运行

在不同的项目中,可能选用不同的负载均衡策略,以达到最好效果

Loadbalance:就是负载均衡的意思

Dubbo内置负载均衡策略的算法

Dubbo内置4种负载均衡算法

  • random loadbalance:随机分配策略(默认)
  • round Robin Loadbalance:权重平均分配
  • leastactive Loadbalance:活跃度自动感知分配
  • consistanthash Loadbalance:一致性hash算法分配

实际运行过程中,每个服务器性能不同

在负载均衡时,都会有性能权重,这些策略算法都考虑权重问题

随机分配策略

假设我们当前3台服务器,经过测试它们的性能权重比值为5:3:1

下面可以生成一个权重模型

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_spring_23

随机生成随机数

在哪个范围内让哪个服务器运行

优点:

算法简单,效率高,长时间运行下,任务分配比例准确

缺点:

偶然性高,如果连续的几个随机请求发送到性能弱的服务器,会导致异常甚至宕机

权重平滑分配

如果几个服务器权重一致,那么就是依次运行

但是服务器的性能权重一致的可能性很小

所以我们需要权重平滑分配

一个优秀的权重分配算法,应该是让每个服务器都有机会运行的

如果一个集群服务器性能比为5:3:1

1>A 2>A 3>A 4>A 5>A 6>B 7>B 8>B 9>C

10>A

上面的安排中,连续请求一个服务器肯定是不好的,我们希望所有的服务器都能够穿插在一起运行

Dubbo2.7之后更新了这个算法使用"平滑加权算法"优化权重平均分配策略

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_spring cloud_24

优点:

能够尽可能的在权重要求的情况下,实现请求的穿插运行(交替运行),不会发生随机策略中的偶发情况

缺点

服务器较多时,可能需要减权和复权的计算,需要消耗系统资源

活跃度自动感知

记录每个服务器处理一次请求的时间

按照时间比例来分配任务数,运行一次需要时间多的分配的请求数较少

一致性Hash算法

根据请求的参数进行hash运算

以后每次相同参数的请求都会访问固定服务器

因为根据参数选择服务器,不能平均分配到每台服务器上

使用的也不多

Seata概述

为什么需要Seata

我们之前学习了单体项目中的事务

使用的技术叫Spring声明式事务

能够保证一个业务中所有对数据库的操作要么都成功,要么都失败,来保证数据库的数据完整性

但是在微服务的项目中,业务逻辑层涉及远程调用,当前模块发生异常,无法操作远程服务器回滚

这时要想让远程调用也支持事务功能,就需要使用分布式事务组件Seata

事务的4个特性:ACID特性

  • 原子性
  • 一致性
  • 隔离性
  • 永久性

Seata保证微服务远程调用业务的原子性

Seata将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

Seata的运行原理(AT模式)

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_微服务_25

上面结构是比较典型的远程调用结构

如果account操作数据库失败需要让order模块和storage模块撤销(回滚)操作

声明式事务不能完成这个操作

需要使用Seata来解决

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_spring_26

Seata构成部分包含

  • 事务协调器TC
  • 事务管理器TM
  • 资源管理器RM

我们项目使用AT(自动)模式完成分布式事务的解决

AT模式运行过程

1.事务的发起方(TM)会向事务协调器(TC)申请一个全局事务id,并保存

2.Seata会管理事务中所有相关的参与方的数据源,将数据操作之前和之后的镜像都保存在undo_log表中,这个表是seata组件规定的表,没有它就不能实现效果,依靠它来实现提交(commit)或回滚(roll back)的操作

3.事务的发起方(TM)会连同全局id一起通过远程调用运行资源管理器(RM)中的方法

4.RM接收到全局id,去运行指定方法,并将运行结果的状态发送给TC

5.如果所有分支运行都正常,事务管理器(TM)会通过事务协调器通知所有模块执行数据库操作,真正影响数据库内容,反之如果有任何一个分支模块运行异常,都会通知TC,再由TC通知所有分支将数据库操作回滚,恢复成运行之前的样子

Seata的启动

seata也是java开发的,启动方式和nacos很像

只是启动命令不同

它要求配置环境变量中Path属性值有java的bin目录路径

解压后路径不要用中文,不要用空格

也是解压之后的bin目录下

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_微服务_27

在路径上输入cmd进入dos窗口

D:\tools\seata\seata-server-1.4.2\bin>seata-server.bat -h 127.0.0.1 -m file

输入后,最后出现8091端口的提示即可!

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_spring_28

其它模式简介

上次课我们讲解了Seata软件AT模式的运行流程

AT模式的运行有一个非常明显的前提条件,这个条件不满足,就无法使用AT模式

这个条件就是事务分支都必须是操作关系型数据库(mysql\MariaDB\Oracle)

因为关系型数据库才支持提交和回滚,其它非关系型数据库都是直接影响数据(例如Redis)

所以如果我们在业务过程中有一个节点操作的是Redis或其它非关系型数据库时,就无法使用AT模式

除了AT模式之外还有TCC、SAGA 和 XA 事务模式

TCC模式

简单来说,TCC模式就是自己编写代码完成事务的提交和回滚

在TCC模式下,我们需要为参与事务的业务逻辑编写一组共3个方法

(prepare\commit\rollback)

prepare:准备

commit:提交

rollback:回滚

  • prepare方法是每个模块都会运行的方法
  • 当所有模块的prepare方法运行都正常时,运行commit
  • 当任意模块运行的prepare方法有异常时,运行rollback

这样的话所有提交或回滚代码都由自己编写

优点:虽然代码是自己写的,但是事务整体提交或回滚的机制仍然可用(仍然由TC来调度)

缺点:每个业务都要编写3个方法来对应,代码冗余,而且业务入侵量大

SAGA模式

SAGA模式的思想是对应每个业务逻辑层编写一个新的类,可以设置指定的业务逻辑层方法发生异常时,运行当新编写的类中的代码

这样编写代码不影响已经编写好的业务逻辑代码

一般用于修改已经编写完成的老代码

缺点是每个事务分支都要编写一个类来回滚业务,

会造成类的数量较多,开发量比较大

XA模式

支持XA协议的数据库分布式事务,使用比较少

 

SpringGateway网关

奈非框架简介

早期(2020年前)奈非提供的微服务组件和框架受到了很多开发者的欢迎

这些框架和SpringCloud Alibaba的对应关系我们要了解

现在还有很多旧项目维护是使用奈非框架完成的微服务架构

Nacos对应Eureka都是注册中心

Dubbo对应Ribbon+feign都是实现微服务远程RPC调用的组件

Sentinel对应Hystrix都是做项目限流熔断降级的组件

Gateway对应Zuul都是网关组件

Gateway框架不是阿里写的,是Spring提供的

什么是网关

"网"指网络,"关"指关口或关卡

网关:就是指网络中的关口\关卡

网关就是当前微服务项目的"统一入口"

程序中的网关就是当前微服务项目对外界开放的统一入口

所有外界的请求都需要先经过网关才能访问到我们的程序

提供了统一入口之后,方便对所有请求进行统一的检查和管理

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_权重_29

网关的主要功能有

  • 将所有请求统一经过网关
  • 网关可以对这些请求进行检查
  • 网关方便记录所有请求的日志
  • 网关可以统一将所有请求路由到正确的模块\服务上

路由的近义词就是"分配"

Spring Gateway简介

我们使用Spring Gateway作为当前项目的网关框架

Spring Gateway是Spring自己编写的,也是SpringCloud中的组件

SpringGateway官网

Spring Cloud Gateway

网关项目git地址:引用自达内课堂的demo项目

jtzhanghl/gateway-demohttps://gitee.com/jtzhanghl/gateway-demo.git

 总结

整个csmall demo项目实现了简单的微服务搭建

搭建spring cloud脚手架的作用 如何搭建spring cloud框架_微服务_10

项目的架构为,csmall为全部项目的父类项目,旗下有business项目=>操作order项目=>分别操作cart和stock项目,而cart和stock项目通过commons获取了pojo、ex、restful类,而不用在每个项目中都配置这些公共类。这几个项目统一通过gateway的网管类来统一配置路由,实现客户只需要通过网关路由即可访问到全部项目的内容,把子项目的端口隐藏起来。

各个项目之间需要通过Nacos进行注册,注册后再通过Dubbo来远程调用。

由于各个项目都对应了一个数据库的表,在business调用order从而调用各个项目的过程当中,需要对多个数据表进行操作,如果其中有部分数据表更新了但有部分数据表又无法进行更新,需要对数据表进行回滚,以免产生脏数据,此时就需要用到Seata进行全局事务管理,这种做法有点类似Spring框架的@Transactional注解。

最后,由于可能会存在高并发的问题,到时同一时间内可能有多个客户端访问数据,就需要用到Sentinel对项目进行限流操作。

此微服务知识来源于达内教育,老师专业授课,把各架构通俗易懂地阐述。