Sentinel入门(干货版)

一、Sentinel简介

1.1、导学

1、流量控制简介

流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。在网络传输中,任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制

在这里插入图片描述

2、熔断降级简介

在调用系统的时候,如果调用链路中的某个资源出现了不稳定(例如图中的 Service D 出现了问题),最终会导致请求发生堆积,进而导致级联错误

在这里插入图片描述

熔断降级就可以解决这个问题,所谓的熔断降级就是当检测到调用链路中某个资源出现不稳定的表现,例如请求响应时间长或异常比例升高的时候,则对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联故障

3、流量控制和熔断降低实现方案

SentinelHystrix(维护状态)Resilience4j(Spring推荐)
隔离策略信号量隔离(并发线程数限流)线程池隔离/信号量隔离信号量隔离
熔断降级策略基于响应时间、异常比率、异常数基于异常比率基于异常比率、响应时间
实时统计实现滑动窗口滑动窗口Ring Bit Buffer
动态规则配置支持多种数据源支持多种数据源有限支持
扩展性支持多种数据源支持多种数据源有限支持
限流基于 QPS,支持基于调用关系的限流有限的支持Rate Limiter
流量整形支持预热模式、匀速器模式、预热排队模式不支持简单的 Rate Limiter 模式
系统的自适应保护支持不支持不支持
控制台提供开箱即用的控制台,可配置规则、查看秒级监控、机器发现等简单的监控查看不提供控制台,可对接其他监控系统

1.2、Sentinel介绍

1、Sentinel简介

Sentinel是阿里巴巴出品的面向分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性

Sentinel组成

  • 核心库: 主要指 Java 客户端,不依赖任何框架 / 库,能够运行于所有 Java 7及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持
  • 控制台: 主要负责管理推送规则、监控、集群限流分配管理、机器发现等

2、Sentinel特征

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

3、Sentinel特性

在这里插入图片描述

4、Sentinel开源生态

在这里插入图片描述

5、Sentinel相关概念

资源

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

规则

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

6、Sentinel的优势

  • 友好的控制面板
  • 支持实时监控
  • 支持多种限流。支持 QPS 限流,线程数限流等多种限流策略
  • 支持多种降级模式,支持按平均值返回事件降级,按异常数降级,按异常比率降级等
  • 方便扩展开发,支持 SPI 模式对 chain 进行扩展
  • 支持链路的关联,可以实现链路统计限流,系统保护,热门资源保护等等

二、Sentinel入门

2.1、公网Demo

如果希望最快的了解 Sentinel 在做什么,我们可以通过 Sentinel 新手指南 来运行一个例子,并且能在云上控制台上看到最直观的监控和流控效果等

2.2、本地接入Sentinel

创建 SpringBoot 项目,在 pom.xml 中引入 sentinel-core 依赖

在这里插入图片描述

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>1.8.0</version>
</dependency>

创建 TestController,定义使用限流规则

这里我们定 OPS 类型的限流规则,每秒可接受的请求最多为2 个,超过则返回给页面“系统繁忙,请稍后”,不超过则返回给页面“Hello World”

package com.controller;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
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 org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

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

@RestController
public class TestController {
    @GetMapping("hello")
    public String hello() {
        // 使用限流规则
        try (Entry entry = SphU.entry("hello")) {
            return "hello Sentinel";
        } catch (BlockException e) {
            e.printStackTrace();
            return "系统繁忙,请稍后";
        }
    }

    // 定义限流规则
    @PostConstruct
    public void initFlowRules() {
        // 1、创建存放限流规则的集合
        List<FlowRule> rules = new ArrayList<>();

        // 2、创建限流规则
        FlowRule rule = new FlowRule();
        // 定义资源,表示 Sentinel 会对哪个资源生效
        rule.setResource("hello");
        // 定义限流规则类型(QPS)
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 定义 QPS 每秒能通过的请求个数
        rule.setCount(2);

        // 3、将限流规则存放到集合中
        rules.add(rule);

        // 4、加载限流规则
        FlowRuleManager.loadRules(rules);
    }
}

测试

页面快速刷新时,页面显示“系统繁忙,请稍后”

在这里插入图片描述

2.3、本地Sentinel控制台搭建

Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、实时监控(单机和集群),规则管理和推送功能

1、下载 Sentinel 控制台 jar 包

下载地址:https://github.com/alibaba/Sentinel/releases/download/1.7.2/sentinel-dashboard-1.7.2.jar

2、启动 Sentinel 控制台

启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。使用如下命令启动控制台

java -Dserver.port=9000 -jar sentinel-dashboard-1.7.2.jar

3、访问 Sentinel 控制台

通过浏览器打开 http://localhost:9090/ 即可访问 Sentinel 控制台

在这里插入图片描述

默认用户名和密码都是 sentinel

在这里插入图片描述

2.4、本地应用接入本地控制台

本地应用是以客户端的身份来接入控制台,具体步骤如下:

1、在本地应用的pom.xml文件中加入引入依赖

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
    <version>1.7.2</version>
</dependency>

2、在本地应用的JVM中添加启动参数

在这里插入图片描述

  • -Dcsp.sentinel.dashboard.server=localhost:9090:设置 Sentinel 控制台的主机地址和端口
  • -Dproject.name=SentinelQuickStart:设置本地应用在 Sentinel 控制台中的名称

3、运行测试

重启本地应用并重新通过浏览器访问 http://localhost:8080/hello,酷傲慢刷新几次,查看控制台中的实时监控情况

在这里插入图片描述

2.5、本地控制台设置限流规则

Sentinel 提供了两种设置流控规则的方式

  • 在应用中使用代码编码流控规则(案例中使用的方式)
  • 在 Sentinel 控制台设置流控规则

将项目中的流控规则部分代码去掉

package com.controller;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
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 org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

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

@RestController
public class TestController {
    @GetMapping("hello")
    public String hello() {
        // 使用限流规则
        try (Entry entry = SphU.entry("hello")) {
            return "hello Sentinel";
        } catch (BlockException e) {
            e.printStackTrace();
            return "系统繁忙,请稍后";
        }
    }

//    // 定义限流规则
//    @PostConstruct
//    public void initFlowRules() {
//        // 1、创建存放限流规则的集合
//        List<FlowRule> rules = new ArrayList<>();
//
//        // 2、创建限流规则
//        FlowRule rule = new FlowRule();
//        // 定义资源,表示 Sentinel 会对哪个资源生效
//        rule.setResource("hello");
//        // 定义限流规则类型(QPS)
//        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
//        // 定义 QPS 每秒能通过的请求个数
//        rule.setCount(2);
//
//        // 3、将限流规则存放到集合中
//        rules.add(rule);
//
//        // 4、加载限流规则
//        FlowRuleManager.loadRules(rules);
//    }
}

重新启动项目,去控制台设置限流规则

在这里插入图片描述

设置 QPS 为 2

在这里插入图片描述

页面快速刷新时,页面显示“系统繁忙,请稍后”

在这里插入图片描述

2.6、Sentinel定义资源的方式

Sentinel除了基本的定义资源的方式之外,还有其他的定义资源的方式,具体如下:

  • 抛出异常的方式定义资源
  • 返回布尔值方式定义资源
  • 异步调用支持
  • 注解方式定义资源
  • 主流框架的默认适配

1、抛出异常的方式定义资源

Sentinel 中的 SphU 包含了 try-catch 风格的 API。用这种方式,当资源发生了限流之后会抛出 BlockExecption。这个时候可以捕捉异常,进行限流之后的逻辑处理,而我们在上面的案例中使用的此种方式进行定义资源,关键代码如下:

// 使用限流规则监控保护资源
try (Entry entry = SphU.entry("hello")) {
    return "hello Sentinel";   // 被保护的资源
} catch (BlockException e) {
    e.printStackTrace();
    return "系统繁忙,请稍后";    // 被限流或者降级的处理
}

2、返回布尔值方式定义资源

Sentinel 中的 SphO 提供了 if-else 风格的 API。用这种方式,当资源发生了限流之后会返回 false,这个时候可以根据返回值, 进行限流之后的逻辑处理

在项目中创建 TestBooleanController,使用返回布尔值方式定义资源

package com.controller;

import com.alibaba.csp.sentinel.SphO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestBooleanController {
    @GetMapping("boolean")
    public boolean hello() {
        // 1、进行限流控制
        if (SphO.entry("Sentinel_Boolean")) {  // 限流入口
            try {
                System.out.println("访问成功");
                return true;
            } finally {
                // SphO.entry(xxx)需要和SphO.exit()成对出现
                // 否则会导致调用链记录异常,抛出ErrorEntryFreeException异常
                SphO.exit();  // 限流出口
            }
        } else {
            // 被限流或者降级的处理
            System.out.println("系统繁忙,请稍后");
            return false;
        }
    }
}

启动之后,设置限流规则:

在这里插入图片描述

快速刷新页面http://localhost:8080/boolean

在这里插入图片描述

3、异步调用支持

Sentinel 支持异步调用链路的统计。在异步调用中,需要通过 SphU.asyncEntry(xxx) 方法定义资源,并通过需要在异步的回调函数中调用 exit 方法

1、在本地应用的引导头类中添加 @EnableAsync,表示 SpringBoot 项目允许异步调用支持

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

2、创建 AsyncService 编写异步调用的方法

package com.controller;

import org.springframework.stereotype.Service;

@Service
public class AsyncService {
    // @Async表示方法为异步调用方法
    public void hello() {
        System.out.println("异步开始-----");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("完成异步-----");
    }
}

3、创建 TestAysncController,实现异步调用流控限制

package com.controller;

import com.alibaba.csp.sentinel.AsyncEntry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestAsyncController {
    @Autowired
    private AsyncService asyncService;

    @GetMapping("async")
    public void hello() {
        // 1、进行限流控制
        AsyncEntry asyncEntry = null;
        try {
            asyncEntry = SphU.asyncEntry("Sentinel_Async"); // 限流入口
            asyncService.hello();  // 异步方法调用
        } catch (BlockException e) {   // 被限流或者降级处理
            System.out.println("系统繁忙,请稍后");
        } finally {
            if (asyncEntry != null) {
                asyncEntry.exit();  // 限流出口
            }
        }
    }
}

4、注解方式定义资源

Sentinel 支持通过 @SentinelResource 注解定义资源并配置 blockHandler 函数来进行限流之后的处理

1、在本地应用的 pom.xml 文件中引入依赖

因为 Sentinel 中使用 Aspectj 的扩展用于自己定义资源、处理 BlockException 等,所以需要在项目中引入 sentinel-annotation-aspectj 依赖

<dependency>
   <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-annotation-aspectj</artifactId>
    <version>1.7.2</version>
</dependency>

2、创建 Aspectj 的配置类

package com.controller;

import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SentinelAspectConfiguration {
    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();
    }
}

3、创建 TestAnnController,实现限流控制

package com.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.RestController;

@RestController
public class TestAnnController {
    // 定义限流资源和限流降级回调函数
    @SentinelResource(value = "Sentinel_Ann", blockHandler = "exceptionHandler")
    @GetMapping("ann")
    public String hello() {
        return "Hello Sentinel";
    }

    // blockHandbler 函数,原方法调用被限流/降级/系统保护的时候调用
    public String exceptionHandler(BlockException ex) {
        ex.printStackTrace();
        return "系统繁忙,请稍后";
    }
}

转载请标明出处,原文地址:https://blog.csdn.net/weixin_41835916 如果觉得本文对您有帮助,请点击支持一下,您的支持是我写作最大的动力,谢谢。
这里写图片描述

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北极星小王子

你的鼓励是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值