当前位置: 首页 > news >正文

06_sentinel—分布式系统遇到的问题

sentinel—分布式系统遇到的问题

在这里插入图片描述

sentinel—服务雪崩

服务雪崩效应:因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程,就叫服务雪崩效应

sentinel—容错机制

  • 超时机制

在不做任何处理的情况下,服务提供者不可用会导致消费者清求线程强制等待,而造成系统资源耗尽。加入超的时机制,一旦超时,就释放资源。由于释放资源速度较快,一定程度上可以抑制资源耗尽的问题。

  • 服务限流

  • 隔离

原理:用户的求将不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池已满,则会进行降级处理,用户的请求不会被旧塞,至少可以看到一个执行结果((例如返回友好的提示信息),而不是无休止的等待或者看到系统崩溃。

  • 服务熔断(保险丝的概念)

远程服务不稳定或网络抖动时暂时关闭,就叫服务熔断。

  • 服务降级(B计划的概念)

有服务熔断,必然要有服务降级。

所谓级,就是当某个服务熔断之后,服务将不再被调用,此时客户端可以自己准备一个本地的fallback(回退)回调,返回一个缺省值,例如O:(备用接口缓存/mock数据),这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,当然这也要看适合的业务场景。

sentinel—介绍

sentinel是阿里巴巴开源的,面向分布式服务架构的高可用防护组件

在这里插入图片描述

sentinel具有以下特征:

  • 丰富的应用场景: Sentiel承接了阿里巴巴近10年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范国)、消息削峰填谷、实时熔断下游不可用应用等
  • 完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至500台以下规模的集群的汇总运行情况。
  • 广泛的开源生态: Sertinel提供开箱即用的与其它开源框架库的整合模块,例如与spring Cloud、Dubbo, gRPC的整合,您只需要引入相应的依赖并进行简单的配置即可快速地接入Sentinel。
  • 完善的SPI扩展点: Sentinel提供简单易用、完善的SPI扩展点。您可以通过实现扩展点,快速的定制逻辑。例如定制规则管理、适配数据源等。

在这里插入图片描述

sentinel和Hystrix对比

在这里插入图片描述

sentinel—流控规则初体验

Sentinel 可以简单的分为Sentinel核心库和Dashboard

核心库不依赖Dashboard,但是结合Dashboard可以取得最好的效果。

1.创建项目导入依赖

<?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>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.7.RELEASE</version>
        <relativePath/>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>sentinel-demo</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--     sentinel核心库  -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-core</artifactId>
            <version>1.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
        <!--    如果要使用 @SentinelResource    -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-annotation-aspectj</artifactId>
            <version>1.8.0</version>
        </dependency>
    </dependencies>

</project>

2.controller层

package com.tian.sentinel.controller;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.ArrayList;

@RestController
@Slf4j
public class HelloController {
    private static final String RESOURCE_NAME ="hello";
    private static final String USER_RESOURCE_NAME="user";
    private static final String DEGRADE_RESOURCE_NAME="degrade";
    //进行流控
    @RequestMapping(value = "/hello")
    public String hello(){
        Entry entry=null;
        try {
            //sentinel针对资源进行限制
            entry= SphU.entry(RESOURCE_NAME);
            //被保护的业务逻辑
            String str = "hello world";
            log.info("-------"+str+"--------");
            return str;
        }catch (BlockException e1){
            //资源访问阻止,被限流或被降级
            //进行对应的处理操作
            log.info("block!");
            return  "被流控了!";
        }catch (Exception ex){
            //若需要配置降级规则,需要通过这种方式记录业务异常
            Tracer.traceEntry(ex,entry);
        }finally {
            if (entry != null) {
                entry.exit();
            }
        }
        return null;
    }


    @PostConstruct
    private static void initFlowRules(){
        //流控规则
        ArrayList<FlowRule> rules = new ArrayList<>();
        //流控
        FlowRule rule = new FlowRule();
        //为那个资源进行流控
        rule.setResource(RESOURCE_NAME);
        //设置受保护的资源阈值
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setCount(1);
        rules.add(rule);

        //加载配置好的规则
        FlowRuleManager.loadRules(rules);


    }
}

3.主启动类

4.application.yml

server:
  port: 8060

5.测试访问

http://localhost:8060/hello

一秒点击一次 访问没问题 显示 hello world

一秒点击2次或以上,显示被限流了

sentinel—@SentinelResource

改善接口中资源定义和被流控降级后的处理方法

1.添加依赖

<!--    如果要使用 @SentinelResource    -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-annotation-aspectj</artifactId>
    <version>1.8.0</version>
</dependency>

2.配置@bean

//注解支持的配置Bean
@Bean
public SentinelResourceAspect sentinelResourceAspect(){
    return new SentinelResourceAspect();
}

3.pojo

@Data
public class User {
    private final String username;
}

4.controller

package com.tian.sentinel.controller;

@RestController
@Slf4j
public class HelloController {
    private static final String RESOURCE_NAME ="hello";
    private static final String USER_RESOURCE_NAME="user";
    private static final String DEGRADE_RESOURCE_NAME="degrade";


    @PostConstruct
    private static void initFlowRules(){
        //流控规则
        ArrayList<FlowRule> rules = new ArrayList<>();
        //流控
        FlowRule rule = new FlowRule();
        //为那个资源进行流控
        rule.setResource(RESOURCE_NAME);
        //设置受保护的资源阈值
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setCount(1);
        rules.add(rule);

        FlowRule rule2 = new FlowRule();
        rule2.setResource(USER_RESOURCE_NAME);
        rule2.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule2.setCount(1);
        rules.add(rule2);

        //加载配置好的规则
        FlowRuleManager.loadRules(rules);


    }

    /**
     * value 定义资源
     * blockHandler 设置 流控降级后的处理方法 (默认该方法必须声明在同一个类)
     * 如果不想在同一个类,用blockHandlerClass 但是方法必须加上static关键字
     * fallback 当接口出现了异常,就可以交给fallback指定的方法进行处理
     * blockHandler > fallback
     * fallbackClass 和 用blockHandlerClass一样的用法
     * @return
     */
    @RequestMapping("/user")
    @SentinelResource(value = USER_RESOURCE_NAME,
            fallback = "fallbackHandlerForGetUser",
            blockHandler = "blockHandlerForGetUser")
    public User getUser(String id){
//        int i=1/0;
        return new User("tian");
    }

    /**
     * 1.一定要public
     * 2.返回值一定要和源方法(上面的)保证一致,包含源方法的参数.顺序也要一样
     * 3.可以在参数最后添加BlockException,可以区分是什么规则的处理方法
     * @return
     */
    public User blockHandlerForGetUser(String id,BlockException ex){
        ex.printStackTrace();
        return new User("流控!!!");
    }

    public User fallbackHandlerForGetUser(String id,Throwable e){
        e.printStackTrace();
        return new User("异常处理");
    }
}

5.配置文件

server:
  port: 8060

6.主启动类

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

    //注解支持的配置Bean
    @Bean
    public SentinelResourceAspect sentinelResourceAspect(){
        return new SentinelResourceAspect();
    }
}

7.测试访问

http://localhost:8060/user

现象:点击速度快,会被流控

sentinel—降级规则初体验

同上controller再加上代码

@PostConstruct  //初始化
    public void initDegradeRule(){
        //降级规则    异常
        ArrayList<DegradeRule> degradeRules = new ArrayList<>();
        DegradeRule degradeRule = new DegradeRule();
        degradeRule.setResource(DEGRADE_RESOURCE_NAME);
        //设置规则测率 : 异常数
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
        //出发熔断异常数: 2
        degradeRule.setCount(2);
        //出发熔断的最小请求数 : 2
        degradeRule.setMinRequestAmount(2);
        //统计时长  单位 ms   1分钟
        degradeRule.setStatIntervalMs(60*1000); //时间太短不好测
        //一分钟内 :执行了2次,出现了2次异常

        //熔断持续时长: 10s
        //一但出发熔断,再次请求对应的接口就会直接调用降级方法
        //10s过后----半开状态,恢复接口请求调用,再次熔断,不会根据设置的条件进行
        degradeRule.setTimeWindow(10);

        degradeRules.add(degradeRule);
        DegradeRuleManager.loadRules(degradeRules);
    }

    @RequestMapping("/degrade")
    @SentinelResource(value = DEGRADE_RESOURCE_NAME,
            entryType = EntryType.IN,
            blockHandler = "blockHandlerForFb")
    public User degarde(String id) throws InterruptedException {
        // 异常数\比例
        throw new RuntimeException("异常---");
    }


    public User blockHandlerForFb(String id,BlockException ex){
        ex.printStackTrace();
        return new User("流控!!!");
    }

访问 http://localhost:8060/degrade 页面都是报500错误访问几次页面显示 流控 (在10s内一直访问页面显示都是流控,10s后的话页面显示500)

sentinel—控制台部署

下载控制台jar包并在本地启动 下载地址

java -jar sentinel-dashboard-1.8.0.jar 默认端口8080

访问localhost:8080

账号sentinel

密码sentinel

在这里插入图片描述

自定义端口 用户名 密码 启动

java -Dserver.port=8888 -Dsentinel.dashboard.auth.username=tian -Dsentinel.dashboard.auth.password=123 -jar sentinel-dashboard-1.8.0.jar

客户端需要引入Transport模块来与sentinel控制台进行通信

导入依赖

<!--  整合控制台      -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
    <version>1.8.0</version>
</dependency>

idea中配置

-Dcsp.sentinel.dashboard.server=127.0.0.1:8888

在这里插入图片描述

启动项目 随便访问一个 localhost:8060/user

发现sentinel监控有东西了

在这里插入图片描述

sentinel—整合springcloud alibaba

1.引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--  sentinel启动器      -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

2.添加yml配置文件

server:
  port: 8861
spring:
  application:
    name: order-sentinel
  cloud:
    sentinel:
      transport:
        dashboard: 127.0.0.1:8888

3.controller

@RestController
@RequestMapping("/order")
public class OrderController {
    @RequestMapping("/add")
    public String add(){
        System.out.println("下单成功!");
        return "hello world";
    }
}

4.主启动类

5.访问测试 http://localhost:8861/order/add

6.发现sentinel控制台 有记录

相关文章:

  • 食品接触材料塑料中的异氰聚酯测试
  • .net core 控制台应用程序读取配置文件app.config
  • 微信小程序---验证码倒计时
  • Elasticsearch:运用 Python 实现在 Elasticsearch 上的向量搜索
  • 树的深度优先遍历与广度优先遍历
  • 大津法(最大类间方差法OTSU)
  • 搭建ELK分布式日志系统
  • 电子竞价是如何运作的?
  • TypeScript 学习之路 - 基础篇
  • 将路径中的“\\”换成“/”的方法
  • (一)Dubbo快速入门、介绍、使用
  • java-多线程,一个线程执行完毕,其他线程跳出运算-利用线程组ThreadGroup(子线程中执行当前线程组的interrupt方法)
  • 三分钟读懂什么是动作捕捉
  • Android—Surface,ViewRootImpl.relayoutWindow
  • <C++>详解string类
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • AzureCon上微软宣布了哪些容器相关的重磅消息
  • Javascript基础之Array数组API
  • Python - 闭包Closure
  • SegmentFault 2015 Top Rank
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 将回调地狱按在地上摩擦的Promise
  • 算法之不定期更新(一)(2018-04-12)
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • 湖北分布式智能数据采集方法有哪些?
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • # 透过事物看本质的能力怎么培养?
  • #if和#ifdef区别
  • #includecmath
  • #Linux(Source Insight安装及工程建立)
  • #微信小程序(布局、渲染层基础知识)
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (27)4.8 习题课
  • (4) PIVOT 和 UPIVOT 的使用
  • (70min)字节暑假实习二面(已挂)
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (Python第六天)文件处理
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (附源码)计算机毕业设计大学生兼职系统
  • (汇总)os模块以及shutil模块对文件的操作
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .gitignore
  • .NET CLR Hosting 简介
  • .net core 依赖注入的基本用发
  • .NET Standard / dotnet-core / net472 —— .NET 究竟应该如何大小写?
  • .net 调用php,php 调用.net com组件 --