Spring Cloud Alibaba

1、Spring Cloud Alibaba

1.1、Spring Cloud Alibaba概述

官网地址:https://spring.io/projects/spring-cloud-alibaba
前文: Spring Cloud

Spring Cloud Alibaba 为分布式应用开发提供一站式解决方案。它包含开发分布式应用程序所需的所有组件,使您可以轻松地使用 Spring Cloud 开发应用程序。

使用Spring Cloud Alibaba,您只需添加一些注解和少量配置,即可将Spring Cloud应用连接到阿里巴巴的分布式解决方案,并通过阿里巴巴中间件构建分布式应用系统。

简单来说,Spring Cloud Alibaba 本质上就是Alibab基于Java自己封装的一些组件,在前面了解Spring Cloud的时候,Spring Cloud也就是在做微服务开发所提供的一系列组件。

1.2、Spring Cloud Alibaba 与 Spring Cloud

上面说到对于Spring Cloud Alibaba提供的一系列组件本质和Spring Cloud 提供的组件差不多,如下表:

Spring Cloud Spring Cloud Alibaba
服务注册中心 Eureka、Consul Nacos
流控(服务熔断) Hystrix Sentinel
统一配置中心 Config Nacos
服务通信、负载均衡 Ribbon、OpenFeign Dubbo RPC

2、Hello World

首先还是和Spring Cloud 项目一致,先构建一个父项目用来统一管理cloud和boot的版本。这里的Alibaba cloud 使用2.2.1版,而cloud和boot还是和前面的spring cloud使用H SR6和2.2.5版本,

github地址:https://github.com/lizuoqun/springcloudalibaba_parent (master分支)

<?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.lzq</groupId>
    <artifactId>springcloudalibaba_parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
    </parent>

    <properties>
        <spring.cloud-version>Hoxton.SR6</spring.cloud-version>
        <spring.cloud.alibaba-version>2.2.1.RELEASE</spring.cloud.alibaba-version>
    </properties>


    <dependencyManagement>
        <dependencies>
            <!-- 版本维护 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring.cloud.alibaba-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

3、服务注册中心、统一配置中心 Nacos

Nacos官网:https://nacos.io/zh-cn/docs/what-is-nacos.html

3.1、Nacos概述

Nacos :Name Configuration Service

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

nacos下载地址:https://github.com/alibaba/nacos/releases

3.2、Nacos的安装和启动

在github上进行下载好慢,最后还是从别人分享的网盘当中下的,这里选择2.0.3版本的Nacos,下载gz文件,部署到linux虚拟机上,首先将gz文件上传给虚拟机,之后进行解压这个gz文件,在这之前还需要安装jdk,linux安装jdk这里也不做详细赘述了,解压后进入到nacos文件下,整个项目下包含3个主要文件夹,分别是bin——启动关闭nacos的脚本目录、conf——配置文件、target——核心jar包。

而后在启动Nacos的时候,默认会以集群进行启动,但是首先还是通过单机版本进行启动,使用命令:./startup.sh -m standalone,在启动之后返回到上一层目录下,会有一个log文件夹,也就是Nacos的日志,进入log文件夹,使用tail -f nacos.log进行查看日志。启动完成之后直接进行访问web端地址:http://192.168.101.128:8848/nacos 之后进行登录系统,默认账号和密码都是nacos

3.3、Nacos服务注册中心

首先构建一个SpringBoot的项目,引入SpringBoot、Nacos Client的依赖:

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

之后只需要在配置文件当中指定需要注册的Nacos的服务地址即可。

# 总地址
spring.cloud.nacos.server-addr=192.168.101.128:8848

# 服务注册中心地址,默认取值${spring.cloud.nacos.server-addr}
# spring.cloud.nacos.discovery.server-addr=192.168.101.128:8848

3.4、服务通信与负载均衡

在Alibaba的Nacos当中我们需要进行服务通信,而在Alibaba里面并没有提供相关服务,但是在Nacos Client当中集成了Ribbon依赖,所以在这里使用负载均衡还是使用Spring Cloud当中的Ribbon组件,这里在之前已经阐述过了,这里就不过多赘述了。

再往后和之前使用Ribbon进行实现负载均衡一样存在问题,这里就需要引入OpenFeign组件进行避免问题。

3.5、Nacos统一配置中心

在Nacos当中还提供了统一配置中心的管理,首先构建一个SpringBoot的项目,之后将服务注册到Nacos上面,在Nacos的web页面上会有一个配置管理,添加一个配置,这里的配置也就是当前SpringBoot应用要用到的公共配置。

Spring Cloud Alibaba
Spring Cloud Alibaba

而原本的项目我们需要配置项目去哪里去找这个配置项,并且配置文件文件名需要修改为bootstrap,配置文件如下:

# Nacos地址
spring.cloud.nacos.config.server-addr=192.168.101.128:8848
# 配置文件的分组
spring.cloud.nacos.config.group=DEFAULT_GROUP
# 配置文件文件名
spring.cloud.nacos.config.name=config-prod
# 配置文件文件后缀
spring.cloud.nacos.config.file-extension=properties

之后进行启动项目也就可以读到Nacos上面给配置的公共配置了,在这里配置实时更新,只需要在对应的Controller类上加上@RefreshScope注解,之后在Nacos上进行修改配置,配置就会进行自动刷新了。

3.6、Nacos统一配置中心明细

dataId:表示完整的配置文件名称,(前缀-环境.后缀)=》 config-prod.properties

服务拉取配置

# 第一种方式
spring.cloud.nacos.config.name=config-prod
spring.cloud.nacos.config.file-extension=properties

# 第二种方式
spring.cloud.nacos.config.prefix=config
spring.profiles.active=prod
spring.cloud.nacos.config.file-extension=properties

统一配置中心的三个重要概念

  • 命名空间(namespace) :默认Nacos安装完成之后会有一个默认命名空间,这个命名空间名为public。这个是站在项目的角度来说,将不同的项目的配置文件进行分开。
  • 组(Group) :默认Nacos中在管理配置文件时不显示执行group名称,默认组名称为DEFAULT_GROUP。这个是站在服务角度,对多个微服务的配置文件进行分开。
  • 文件名(dataId) : 获取一个配置文件的唯一标识

最后在这里新建了多个命名空间、组、文件名,在前面的配置文件当中还需要添加namespace的配置,其余的配置更换为对应的group、文件名id即可。

spring.cloud.nacos.config.namespace=对应id

最后在Nacos当中还可以对修改了的配置进行回滚操作,如下所示:

Spring Cloud Alibaba
3.7、Nacos的mysql持久化

在前面对Nacos的了解,对于服务注册中心来说,数据不需要进行持久化,当有服务注册上来就直接进行显示,服务停掉就不显示,而这里的持久化是Nacos作为配置中心的数据进行持久化,前面对于配置管理可以看到,配置中心的数据还是存储在本地的,这里也就将数据持久化了到本地。在Nacos当中,默认的持久化的方式是内嵌的数据库debery。但是debery数据库也是有缺点的,在官网还是支持使用mysql数据库,

Spring Cloud Alibaba
首先在linux下安装Mysql服务,这里网上教程也很多,也不进行过多赘述了,直接按照网上的教程进行安装即可,在官网下载安装包属实有点太慢了,这里可以使用清华源进行下载对应的安装包:https://mirrors.tuna.tsinghua.edu.cn/mysql/downloads/MySQL-8.0/

在安装完成之后,修改远程连接并生效,使用以下命令:修改远程连接之后就可以使用sql工具进行连接就好了。

    update user set host='%' where user='root';
    flush privileges;

最后就是对当前这个数据库进行设置了,首先创建一个库用于Nacos的持久化,

CREATE DATABASE nacos DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci

而后对于数据库初始化需要一个nacos-mysql.sql文件,这个文件就在Nacos安装包的conf目录下
Spring Cloud Alibaba
直接拉出来到sql工具当中执行。也就是将Nacos需要用到的表进行创建,而后在这个conf文件下修改application.properties文件,将数据源改成mysql,以及其余的mysql配置根据自身安装时的配置更改即可。

Spring Cloud Alibaba
最后重启nacos。当在配置列表当中新加了一个配置之后,在mysql当中会存放在his_config_info表当中,这样也就完成了nacos的mysql本地持久化了。

4、Sentinel

4.1、Sentinel 概述

Sentinel 是什么?
分布式系统的流量防卫兵,类似之前Cloud的Hystrix。随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Sentinle是用来对现有微服务系统进行保护,也是用来替换Hystrix的。

Sentinel 基本概念

  • 资源

    • 资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
  • 规则

    • 围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。

4.2、Sentinel DashBoard

首先在使用Sentinel的时候,sentinel和sentinel DashBoard都需要,这里的Sentinel 是通过依赖得到的,而DashBoard是通过jar包进行启动,首先先到官网进行下载。下载得到jar包后,直接通过命令进行启动即可:默认端口是8080,当然了这里还是和前面安装nacos一样,也将这个jar包给放到虚拟机上进行管理。放在windows下也是可以的。

下载地址:https://github.com/alibaba/Sentinel/releases

java -jar sentinel-dashboard-1.8.2.jar
# 修改端口进行启动
java -jar -Dserver.port=9999 sentinel-dashboard-1.8.2.jar

启动之后直接访问8080端口,账号密码都是sentinel进行登录。

4.3、Sentinel 服务

在 启动后,创建一个微服务注册到nacos上,在这里引入sentinel依赖,

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

修改配置文件:

spring.cloud.sentinel.enabled=true
spring.cloud.sentinel.transport.dashboard=192.168.101.128:8080
spring.cloud.sentinel.transport.port=8719

对接口进行监控

Spring Cloud Alibaba
4.4、熔断规则——流量控制

Spring Cloud Alibaba

  • 资源名:唯一名称,默认请求路径
  • 针对来源:Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)
  • 阈值类型/单机阀值:
    • QPS(每秒钟的请求数量):当调用该api的QPS达到阈值的时候,进行限流。
    • 线程数:当调用该api的线程数达到闽值的时候,进行限流
  • 是否集群:不需要集群
  • 流控模式:
    • 直接:api达到限流条件时直接限流
    • 关联:当关联的资源达到阈值时,就限流自己。
    • 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【API级别的针对来源】
  • 效果
    • 快速失败:直接失败,抛异常
    • Warm up:根据codeFactor(冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值
    • 排队等待:匀速排队,让请求以匀速通过,与值类型必须设置为QPS,否则无效。

如上图:新加了一个熔断规则对接口进行监控,首先对QPS也就是每秒请求数量设置为2,当直接在浏览器一直刷新,访问该接口,可以在下图看到,当一个时间段的访问数超过了2之后,其余的请求都会直接失败进行处理掉。

Spring Cloud Alibaba
上面是QPS每秒请求数进行处理,而后改成线程数为2,这个时候就需要借助工具来进行测试了,在这里使用JMater来进行压力测试,设置线程组,每组一次发3个线程,每次限制2个线程进行访问,多余的线程也会直接失败处理。

JMeter压力测试:JMeter压力测试博文

Spring Cloud Alibaba

Spring Cloud Alibaba

4.5、熔断规则——熔断降级

原理:当监控到调用链路中某–个服务,出现异常(20个以上异常)自动触发培断,在触发之后对于谈服务调用不可用

Spring Cloud Alibaba

  • RT:平均响应时间,秒级
    • 平均响应时间 超出阈值 且 在时间窗口内通过的请求>=5,两个条件同时满足后触发降级,窗口期过后关闭断路器
    • RT最大为4900,更大的需要通过 -Dcsp.sentinel.statistic.max.rt=XXXX 才能生效
  • 异常比例,秒级
    • QPS >= 5 且异常比例(秒级统计)超过阈值时,触发降级;时间窗口结束后,关闭降级
  • 异常数,分钟级
    • 异常数(分钟统计)超过阈值时,触发降级;时间窗口结束后,关闭降级

4.6、熔断规则——热点参数限流

Spring Cloud Alibaba

热点也就是经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:

  • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
  • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制

热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。

在业务类中添加代码

  • 这里@SentinelResource注解的value属性要求唯一,一般与请求Mapping相同,将来在sentinel控制台添加热点key限流时可以用@SentinelResource注解的value作为资源名。
  • @SentinelResource注解的blockHandler属性用于指定兜底方法,需要在兜底方法的参数列表中添加一个BlockException类型的参数
    @GetMapping("/demo")
    @SentinelResource(value = "sentinelDemo", blockHandler = "blockHandler" , fallback = "fall")
    public String demo(Integer id){
        if (id<0) throw new RuntimeException("id 无效");
        return "demo ok";
    }

    public String blockHandler(Integer id, BlockException e){
        if(e instanceof FlowException){
            return "已被流控";
        }
        if(e instanceof DegradeException){
            return "已被降级";
        }
        return "===== 其余子类异常,这里就不一一列出来了 =====";
    }

    public String fall(){
        return "服务器异常";
    }

在这里的BlockException是整个所有sentinel抛出的异常的一个父类,在这里我们直接进入到该类就可以看到他的所有的子类,

Spring Cloud Alibaba

上一篇:springboot配置开发环境和生产环境application.yml


下一篇:ECS服务器新手上路