Spring Cloud个人总结(二)之Alibaba

Spring Cloud —Alibaba

学习目标

Nacos

Sentinel

一. 入门简介

1. 能做什么

  • 服务限流降级:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
  • 服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
  • 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
  • 消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
  • 分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。
  • 阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
  • 分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行。
  • 阿里云短信服务:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

2. 组件

Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。

Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架。

Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。

Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。

Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。

Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

Spring Cloud个人总结(二)之Alibaba_第1张图片

二. Nacos 服务注册和配置中心(重点)

1. Nacos简介

为什么叫Nacos?

前四个字母分别为Naming和Configuration的前两个字母,最后的s为Service

是什么?

一个更易于构建云原生应用的动态服务发现,配置管理和服务管理中心

Nacos:Dynamic Naming and Configuration Service

Nacos就是注册中心+配置中心的组合

等价于:Nacos = Eureka+Config+Bus

2. Nacos安装及运行

1.  先从官网下载Nacos(注意有系统)  https://github.com/alibaba/nacos/releases/tag/1.1.4
2.  解压安装包,直接运行bin/startup.cmd 
3.  命令运行成功后直接访问  http://localhost:8848/nacos      默认账号密码都是nacos                                                                  

3.Nacos的服务注册中心演示

服务提供者

① 新建Module

cloudalibaba-provider-payment9001

② POM

父POM

<!--spring cloud alibaba 2.1.0.RELEASE-->
<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>

本模块POM

<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        </dependency>
</dependencies>

③ YML

server:
  port: 9001

spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #配置Nacos地址

management:
  endpoints:
    web:
      exposure:
        include: '*'  #默认只公开了/health和/info端点,要想暴露所有端点只需设置成星号

④ 主启动

package com.atguigu.alibaba;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

⑤业务类

package com.atguigu.alibaba.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PaymentController{
    @Value("${server.port}")
    private String serverPort;
 
    @GetMapping(value = "/payment/nacos/{id}")
    public String getPayment(@PathVariable("id") Long id) {
        return "nacos registry, serverPort: "+ serverPort+"\t id"+id;
    }
}

⑥ 测试

http://localhost:9001/payment/nacos/1

服务消费者

① 新建Module

cloudalibaba-consumer-nacos-order83

② POM

<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        </dependency>
</dependencies>

③ YML

server:
  port: 83

spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者【可选】,注意:nacos-payment-provider含有IP和端口)
service-url:
  nacos-user-service: http://nacos-payment-provider

④ 主启动

package com.atguigu.alibaba;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

⑤ 业务类

package com.atguigu.alibaba.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ApplicationContextConfig{
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

⑥OrderNacosController

package com.atguigu.alibaba.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
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;

@RestController
@Slf4j
public class OrderNacosController{
    @Resource
    private RestTemplate restTemplate;

    @Value("${service-url.nacos-user-service}")
    private String serverURL;

    @GetMapping(value = "/consumer/payment/nacos/{id}")
    public String paymentInfo(@PathVariable("id") Long id){
        return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class);
    }
}

⑦测试

http://localhost:83/consumer/payment/nacos/1

4.服务注册中心对比

Spring Cloud个人总结(二)之Alibaba_第2张图片

Nacos支持AP和CP模式的切换

5. Nacos作为服务配置中心演示

5.1 Nacos作为配置中心-基础配置

①创建Module:cloudalibaba-config-nacos-client3377

② POM

<dependencies>
    <!--nacos-config-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    <!--nacos-discovery-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--web + actuator-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency> 
</dependencies>

③YML

springboot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于application

bootstrap.yml

server:
  port: 3377

spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #服务注册中心地址
      config:
        server-addr: localhost:8848 #配置中心地址
        file-extension: yaml #指定yaml格式的配置(yml和yaml都可以)

#${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
#nacos-config-client-dev.yaml  (一定要与file-extension值保持一致)

application.yml

spring:
  profiles:
    active: dev #表示开发环境

④ 主启动

package com.atguigu.alibaba;

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

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

⑤业务类:ConfigClientController

package com.atguigu.alibaba.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   //通过SpringCould原生注解@RefreshScope实现配置自动更新
public class ConfigClientController{
    @Value("${config.info}") //对应nacos配置:nacos-config-client-dev.yaml
    private String configInfo;

    @GetMapping("/config/info")
    public String getConfigInfo() {
        return configInfo;
    }
}

⑥ 在Nacos中添加配置信息

设置DataId

公式: ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}

⑦访问地址

http://127.0.0.1:3377/config/info

改变application.yml

spring:
  profiles:
    active: pro #表示开发环境

配置文件结果不一样Spring Cloud个人总结(二)之Alibaba_第3张图片

Spring Cloud个人总结(二)之Alibaba_第4张图片

5.2 Nacos作为配置中心-分类配置

多环境多项目管理

问题1

· 实际开发中,通常一个系统会准备

· dev开发环境

· test测试环境

· prod生产环境

· 如何保证指定环境启动时服务能正确读取到 Nacos上相应环境的配置文件呢?

问题2

· 一个大型分布式微服务心痛会有很多微服务子项目

· 每一个微服务项目又会相应的开发环境、测试环境、预发环境、正式环境….

那怎么对这些微服务配置进行管理呢

6. Nacos集群和持久化配置(超级重要)

6.1 集群部署架构图及说明

推荐用户把所有服务列表放到一个vip下面,然后挂到一个域名下面

http://ip1:port/openAPI 直连ip模式,机器挂则需要修改ip才可以使用。

http://VIP:port/openAPI 挂载VIP模式,直连vip即可,下面挂server真实ip,可读性不好。

http://nacos.com:port/openAPI 域名 + VIP模式,可读性好,而且换ip方便,推荐模式

架构图

Spring Cloud个人总结(二)之Alibaba_第5张图片

上图官网翻译

Spring Cloud个人总结(二)之Alibaba_第6张图片

说明

默认Nacos使用嵌入式数据库实现数据的存储。所以,如果启动多个默认配置下的Nacos节点,数据存储是存在一致性问题多的。

为了解决这个问题,Nacos采用了集中式存储的方式来支持集群化部署,目前只支持MySQL的存储

Spring Cloud个人总结(二)之Alibaba_第7张图片

Spring Cloud个人总结(二)之Alibaba_第8张图片

6.2 Nacos持久化配置解释
Nacos默认自带的是嵌入式数据库derby
https://github.com/alibaba/nacos/blob/develop/config/pom.xml

derby到mysql切换配置步骤

nacos-server-1.1.4\nacos\conf目录下找到sql脚本

nacos-mysql.sql

执行脚本

nacos-server-1.1.4\nacos\conf目录下找到application.properties

spring.datasource.platform=mysql

db.num=1
db.url.0=jdbc:mysql://192.168.01:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=133009

启动nacos,可以看到是个全新的空记录界面,以前是记录进derby

​ 先杀死进程再执行bin/startup.sh -m standalone

测试:新建配置,发现配置信息写入了MySQL数据库

6.3 Linux版Nacos+MySQL生产环境配置
①预计需要,1个nginx+3个nacos注册中心+1个mysql

②Nacos下载linux版本

<https://github.com/alibaba/nacos/releases/tag/1.1.4>

nacos-server-1.1.4.tar.gz

Spring Cloud个人总结(二)之Alibaba_第9张图片

③集群配置步骤(重点)
Ⅰ Linux服务器上mysql数据库配置

Spring Cloud个人总结(二)之Alibaba_第10张图片Spring Cloud个人总结(二)之Alibaba_第11张图片

Ⅱ application.properties配置
spring.datasource.platform=mysql

db.num=1
db.url.0=jdbc:mysql://192.168.137.128:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=zhang3
db.password=123456

④ 测试
高可用小总结

Spring Cloud个人总结(二)之Alibaba_第12张图片

三. Sentinel (哨兵)实现熔断与限流

Spring Cloud个人总结(二)之Alibaba_第13张图片

1.介绍

是什么

一句话解释,之前学过的Hystrix

Spring Cloud个人总结(二)之Alibaba_第14张图片

能干嘛

Spring Cloud个人总结(二)之Alibaba_第15张图片

2.安装Sentinel控制台

sentinel组件由2部分组成

Sentinel 分为两个部分:

核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。

控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

l 后台

l 前台8080

安装步骤

① 下载

https://github.com/alibaba/Sentinel/releases
下载到本地sentinel-dashboard-1.7.1.jar

②运行命令

前提
java8环境OK
8080端口不能被占用

命令:java -jar sentinel-dashboard-1.7.1.jar

③访问sentinel管理界面

<http://localhost:8080>

登录账号密码均为sentinel

3. 初始化演示工程

① 创建Module

cloudalibaba-sentinel-service8401

②POM

<?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">
    <parent>
        <artifactId>cloud2020</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cloudalibaba-sentinel-service8401</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <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>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.6.3</version>
        </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>

③ YML

server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719  #默认8719,应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用HttpServer

management:
  endpoints:
    web:
      exposure:
        include: '*'

Spring Cloud个人总结(二)之Alibaba_第16张图片

④ 主启动

package com.atguigu.springcloud.alibaba;

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

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

⑤ 业务类FlowLimitController

package com.atguigu.springcloud.alibaba.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class FlowLimitController{
    @GetMapping("/testA")
    public String testA() {
        return "------testA";
    }

    @GetMapping("/testB")
    public String testB() {
        return "------testB";
    }
}

⑥启动

启动Sentinel8080
java -jar sentinel-dashboard-1.7.0
启动微服务8401
.	启动8401微服务后查看sentienl控制台
空空如也,啥都没有
Sentinel采用的懒加载说明
执行一次访问即可
http://localhost:8401/testA
http://localhost:8401/testB

结论
sentinel8080正在监控微服务8401

4. 流控规则(工作100%要用的)

1.介绍

Spring Cloud个人总结(二)之Alibaba_第17张图片

2. 流控模式

2.1 直接(默认)

资源名,唯一名称,默认请求路径 @GetMappinf ("/testA") 对应的是 上面截图资源名

QPS(Query Per Second):每秒请求数,就是说服务器在一秒的时间内处理了多少个请求。

·        直接->快速失败
                      系统默认
配置及说明:    表示1秒钟内查询1次就是OK,若超过次数1,就直接-快速失败,报默认错误

①测试 QPS

Spring Cloud个人总结(二)之Alibaba_第18张图片

快速点击访问: http://localhost:8401/testA
结果如下
•	Blocked by Sentinel (flow limiting)

②测试线程数

Spring Cloud个人总结(二)之Alibaba_第19张图片

Spring Cloud个人总结(二)之Alibaba_第20张图片

快速点击访问: http://localhost:8401/testA
结果 : 不会出现Blocked by Sentinel (flow limiting)(线程处理请求很快)
如果再开一个线程  http://localhost:8401/testA
结果就会出现   Blocked by Sentinel (flow limiting)

Spring Cloud个人总结(二)之Alibaba_第21张图片

资源名,唯一名称,默认请求路径 @GetMappinf ("/testA") 对应的是 上面截图资源名

但是,在映射方法里添加sleep后,同样也会出现Blocked by Sentinel (flow limiting)默认提示信息。
 
思考???
•	直接调用默认报错信息,技术方面OK but,是否应该有我们自己的后续处理?
•	类似有一个fallback的兜底方法?
2.2关联
  是什么?
当关联的资源达到阈值时,就限流自己
当与A关联的资源B达到阈值后,就限流自己
B惹事,A挂了
实例: 比如支付接口达到阈值时,就限流下下订单的接口,防止连坐效应.
配置A

· 设置效果:

当关联资源/testB的QPS阀值超过1时,就限流/testA的REST访问地址,当关联资源到阀值后闲置配置的的资源名

Spring Cloud个人总结(二)之Alibaba_第22张图片

1.    postman模拟并发密集访问testB
2.   Run
     大批量线程高并发访问B,导致A失效了
	运行后发现testA挂了
	点击访问http://localhost:8401/testA
	结果Blocked by Sentinel (flow limiting)

3. 流控效果

3.1 直接->快速失败

(默认的流控处理)

l  直接失败,抛出异常:Blocked by Sentinel (flow limiting)

l  源码:com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController
3.2 预热 (Warmup)

· Warmup配置

默认 coldFactor 为 3,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。

案例:阈值为10 + 预热时长设置5秒。

系统初始化的阈值为10/3约等于3,即阈值刚开始为3;然后过了5秒后阈值才慢慢升高,恢复到10

Spring Cloud个人总结(二)之Alibaba_第23张图片

多次点击http://localhost:8401/testB
结果 :  刚开始不行,后续慢慢OK
应用场景:

如秒杀系统在开启的瞬间,会有很多流量上来 , 很有可能把系统打死. 预热方式. 就是为了保护系统. 可慢慢的把流量放进来, 慢慢的把阈值增长到设置的阈值.

3.3 排队等待
实现

Spring Cloud个人总结(二)之Alibaba_第24张图片

原理

Spring Cloud个人总结(二)之Alibaba_第25张图片

5.降级规则 (熔断降级)

1. 基本介绍

Spring Cloud个人总结(二)之Alibaba_第26张图片

·
①RT(平均响应时间,秒级)

​ 平均响应时间 (DEGRADE_GRADE_RT):超过阈值 时间窗口内的请求>=5,两个条件同时满足后触发降级,窗口期过后关闭断路器

RT 最大4900 ms,更大的需要通过启动配置项

-Dcsp.sentinel.statistic.max.rt=xxx 来配置。

② 异常比例(秒级)

​ QPS>=5且异常比例(秒级统计)超过阈值时,触发降级;时间窗口结束后,关闭降级

异常数(分钟级)

​ 异常数(分钟统计)超过阈值时,触发降级;时间窗口结束后,关闭降级

进一步说明

· Sentinel熔断降级会在调用链路中某个资源出现不稳定状态时(例如:调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其他的资源而导致级联错误。

· 当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出DegradeException)。

Sentinel的断路器是没有半开状态

半开的状态系统自动去检测是否请求有异常,没有异常就关闭断路器恢复使用,有异常则继续打开断路器不可用。

2. 降级策略实战

2.1 RT

降级要求:每秒钟请求数大于5个,且每个请求要在0.2秒内处理完。

Spring Cloud个人总结(二)之Alibaba_第27张图片

jmeter测试

Spring Cloud个人总结(二)之Alibaba_第28张图片

结论

​ 永远一秒钟打进来10个线程(大于5个了)调用testD,我们希望200毫秒处理完本次任务,

​ 如果超过200毫秒还没处理完,在未来1秒钟的时间窗口内,断路器打开(保险丝跳闸)微服务不可用,保险丝跳闸断电了, 后续停止jmeter,没有这么大的访问量了,断路器关闭(保险丝恢复),微服务恢复OK

2.2 异常比例

表示在一定时间内,请求的异常次数不能占总请求次数的比例,且每个时间窗口内的请求数要大于5次,最后在设定的时间窗口结束后,关闭降级

Spring Cloud个人总结(二)之Alibaba_第29张图片

2种情况 :
① 单独访问一次,必然来一次报错一次(int age=10/0;),调一次错一次, 因为不满足请求数大于5.

②· 开启jmeter后,直接高并发送请求,多次调用达到我们的配置条件了。

断路器开启(保险丝跳闸),微服务不可用了,不再报错error 而是服务降级了

Spring Cloud个人总结(二)之Alibaba_第30张图片

2.3 异常数

异常数和上面有所不同,其统计的时间窗口是分钟级别的,如果时间窗口内请求数异常请求数大于我们设置的5,那么就会产生降级,然后直到有个时间窗口统计到的异常数小于5才会放行

注意

时间窗口一定要大于等于60秒

异常数是按分钟统计的.

测试

@GetMapping("/testE")
public String testE(){
    log.info("testE 测试异常数");
    int age = 10/0;
    return "------testE 测试异常数";
}

Spring Cloud个人总结(二)之Alibaba_第31张图片

6.热点规则--------- 热点key限流(最实用和常用)

热点参数限流

1. Overview

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

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

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

Spring Cloud个人总结(二)之Alibaba_第32张图片

Sentinel 利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。热点参数限流支持集群模式。

2. 承上启下复习
	兜底方法
	之前的case,限流出问题后,都是用sentinel系统默认的提示: Blocked by Sentinel(flow limiting)
	我们能不能自定义?类似hystrix,某个方法出现问题了,就找对应的兜底降级方法?
	结论
	从HystrixCommand到@SentinelResource----下面会有一章节详细讲解
3. 代码
@GetMapping("/testHotKey")      = Rest 地址
@SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")
public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                         @RequestParam(value = "p2",required = false) String p2) {
    //int age = 10/0;
    return "------testHotKey";
}

//兜底方法
public String deal_testHotKey (String p1, String p2, BlockException exception){
  return "------deal_testHotKey,o(╥﹏╥)o";    sentinel 系统默认提示: Blocked by Sentinel (flow limiting)
}

4. 配置

Spring Cloud个人总结(二)之Alibaba_第33张图片

第一种

o 自定义

· @SentinelResource(value = testHotKey", blockHandler = “deal_testHotKey”) //value值与资源名一致即可

· 方法testHostKey里面第一个参数只要QPS超过每秒1次,马上降级处理 ,

注解里的配置了 blockHandler = "deal_testHotKey), 返回兜底操作

Spring Cloud个人总结(二)之Alibaba_第34张图片

第二种

o 默认

· @SentinelResource(value = “testHotKey”)

· 异常打到了前台用户界面,不友好

注解里的只有一个 value “testHotKey” , 返回错误界面

Spring Cloud个人总结(二)之Alibaba_第35张图片

7. 参数例外项

特殊情况

· o 普通 : 超过1秒钟一个后,达到阈值1后马上被限流, 我们期望p1参数当它是某个特殊值时,它的限流值和平时不一样

·

​ o 特例:假如当p1的值等于5时,它的阈值可以达到200

​ o 配置

· 添加按钮不能忘

Spring Cloud个人总结(二)之Alibaba_第36张图片

o 测试

http://localhost:8401/testHotKey?p1=5 对

http://localhost:8401/testHotKey?p1=3 错

· 当p1等于5的时候,阈值变为200

· 当p1不等于5的时候,阈值就是平常的1

o 前提条件

· 热点参数的注意点,参数必须是基本类型或者String

8. 系统规则(慎用)

1. 是什么

​ Sentinel 系统自适应限流从**整体维度对应用入口流量进行控制**,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

2. 各项配置参数说明

Spring Cloud个人总结(二)之Alibaba_第37张图片

3. 配置全局QPS

Spring Cloud个人总结(二)之Alibaba_第38张图片

危险!!!尽量不要乱配这个,相当于去总入口去限制

9. @SentinelResource(非常重要)

从HystrixCommand到@SentinelResource

​ @SentinelResource注解的blockHandler字段,指定发生Sentinel异常时的处理方法(即触发Sentinel五种类型规则时的处理逻辑)。fallback字段指定发生业务异常时的处理方法。当然,为了省事,可以不指定blockHandler,所有处理逻辑都放在fallback中。

Spring Cloud个人总结(二)之Alibaba_第39张图片

10. 规则持久化

1. 是什么

一旦我们重启应用,Sentinel规则将消失,生产环境需要将配置规则进行持久化

2.怎么玩

​ 将限流配置规则持久化进Nacos保存,只要刷新8401某个rest地址,sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对8401上Sentinel上的流控规则持续有效

3. 步骤

1. 修改:cloudalibaba-sentinel-service8401

2. POM


    com.alibaba.csp
    sentinel-datasource-nacos


3.YML

server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos服务注册中心地址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard地址
        port: 8719
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

management:
  endpoints:
    web:
      exposure:
        include: '*'

feign:
  sentinel:
    enabled: true # 激活Sentinel对Feign的支持

4.添加Nacos业务规则配置

Spring Cloud个人总结(二)之Alibaba_第40张图片

·
内容解析

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

Spring Cloud个人总结(二)之Alibaba_第41张图片

5. 启动8401后刷新sentinel发现业务规则有了

Spring Cloud个人总结(二)之Alibaba_第42张图片

6. 快速访问测试接口

http://localhost:8401/rateLimit/byUrl

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

7. 停止8401再看sentinel

Spring Cloud个人总结(二)之Alibaba_第43张图片

8. 重新启动8401再看sentinel

扎一看还是没有,稍等一会儿

多次调用

http://localhost:8401/rateLimit/byUrl

重新配置出现了,持久化验证通过

你可能感兴趣的:(Spring,Cloud,spring,cloud,alibaba)