zoukankan      html  css  js  c++  java
  • Spring Cloud alibaba

    1.引言

    目前Spring Cloud进入了维护模式,而Spring Cloud alibaba对Spring Cloud做了封装,使用起来更简单。包含的功能有服务限流降级、服务注册于发现、分布式配置管理、消息驱动能力、阿里云对象存储、分布式任务调度等。

    参考文档:

    https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
    https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html

    源代码:https://github.com/zhongyushi-git/spring-cloud-alibaba-demo.git

    2.Nacos

    一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。是注册中心与配置中心的组合。官网:https://nacos.io/zh-cn/index.html

    2.1下载

    打开https://github.com/alibaba/nacos/releases下载需要的版本,这里以1.1.4版本为例说明。

    2.2安装

    2.2.1在windows系统安装

    下载压缩包后解压即可使用。进入bin目录,双击startup.cmd看到下图说明运行成功。

    默认是以集群方式启动,若启动报错,那么需要修改为单机版启动,在bin目录打开cmd,输入下面的命令进行启动。

    startup.cmd -m standalone

    访问http://localhost:8848/nacos,登录用户名和密码都是nacos。登录之后的页面如下,可以看到相关想信息。

    2.2.2在Linux系统安装

    把下载好的压缩上传制到Linux后解压

    tar -zxvf nacos-server-1.1.4.tar.gz -C /usr/local

    解压之后单机版启动,启动之后在浏览器访问nacos首页,同上。

    bash startup.sh -m standalone

    2.3基础环境搭建

    创建maven的父工程spring-cloud-alibaba-demo,删除src目录。导入依赖,进行版本锁定

        <!--统一管理jar包版本-->
        <properties>
            <spring.boot.version>2.2.2.RELEASE</spring.boot.version>
            <spring.cloud.alibaba.version>2.2.0.RELEASE</spring.cloud.alibaba.version>
            <spring.cloud.version>Hoxton.SR1</spring.cloud.version>
        </properties>
    
        <!--  依赖管理,父工程锁定版本-->
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <version>${spring.boot.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>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring.cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>

    2.4服务注册

    1)创建服务提供者子模块cloud-alibaba-provider8001,导入依赖

     <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>
            <!--springcloud alibaba nacos-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
        </dependencies>

    2)application.yml配置

    server:
      port: 8001
    
    spring:
      application:
        name: cloud-alibaba-nacos-provider
      cloud:
        #配置nacos地址
        nacos:
          #服务器地址
          server-addr: 127.0.0.1:8848
          #服务注册与发现地址
          discovery:
            server-addr: ${spring.cloud.nacos.server-addr}
    
    #开启端口暴露
    management:
      endpoints:
        web:
          exposure:
            include: "*"

    3)创建启动类

    package com.zys.cloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    public class NacosProviderMain8001 {
        public static void main(String[] args) {
            SpringApplication.run(NacosProviderMain8001.class,args);
        }
    }

    4)创建controller接口

    package com.zys.cloud.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class UserController {
    
        @Value("${server.port}")
        private String port;
    
        @GetMapping("/user/get")
        public String get() {
            return "provider port is :" + port;
        }
    }

    5)启动服务提供者,在nacos页面的服务列表中可以看到服务已注册进来。那么此时服务的注册就已完成,非常简单。

    6)同理,按照cloud-alibaba-provider8001方式创建服务提供者子模块cloud-alibaba-provider8002,端口为8002。启动后发现nacos中服务的集群数目变成了2。

    2.5服务调用

    nacos并不提供服务调用的方法,因此还需要使用SpringCloud的方式进行调用,这里使用OpenFeign进行说明(关于OpenFeign的用法其他文章已介绍)。

    1)创建服务消费者子模块cloud-alibaba-consumer80,导入依赖

    <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>
            <!--springcloud alibaba nacos-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
        </dependencies>

    2)application.yml配置

    server:
      port: 80
    
    spring:
      application:
        name: cloud-alibaba-nacos-consumer
      cloud:
        #配置nacos地址
        nacos:
          #服务器地址
          server-addr: 127.0.0.1:8848
          #服务注册与发现地址
          discovery:
            server-addr: ${spring.cloud.nacos.server-addr}
    
    
    feign:
      client:
        config:
          #指定全局
          default:
            #连接超时时间
            connectTimeout: 5000
            #服务等待时间
            readTimeout: 5000
            loggerLevel: full
    
    logging:
      level:
        com.zys.cloud.client.UserClient: debug

    虽然是调用别的服务,但也需要把自身服务注册到nacos.

    3)创建启动类

    package com.zys.cloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    public class ConsumerMain80 {
        public static void main(String[] args) {
            SpringApplication.run(ConsumerMain80.class, args);
        }
    }

    4)创建Client接口,用于接口映射

    package com.zys.cloud.client;
    
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    
    @FeignClient(value = "cloud-alibaba-nacos-provider")
    public interface UserClient {
    
        @GetMapping("/user/get")
        String get();
    }

    5)创建controller接口

    package com.zys.cloud.controller;
    
    import com.zys.cloud.client.UserClient;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/consumer")
    public class UserController {
    
        @Autowired
        private UserClient userClient;
    
        @GetMapping("/get")
        public String get() {
            return userClient.get();
        }
    }

    6)启动服务,可以在nacos页面的服务列表中看到两个注册的服务。

    访问http://localhost/consumer/get,看到是8001和8002进行轮询负载的。是因为nacos默认支持负载均衡,原因是它默认引入了ribbon。

    2.6服务配置

    2.6.1基本配置

    为了不改动上述的代码,这里新建一个模块说明服务的配置,原理是一样的。

    1)创建配置的客户端子模块cloud-alibaba-config-client,导入依赖

        <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>
            <!--springcloud alibaba nacos-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            </dependency>
        </dependencies>

    这里同时引入了服务注册和服务配置的依赖。作为客户端,当然需要注册到nacos,而配置又是此服务必不可少的。

    2)yml配置

    bootstrap.yml:系统级别的配置,主要配置配置中心的相关信息。

    spring:
      cloud:
        nacos:
          #服务器地址
          server-addr: 127.0.0.1:8848
          discovery:
            server-addr: ${spring.cloud.nacos.server-addr}
          config:
            #配置中心地址
            server-addr: ${spring.cloud.nacos.server-addr}
            #指定配置的格式,有yaml和properties两种
            file-extension: yaml

    application.yml:主要配置服务的名称及激活的配置文件

    spring:
      application:
        name: nacos-config-client
      profiles:
        active: dev

    3)创建启动类

    package com.zys.cloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    public class NacosConfigClientMain {
        public static void main(String[] args) {
            SpringApplication.run(NacosConfigClientMain.class,args);
        }
    }

    4)创建controller接口

    package com.zys.cloud.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    //动态刷新
    @RefreshScope
    public class UserController {
    
        @Value("${config.info}")
        private String info;
    
        @GetMapping("/config/get")
        public String get() {
            return "The config info is :" + info;
        }
    }

    需要注意的是,这里在类上加了@RefreshScope注解,用于自动刷新。若不添加,则无法进行自动的配置刷新。

    5)创建统一的配置文件

    在创建之前,先了解一些dataID的命名规则,它的完整格式为${prefix}-${spring.profile.active}.${file-extension}。

    prefix :默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
    spring.profile.active :即为当前环境对应的 profile。
    file-exetension: 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。

    假如spring.application.name=nacos-config-client,环境为dev,后缀名是yaml,那么dataID就是nacos-config-client-dev.yaml。这里不存在主/从配置文件的说法,只指定不同环境的配置,公共的配置都放在自己的环境中。另外,dataId后缀必须是yaml或properties。

    了解之后,就在nacos的配置管理页面新建一个配置文件,然后发布。

    配置代码:

    server:
        port: 3344
    
    config:
        info: '我的名字叫张三'
    

     6)测试

    启动3344,访问http://localhost:3344/config/get,可以看到配置的信息。然后修改配置中的config.info内容,再刷新页面,发现配置信息也更新了。此时就做到了配置实时刷新。

    2.6.2分类配置

    级别大小:namespace > Group > dataId。

    1)dataId方案

    一个dateId就是一个配置文件。在nacos页面再创建一个配置文件,作为测试环境配置

    修改application.yml的环境为test。

    重启后访问http://localhost:3355/config/get,可以看到test环境的配置信息。

    2)Group方案

    在上述的章节中,并没有去指定Group,而是采用的默认的名称DEFAULT_GROUP,如果需要自定义分组名称,则在创建配置时指定分组名即可,不过需要在bootstrap.yml在指定组名。

    新建一个配置文件,分组名为GROUP_TEST

    修改application.yml的环境为info,然后在bootstrap.yml指定组名

    重启后访问http://localhost:3344/config/get,可以看到info环境的配置信息。

    3)namespace方案

    用于区分不同的部署环境,实现隔离。命名空间是最大的,需要设置的话就创建命名空间(id一般不指定,自动生成即可),在配置文件中指定创建的命名空间的id即可。

    2.7持久化配置

    nacos默认自带的是嵌入式数据库derby,持久化就需要切换到MySQL,MySQL版本5.7以上。

    1)执行sql脚本

    在下载的nacos文件夹中,nacos-server-1.1.4\nacos\conf\nacos-mysql.sql即是sql脚本,先创建一个名为nacos的数据库,然后执行这个脚本即可。

    2)修改配置文件

    打开nacos-server-1.1.4\nacos\conf\application.properties,在最后添加

    #增加支持mysql数据源配置
    spring.datasource.platform=mysql
    
    db.num=1
    db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
    db.user=root
    db.password=123456

    3)启动测试

    重启nacos,发现之前配置的信息没有了,原因是MySQL中并没有进行配置。这时在nacos页面创建一个名为nacos-config-client-info.yaml的配置文件如下:

    启动服务配置客户端,访问http://localhost:3344/config/get,可以看到info环境的配置信息。其配置信息在表config_info中可看到。

    2.8集群配置

    在搭建集群之前,默认在Linux已安装完成nocas。另外,nginx单机版也在Linux搭建完成,用于负载均衡nacos服务,MySQL在Linux已安装完成(MySQL版本5.7+)。

    1)执行sql脚本(同上一小节)

    2)配置nacos数据源,修改application.properties文件,在最后添加

    #增加支持mysql数据源配置
    spring.datasource.platform=mysql
    
    db.num=1
    db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
    db.user=root
    db.password=123456

    3)获取本机的ip

    hostname -i

    4)配置cluster.conf

    打开文件

    cp cluster.conf.example cluster.conf
    vim cluster.conf

    把内容修改如下:

    172.16.68.248:8849
    172.16.68.248:8850
    172.16.68.248:8851

    需要注意的是,这里的ip必须是上一步获取的本机ip。

    5)修改startup.sh启动文件

    vim startup.sh

    修改的文件前后对比,主要添加了启动的端口号

       

     6)启动集群

    ./startup.sh -p 8849
    ./startup.sh -p 8850
    ./startup.sh -p 8851

    在启动的时候,遇到了一个大坑,就是安装的jdk必须手动配置java_home,否则会报错。

    3.Sentinel

    学习地址:https://github.com/alibaba/Sentinel/wiki/介绍

    Sentinel主要从流量控制、熔断降级、系统负载保护维度保护服务的稳定性。

    3.1下载与安装

    1)下载地址https://github.com/alibaba/Sentinel/releases,选择对应的版本下载即可。这里以1.8.2版本为例

    可以下载压缩包,也可以直接下载jar。本章节在Windows中说明,就直接下载jar进行说明。

    2)下载到本地后,在其目录下打开cmd,输入命令

    java -jar sentinel-dashboard-1.7.2.jar

    3)在浏览器访问http://localhost:8080,看到下面的页面说明安装成功。

    用户名和密码都是sentinel。

    4)登录后看到仪表盘是空的,因为现在没有监控任何的服务。

    3.2初始化监控

    为了不改动上述的代码,这里新建一个模块进行说明,原理是一样的。

    1)创建一个模块cloud-alibaba-sentinel,导入依赖

          <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>
            <!--springcloud alibaba nacos-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
            <!--springcloud alibaba sentinel-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            </dependency>

    2)配置application.yml,简单起见,配置文件在本地进行配置

    server:
      port: 8401
    spring:
      application:
        name: cloud-alibaba-sentinel-service
      cloud:
        nacos:
          server-addr: 127.0.0.1:8848
          discovery:
            server-addr: ${spring.cloud.nacos.server-addr}
        sentinel:
          transport:
            # sentinel dashboard的地址
            dashboard: 127.0.0.1:8080
            # sentinel dashboard内部通信端口,默认为8719,如果被占用会自动+1,直到找到为止
            port: 8719
    
    management:
      endpoints:
        web:
          exposure:
            include: "*"

    3)创建启动类

    package com.zys.cloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    public class SentinelMain {
        public static void main(String[] args) {
            SpringApplication.run(SentinelMain.class, args);
        }
    }

    4)创建controller

    package com.zys.cloud.controller;
    import com.alibaba.csp.sentinel.annotation.SentinelResource;
    import com.alibaba.csp.sentinel.slots.block.BlockException;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class FlowLimitController {
    
        @GetMapping("/testA")
        public String testA(){
            return "--------testA";
        }
    
        @GetMapping("/testB")
        public String testB(){
            return "--------testB";
        }
    
    
    }

    5)测试。先启动nacos服务,再启动sentinel服务,再启动8401。访问http://localhost:8401/testA后会在仪表盘看到生成了一个服务:

    将接口testA多调用几次,再看仪表盘

    其中QBS表示1秒的请求数,QPS表示1秒的拒绝请求数。

    原理:只要服务加入了Sentienl并进行了配置,那么在调用服务时,就会通过内部通信服务把日志信息发送给dashboard服务,其在页面上展示。因此只有的服务调用时dashboard才会进行初始化。

    6)簇点链路

    打开簇点链路的菜单,可以看到链路的信息,可操作的按钮包含流控、熔断、热点和授权,后续一一介绍。

    3.2流控

    流控:流量控制(flow control),其原理是监控应用流量的QPS或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

    3.2.1阈值类型-QPS

    QPS表示每秒的请求数。可在簇点链路中选择链路的点击流控按钮添加,也可在流控规则中添加。其他的功能类似。这里以/testA的流控为例:

    上图的配置,也就是说对于请求/testA,当每秒请求的次数超过阈值,那么会直接返回失败的信息。保存后显示列表如下:

    访问localhost:8401/testA结果是正常的,若快速的刷新几次,会发现返回了流控的信息:

    对于针对来源,默认使用default,那么也可以指定来源,那么当指定的这个来源调用/testA请求时会进行流控,其他服务调用/testA时不进行流控,也就是对来源进行针对性的流控。

    3.3.2阈值类型-并发线程数

    当然也可设置并发线程的阈值,当某一时刻并发线程数量超过时会进行流控。

    1)点击编辑,将/testA的阈值类型修改并发线程数

    2)使用Jmeter对/testA发送超过阈值的并发请求,那么在发送的同时再访问/testA就会出现流控。

    3.3.3 流控模式-关联

    1)说明:前面的两种的流程模式都设置为直接,这种模式是默认的,也就是说流量控制规则到达阈值时直接触发流量控制。本小节说明关联模式,均以QPS类型说明,后同。

    2)关联:当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写得速度,写的速度过高会影响读的速度。如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的吞吐量。关联的关系是反向关联。

    3)上述代码中的/testA和/testB就是关联关系,它们在同一个controller中,占用相同的资源,编辑配置如下:

    使用Jmeter对/testB发送超过阈值的并发请求,那么在发送的同时再访问/testA就会出现流控。原因是两个请求相互争抢资源,进行了流控。

    3.3.3 流控模式-链路

    链路模式也就是对某一条链路进行流控。如用户服务会调用订单服务,商品服务也会调用订单服务,就存在两条链路。在某个时刻,对商品服务->订单服务这条链路进行流控,从而保证订单服务的正常使用,最终让用户服务可以正常调用订单服务,虽然限流了商品服务这条链路,但不影响用户服务这条链路。

    3.3.4流控效果-快速失败

    默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException 。前面已经使用过多次。

    3.3.5流控效果-Warm Up

    预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。它有一个冷加载因子,值是3。曲线图如下:

    新加/testA的流控规则如下:

    当1秒同时有20个请求,预热时间是10秒。那么服务会先处理7个请求(20/3),后面依次处理,当达到20秒时处理完所有的请求。

    3.3.6流控效果-排队等待

    让请求以均匀的速度通过。修改/testA的规则:

    也就是说,当有大量的请求来时,每秒只处理20个请求,其他的请求进行排队等待,依次类推。当后面排队的时间超过5秒时就报错,显示流控信息。

    3.3熔断降级

    一个服务常常会调用别的模块,如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。而Sentinel在服务出现不稳定情况时,会对其进行限制,请求快速失败,避免影响到其他资源而导致级联错误。当资源被降级后,在接下来的时间窗口内,对该资源的调用都自动熔断。

    3.3.1降级策略

    (1)慢调用比例:当单位统计时长内请求数目大于设置的最小请求数目,并且平均响应时间超过最大RT的请求的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。

    经过熔断时长后熔断器会进入探测恢复状态,若接下来的一个请求成功完成则结束熔断,否则会再次被熔断。

    说明:在1000ms内请求数超过5个,且平均响应时间超过300ms的请求的比例(超过300ms的请求占总请求的比例)大于0.4,则该资源自动熔断10s。10s后根据下一个请求判断是否再次被熔断。

    (2)异常比例:当单位统计时长内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。

    经过熔断时长后熔断器会进入探测恢复状态,若接下来的一个请求成功完成则结束熔断,否则会再次被熔断。

    说明:在1000ms内请求数超过5个,且异常的比例(异常的请求占总请求的比例)大于0.8,则该资源自动熔断15s。15s后根据下一个请求判断是否再次被熔断。

    (3)异常数:当单位统计时长内的异常数目超过阈值之后会自动进行熔断。

    经过熔断时长后熔断器会进入探测恢复状态,若接下来的一个请求成功完成则结束熔断,否则会再次被熔断。

    说明:在1000ms内请求数超过5个,且异常的请求超过6个,那么该资源将自动熔断20s。20s后根据下一个请求判断是否再次被熔断。

    3.3.2注解@SentinelResource的使用

    前面的所讲的流控或降级,其返回的数据都是 Blocked by Sentinel (flow limiting) ,当然可以自定义。@SentinelResource和@HystrixCommand的作用是类似的,都是来指定流控或降级时返回的信息。

    在方法上加@SentinelResource注解,且使用blockHandler(或者blockHandlerClass)指定流控或降级时的自定义提示,而blockHandler函数访问范围需要是public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数(类型是BlockException),且和原方法在同一个类中。使用fallback 指定未流控或降级发生异常时的自定义提示,其方法必须是public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配。

    下面通过对/testC进行流控和降级来说明:

    1)流控配置:

    2)降级配置:

    3)后台代码:

        @GetMapping("/testC")
        @SentinelResource(value = "aaa", blockHandler = "testCBlockHandler",fallback = "testCFallback")
        public String testC(Integer id) {
            if (id < 0) {
                throw new RuntimeException("参数值格式错误");
            }
            return "--------testC";
        }
    
        //自定义降级或熔断时的提示信息
        public String testCBlockHandler(Integer id, BlockException exception) {
            //判断异常的类型
            if (exception instanceof FlowException) {
                return "你被限流了,请稍后再试";
            } else if (exception instanceof DegradeException) {
                return "你被降级了,请稍后再试";
            }
            return "当前服务不可用";
        }
    
        //自定义未限流时发生异常的提示信息
        public String testCFallback(Integer id){
            return "参数不合法";
        }

    在@SentinelResource指定了value,其值就是要流控或降级的资源名,必须配置。

    当访问/testC?id=8时,快速刷新,会出现流控提示信息。

    当问/testC?id=-5时,刷新1此,会出现错误提示信息。

    当问/testC?id=-5时,刷新5次以上,会出现降级提示信息。

    3.4规则持久化

    你有没有发现,每次无论重启sentinel服务还是要监控的服务,sentinel页面的配置规则都会消失,这是因为这些规则没有持久化,对应大量的配置规则,持久化也非常重要,可将其配置到nacos中。

    这里直接在cloud-alibaba-sentinel模块进行说明:

    1)导入依赖

            <!--springcloud alibaba sentinel-datasource-nacos-->
            <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-datasource-nacos</artifactId>
            </dependency>

    2)在yml配置,已存在配置省略:

    spring:
      cloud:
          # 流控规则持久化到nacos
          datasource:
            dsl:
              nacos:
                server-addr: ${spring.cloud.nacos.server-addr}
                data-id: ${spring.application.name}
                group-id: DEFAULT_GROUP
                data-type: json
                rule-type: flow

    3)在nacos中添加配置文件,如下图:

     json内容:

    [
        {
            "resource": "/testA",
            "limitApp": "default",
            "grade": 1,
            "count": 5,
            "strategy": 0,
            "controlBehavior": 0,
            "clusterMode": false
        }
    ]

    可看到json中是一个数组,数组中只有一个元素,那么针对/test的请求的配置规则会存下来,不会因为重启而丢失,而其他的请求的配置规则还是丢失。针对这些请求,都按照这种规则配置在数组中即可。

    4.Seata

    官网:https://seata.io/zh-cn/index.html

    一次业务操作需要跨多个数据源或需要跨多个系统进行远程调用,就会产生分布式事务问题。Seata是一种分布式事务的解决方案,在服务搭建正确的情况下,在业务上添加@GlobalTransactional

    4.1术语(一ID+三组件模式)

    1)XID:(Transaction ID)全局唯一的事务ID

    1)TC:(Transaction Coordinator)事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚

    2)TM:(Transaction Manager)控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议

    3)RM:(Resource Manager)控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚

    4.2处理过程

    1)TM向TC申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID

    2)XID在微服务调用链路的上下文中传播

    3)RM向TC注册分支事务,将其纳入XID对应全局事务的管辖

    4)TM向TC发起针XID的全局提交或回滚决议

    5)TC调度XID下管辖的全部分支事务完成提交或回滚请求。 

    4.3下载安装

    1)下载地址:https://github.com/seata/seata/releases,下载对应版本即可。

    5.微服务架构整合

    相比之下,使用SpringCloud+SpringCloud alibaba效果会更好。整合的组件说明如下表:

    微服务组件 框架 具体组件
    服务注册 SpringCloud alibaba nacos
    服务调用 SpringCloud openfeign
    服务配置 SpringCloud alibaba nacos
    服务网关 SpringCloud gateway
    服务熔断和降级 SpringCloud alibaba sentinel
    服务负载均衡 SpringCloud Ribbon。默认已有

    涉及到整合,那么两者的版本需要进行匹配并进行统一管理。

    就是这么简单,你学废了吗?感觉有用的话,给笔者点个赞吧 !
  • 相关阅读:
    TCP全局同步
    pytest框架之fixture详细使用
    库操作和表操作
    封装之如何隐藏对象及封装的意义
    类的抽象
    组合
    在子类中重用父类的方法和属性
    类的继承和实现原理
    类的使用,对象的使用
    互联网协议的五层协议详解
  • 原文地址:https://www.cnblogs.com/zys2019/p/12682628.html
Copyright © 2011-2022 走看看