系列学习 SpringCloud-Alibaba 框架之第 4 篇 —— Sentinel 高可用流量控制组件

news2024/11/24 1:21:07

1、概念

        Sentinel 是由阿里巴巴开发的开源项目,面向分布式微服务架构的轻量级高可用流量控制组件。以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度帮助用户保护服务的稳定性。可以说,Sentinel 就是取代 Hystrix 组件的。因为 Hystrix 已经进入了维护状态,不再更新。

Hystrix 官网:https://github.com/Netflix/Hystrix

Sentinel 官网:https://github.com/alibaba/Sentinel

Sentinel 中文使用文档:https://sentinelguard.io/zh-cn/docs/introduction.html

2、Sentinel 2 大核心

  • 核心库(Java 客户端):就是我们微服务要写的代码。
  • 控制台(Dashboard):Dashboard 主要负责管理推送规则、监控、管理机器信息等(下载 Jar 包运行即可)。参考官网:https://sentinelguard.io/zh-cn/docs/dashboard.html

3、Sentinel 控制台

3.1 Sentinel 控制台提供的功能

  • 查看机器列表以及健康情况:Sentinel 控制台能够收集 Sentinel 客户端发送的心跳包,判断机器是否在线。
  • 监控(单机和集群聚合):Sentinel 控制台通过 Sentinel 客户端暴露的监控 API,可以实现秒级的实时监控。
  • 规则管理和推送:通过 Sentinel 控制台,我们还能够针对资源定义和推送规则。
  • 鉴权:从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel。

3.2 下载控制台的 jar 包

官网地址:https://github.com/alibaba/Sentinel/releases

 目前最新版本 1.8.6(2022年12月5日)

3.3 创建启动脚本 .bat

 在我们下载好的 sentinel jar 包的同一级目录,我们创建一个名字叫做:sentinelRun.bat 文件,bat文件是dos下的批处理文件,它包含一条或多条命令。

然后,使用记事本打开 sentinelRun.bat 文件,输入如下启动命令:

java -Dserver.port=8898 -Dcsp.sentinel.dashboard.server=localhost:8898 -Dproject.name=sentinel-dashboard -Dsentinel.dashboard.auth.username=admin -Dsentinel.dashboard.auth.password=admin -jar sentinel-dashboard-1.8.6.jar
pause

说明:

  • -Dserver.port=8898 用于指定 Sentinel 控制台端口为 8898
  • sentinel-dashboard-1.8.6.jar  要对应我们下载好的 jar 包文件名称。
  • -Dsentinel.dashboard.auth.username=admin 表示设置登录账号名为:admin
  • -Dsentinel.dashboard.auth.password=admin 表示设置登录密码为:admin
  • 默认的账号和密码都是:sentinel,现在我们手动修改为:admin

3.4 双击 bat 文件启动服务

如图所示,sentinel 控制台启动成功。

访问地址:http://localhost:8898/     账号密码都是:admin (端口号、账号密码根据自己配置的来)

 

 页面如图:

 

注意:sentinel 服务内部通讯端口是 8719 

4、Sentinel 客户端(具体微服务)

控制台启动后,客户端(客户端,就是具体的微服务)需要按照以下步骤接入控制台:

1、添加依赖(pom.xml 依赖)
2、定义资源(Java 方法)
3、定义规则

4.1 添加依赖

        <!-- sentinel 依赖 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            <version>2.2.8.RELEASE</version>
        </dependency>

说明:如果想查看 sentinel 的版本(注意不是控制台版本,避免混淆),可以查看 Maven 中央仓库:https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-sentinel

yml 配置文件增加对 sentinel 的配置:

spring:
  cloud:
    # sentinel 配置
    sentinel:
      transport:
        # 内部通讯端口号
        port: 8719
        dashboard: localhost:8898

这时候客户端就算搭建好了,但是在 sentinel 的控制台还看不到效果,因为还需要客户端触发一次请求,才能初始化 sentinel 的相关配置。

4.2 定义资源(Java 方法)

在客户端某个 controller 类里增加测试代码:

    @GetMapping("/demo/sayHello")
    @SentinelResource(value = "helloWorld",
    blockHandler = "myBlockHandler", fallback = "myFallback")
    public String hello(){
        return "Hello,Welcome to the Sentinel world!";
    }

    /**
     * 触发了限流,直接拒绝后面的请求。
     * @return
     */
    public String myBlockHandler(BlockException blockException){
        blockException.printStackTrace();
        return "blockHandler";
    }

    /**
     * 触发了降级,直接返回快速失败的数据(熔断)。
     * @return
     */
    public String myFallback(Throwable throwable){
        throwable.printStackTrace();
        return "fallback";
    }

说明:

  • 使用注解:@SentinelResource 定义资源,@SentinelResource 注解是 Sentinel 提供的最重要的注解之一,它还包含了多个属性,如下表:
属性说明必填与否使用要求
value用于指定资源的名称必填
entryTypeentry 类型可选项(默认为 EntryType.OUT)
blockHandler服务限流后会抛出 BlockException 异常,而 blockHandler 则是用来指定一个函数来处理 BlockException  异常的。

简单点说,该属性用于指定服务限流后的后续处理逻辑。
可选项
  • blockHandler 函数访问范围需要是 public;
  • 返回类型需要与原方法相匹配;
  • 参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException;
  • blockHandler 函数默认需要和原方法在同一个类中,若希望使用其他类的函数,则可以指定 blockHandler 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
blockHandlerClass若 blockHandler 函数与原方法不在同一个类中,则需要使用该属性指定 blockHandler 函数所在的类。可选项
  • 不能单独使用,必须与 blockHandler 属性配合使用;
  • 该属性指定的类中的 blockHandler 函数必须为 static 函数,否则无法解析。
fallback用于在抛出异常(包括 BlockException)时,提供 fallback 处理逻辑。

fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。
可选项
  • 返回值类型必须与原函数返回值类型一致;
  • 方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常;
  • fallback 函数默认需要和原方法在同一个类中,若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
fallbackClass 若 fallback 函数与原方法不在同一个类中,则需要使用该属性指定 blockHandler 函数所在的类。可选项
  • 不能单独使用,必须与 fallback 或 defaultFallback  属性配合使用;
  • 该属性指定的类中的 fallback 函数必须为 static 函数,否则无法解析。
defaultFallback默认的 fallback 函数名称,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。

默认 fallback 函数可以针对所以类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。
可选项
  • 返回值类型必须与原函数返回值类型一致;
  • 方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常;
  • defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
exceptionsToIgnore用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。可选项

-

  • 如果接口上没有使用 @SentinelResource 注解,默认的资源名称就是接口路径地址。
  • 注意 handler 和 fallback 的方法都需要增加异常类。fallback是针对方法出现异常了,则会进入fallback方法。blockhandler是针对流控设置,超出规则,则会进入blockhandler方法。若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出BlockException时只会进入 blockHandler 处理逻辑。若未配置 blockHandler、fallback 和 defaultFallback,则被限流降级时会将 BlockException 直接抛出。
  • handler 和 fallback 对应的函数,要么在相同的类里面,要么在其它类里是 static 静态函数。

重启客户端,发送测试请求。http://localhost:9050/demo/sayHello

 然后查看 Sentinel 控制台:

可以看到我们的客户端(微服务)已经受到 Sentinel 控制了。至此,客户端与 sentinel 打通。

4.3 定义规则

规则可以通过配置文件定义,也可以在控制台中定义。在配置文件定义的话,在客户端初始化之后,就会同步到 Sentinel 控制台上来。如果通过控制台设置,在客户端(微服务)重启后失效,也就是说,限流规则并没有持久化在 Sentinel 服务端

  1. 通过控制台设置流控规则

 

 

设置阈值类型是:QPS (Queries Per Second,意思是“每秒查询率”)。阈值 1 秒内接受1次请求。测试:1秒内多次请求接口,

 模拟程序出现异常的情况:

    @GetMapping("/demo/sayHello")
    @SentinelResource(value = "helloWorld",
    blockHandler = "myBlockHandler", fallback = "myFallback")
    public String hello(){
        int k = 1/0;
        return "Hello,Welcome to the Sentinel world!";
    }

 测试:

 第一次请求直接 fallback(因为抛出了异常)。但是后面多次请求后,会出现 handler,因为触发了流控规则。

        2、动态配置规则

通过控制台新增规则,重启微服务客户端规则就失效了。显然不符合我们实际生产所需。生产上一般通过动态规则源的方式来动态管理规则。因此需要动态配置规则。一方面,可以跟 nacos 整合,另一方面,可以写到配置文件中。

SentinelProperties 内部提供了 TreeMap 类型的 datasource 属性用于配置数据源信息,支持:

  • 文件配置规则
  • Nacos 配置规则
  • ZooKeeper 配置规则
  • Apoloo 配置规则
  • Redis 配置规则

讲解一下用到最多的【文件配置规则】,在配置文件中的 sentinel 节点增加 datasource 节点:

spring:
  cloud:
    # sentinel 配置
    sentinel:
      transport:
        # 内部通讯端口号
        port: 8719
        dashboard: localhost:8898
      datasource:
        ds1:
          file:
            # 配置文件地址和类型
            file: classpath:myRule.json
            data-type: json
            rule-type: flow

对应的,在项目的根目录增加 myRule.json 文件,文件内容如下:

[
  {
    "resource": "helloWorld",
    "count": 1,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0,
    "controlBehavior": 0
  }
]

流量控制规则 (FlowRule):

Field说明默认值
resource资源名,资源名是限流规则的作用对象
count限流阈值
grade限流阈值类型,QPS 或线程数模式QPS 模式
limitApp流控针对的调用来源default,代表不区分调用来源
strategy调用关系限流策略:直接、链路、关联根据资源本身(直接)
controlBehavior流控效果(直接拒绝 / 排队等待 / 慢启动模式),不支持按调用关系限流直接拒绝

更多动态配置参考官网:dynamic-rule-configuration | Sentinel

配置完毕,重启客户端的微服务。调用一次接口:

可以看到流控规则已经包含了我们配置文件里设置的规则了,注意到配置文件里的流控规则不允许修改资源名。生产环境一般都是这样配置使用。 

5、Sentinel 对 Feign 的支持

5.1 添加对 feign 的依赖

        <!-- sentinel 对 feign 支持 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.8.RELEASE</version>
        </dependency>

代码与 Feign 整合 Hystrix 的一样,如:

API 接口定义如下:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;

@Component
@FeignClient(name = "xxx-service", fallbackFactory = TestFactory.class, contextId = "TestApi")
public interface TestApi {

    @GetMapping("/test")
    String test();

}

注意:我们增加了一个 contextId 等于当前类名,主要是因为旧版本的 springboot 是支持 2 个或者 2 个以上接口类 @FeignClient 有相同的 value 或者 name,但是 SpringBoot 2.2.x 版本以后,就不支持了,会抛出异常:

could not be registered. A bean with that name has already been defined and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

可以通过配置文件里设置:spring.main.allow-bean-definition-overriding=true,也可以通过 contextId 作为区分。推荐后者。

对应的 TestFactory 类(核心代码):

import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class TestFactory implements FallbackFactory<TestApi> {

    /**
     * 如果调用异常,使用熔断机制返回错误信息
     * @param cause
     * @return
     */
    @Override
    public TestApi create(Throwable cause) {
        return new TestApi() {
            @Override
            public String test() {
                log.error("远程调用异常:"+cause);
                return "远程调用异常,这是托底数据";
            }
        };
    }
}

增加一个测试的 controller:

@RestController
public class TestController {
    @Autowired
    private TestApi testApi;

    @GetMapping("/test")
    public String test() {
        return testApi.test();
    }
}

5.2 配置文件开启对 feign 的支持

配置文件增加配置:feign.sentinel.enabled=true 即可。

重启客户端的微服务,发送一次测试请求:http://localhost:9050/test

这时候是有异常的,因为我们没有配置对应的远程服务,但不影响。我们查看控制台,已经将 feign 接口纳入管理了。

远程调用异常:java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: xxx-service

 

只要我们增加对应的远程微服务,提供对应的测试接口,就可以打通整条链路的调用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/66627.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

H3C WX2510h无线控制器如何网关式部署无线网络

环境&#xff1a; H3C-WX2510H AC控制器 H3C Comware Software, Version 7.1.064, Release 5457 AP H3CWA6320-C 问题描述&#xff1a; H3C wx2510h无线控制器如何网关式部署无线网络 解决方案&#xff1a; 1.配置DHCP服务&#xff0c;开启vlan1为DHCP服务器 2.新建地址…

Spring-boot初级

一、springboot介绍 Spring Boot 是由 Pivotal 团队提供的基于 Spring 的全新框架&#xff0c;其设计目的是为了简化 Spring 应用的搭建和开发过程。该框架遵循『约定大于配置』原则&#xff0c;采用特定的方式进行配置&#xff0c;从而使开发者无需定义大量的 XML 配置。通过…

表、栈和队列及其C语言实现

1、抽样数据类型 程序设计的基本法则之一是例程不应该超过一页。这可以通过把程序分割为一些模块(module)来实现。每个模块是一个逻辑单元并执行某个特定的任务&#xff0c;它通过调用其他模块而本身保持很小。模块化有几个优点。首先&#xff0c;调试小程序比调试大程序容易得…

ALM研发管理中规则库的配置与使用

1.规则库简介 规则库就是描述某领域内知识的产生式规则的集合&#xff0c;而规则往往是由一个具体的业务逻辑具象而来&#xff0c;它通常是很具体的&#xff0c;有着明确的处理逻辑&#xff08;即将输入数据经过一系列逻辑处理&#xff0c;输出处理后的结果&#xff09;。 2.规…

从一个 issue 出发,带你玩图数据库 NebulaGraph 内核开发

如何 build NebulaGraph&#xff1f;如何为 NebulaGraph 内核做贡献&#xff1f;即便是新手也能快速上手&#xff0c;从本文作为切入点就够了。 NebulaGraph 的架构简介 为了方便对 NebulaGraph 尚未了解的读者也能快速直接从贡献代码为起点了解它&#xff0c;我把开发、贡献内…

synchronized详解

什么是线程安全问题? 简单来说就是当多个线程同时访问某个方法时,这个方法无法按照我们预期的行为来执行&#xff0c;那么我们认为这个方法是线程不安全的 导致线程不安全的主要原因 1.原子性 什么是原子性 比如在数据库事务的ACID特性中 当前操作中包含多个数据库事务操…

DolphinDB 诚挚招募实施伙伴

随着 DolphinDB 业务发展&#xff0c;为满足迅速增长的客户需求&#xff0c;我们现正式启动“实施伙伴招募计划”。DolphinDB 客户已经涵盖7家Top 10券商、头部公募及私募基金、知名银行、交易所、世界500强制造业客户、标杆能源企业等&#xff0c;我们非常期待和欢迎实施伙伴们…

毕业设计 基于stm32的智能平衡小车 - 单片机 物联网嵌入式

文章目录0 前言1 项目背景2 设计思路3 硬件设计4 软件设计4.1 核心PID控制4.2 直立控制程序设计4.3 速度控制程序设计4.4 方向控制程序设计4.5 关键代码5 最后0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点…

32、Java高级特性——日期操作类、Date类、SimpleDateFormat类、Calendar类

目录 一、日期操作类 二、Date类 1、Date类中的构造方法 2、获取系统当前时间 三、SimpleDateFormat类 1、SimpleDateFormat类中的构造方法 2、format(Date date,StringBuffer toAppendTo,FieldPosition pos)方法 四、Calendar类 1、Calendar类中的构造方法 2、Cal…

[附源码]Python计算机毕业设计SSM家政信息管理平台(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Removing the Bias of Integral Pose Regression 阅读笔记

消除积分姿态回归的偏差 ICCV2021 论文链接 补充材料链接 参考链接 摘要&#xff1a; 尽管姿态估计的回归法更直观&#xff0c;但由于热图法的优越性能&#xff0c;使其在2D人体姿态估计中占主导地位。积分回归法在架构上使用隐式热图&#xff0c;拉近了热图法与回归法。这就…

GraalVM + Springboot3 + IDEA 在widow10 上完成构建本地化服务

GraalVM是开发人员编写和执行Java代码的工具。具体来说&#xff0c;GraalVM是由Oracle创建的Java虚拟机&#xff08;JVM&#xff09;和Java开发工具包&#xff08;JDK&#xff09;。它是一个高性能的运行时&#xff0c;可以提高应用程序的性能和效率。 GraalVM的目标包括&…

【数据结构】哈希表

目录 一、哈希函数的引入 二、解决哈希冲突的思路 2.1基于闭散列的思路 2.2基于开散列的思路 2.3负载因子 三、关于哈希函数的设计 四、基于拉链法实现哈希表 4.1哈希表的内部构造 4.2插入操作 4.3扩容操作 4.4搜索操作 4.5删除操作 哈希表其实就是基于数组衍生而来…

深度解读面试题:链表中环的入口结点(附代码,可过在线OJ)

在解读“链表中环的入口结点”前&#xff0c;我认为有必要明白关于它的一些用于打基础的问题&#xff08;相交链表、判断链表中是否存在环&#xff09; 相交链表 题目&#xff1a; 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点…

快收藏!!整理了100个Python小技巧!!

下面&#xff0c;我就给大家分享100个Python小技巧&#xff0c;帮助大家更好的了解和学习Python&#xff0c;欢迎收藏、关注&#xff0c;点赞支持&#xff01; ▍1、for循环中的else条件 这是一个for-else方法&#xff0c;循环遍历列表时使用else语句。下面举个例子&#xff…

根据平均值列出记录

AANSI SQL包括几个聚合函数&#xff0c;使您可以对一组值进行计算以将其结果作为单个值返回。他们包括Count(), Min(), Max(), Sum() and AVG(),以及其他。默认情况下&#xff0c;聚合函数适用于所有行&#xff0c;但是您可以通过将WHERE子句应用于SELECT语句来缩小字段的范围。…

直冲云霄,阿里大牛耗时49天整理12W字面试手册,押题准确率直冲95%

很多人都想进字节做开发&#xff0c;不论是技术还是薪资、福利都算得上TOP级~ 7月底官方再次启动扩招&#xff0c;发布了1200&#xff0b;后端工程师岗位&#xff01; 那么本批有哪些优质岗位可选择&#xff1f;薪资待遇如何&#xff1f; 下面给大家列出几类具体的岗位要求&a…

软件项目管理指南:定义、5大过程、估算及进度管理方法等

本文将分享&#xff1a;1、软件项目管理的定义&#xff1b;2、软件项目管理的过程步骤&#xff1b;3、软件项目管理的内容&#xff1b;4、软件项目估算与进度管理方法&#xff1b;5、软件开发各生命周期阶段与文档、角色间的关系&#xff1b;6、软件开发项目中的各大角色职能&a…

深度学习-第P1周——实现mnist手写数字识别

深度学习-第P1周——实现mnist手写数字识别深度学习-第P1周——实现mnist手写数字识别一、前言二、我的环境三、前期工作1、导入依赖项并设置GPU2、导入数据集3、数据可视化四、构建简单的CNN网络五、训练模型1、设置超参数2、编写训练函数3、编写测试函数4、正式训练六、结果可…

ADSP-21489的图形化编程详解(7:延时、增益、分频、反馈、响度)

延时 21489 可以做延时&#xff0c;音频高手会运用此项算法来增强音效&#xff0c;我们做个最简单的&#xff0c;让大家知道怎么用它&#xff0c;至于怎么样嵌入到自己的系统里实现更好的效果&#xff0c;则需要各位调音师专业的耳朵来判断&#xff0c;调音无上限&#xff01;…