SpringCloud中使用Sentinel实现限流的实战

 更新时间:2022年01月19日 12:01:54   作者:蹊源的奇思妙想  
限流在很多地方都可以使用的到,本篇博客将介绍如何使用SpringCloud中使用Sentinel实现限流,从而达到服务降级的目的,感兴趣的可以了解一下

前言

在分布式的项目中经常会遇到那种高并发的场景,为了保证系统不会被突然激增的请求导致宕机,我们常常会使用一种服务降级的手段来保护我们的系统,本篇博客将介绍如何使用SpringCloud中使用Sentinel实现限流,从而达到服务降级的目的。

正文 Sentinel

Sentinel 是面向微服务的轻量级流量控制框架,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Sentinel可以作为Hystrix的替代品,为系统提供服务熔断和服务降级的功能。

  • 服务熔断:根据保险丝的熔断是一个原理,当调用目标服务大量超时和失败,这时候应该熔断掉该服务的调用,从而快速释放资源,这段时间所有对其调用都是快速返回,保证整体服务系统的稳定
  • 服务降级:针对核心业务服务的压力剧增,根据当前业务场景和流量对其他非核心服务进行降级处理,可以进行限流,快速返回等处理,释放资源保证核心任务的正常运行。

Sentinel的限流原理

  • SentinelBucket(桶)为单位记录一个时间窗口内的请求总数、异常总数、总耗时等指标数据。
  • 而一个Bucket可以是记录一秒内的数据,也可以是10毫秒内的数据,我们称这个时间窗口为Bucket的统计单位,由使用者自定义。

所以Sentinel是基于滑动窗口算法来实现的。

设置Sentinel的阈值指标:

线程数模式
线程数的模式采用信号隔离的方式来防止线程池被占用。
用于防止线程池被占用,一般有两种方式:

  • 线程池隔离:为应对太多线程占用的情况,业内有使用隔离的方案,比如通过不同业务逻辑使用不同线程池来隔离业务自身之间的资源争抢,这种隔离方案虽然隔离性比较好,但是代价就是线程数目太多,线程上下文切换的 overhead 比较大,特别是对低延时的调用有比较大的影响。
  • 信号隔离sentinel采用的是信号隔离的方案,简单统计当前请求上下文的线程数目(正在执行的调用数目),如果超出阈值,新的请求会被立即拒绝。

所以业务处理是多线程的情况下使用线程数模式。

Sentinel采用信号隔离的方式,通过并发线程数模式,并结合基于响应时间的熔断降级模式,可以在不稳定的平均相应时间比较高的时候自动降级,防止过多的慢调用占满并发数,影响整个系统,避免慢调用引起依赖雪崩的现象。

QPS模式
QPS即每秒查询率,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。
QPS模式适合单读线程情况(如servlet请求),这种模式下提供了三种更加精确的流控方式:

  • 直接拒绝 :直接失败
  • Warm Up: 即请求 QPSthreshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值,通常用于秒杀系统。
  • 匀速排队:设置一个等待时间, 匀速处理请求,保证服务的均匀性,不能处理QPS>1000的场景。

Sentinel 两种计算阈值的模式:

  • 集群总体模式:即限制整个集群内的某个资源的总体 qps 不超过此阈值。
  • 单机均摊模式:单机均摊模式下配置的阈值等同于单机能够承受的限额,token server 会根据连接数来计算总的阈值(比如独立模式下有 3个 client 连接到了 token server,然后配的单机均摊阈值为 10,则计算出的集群总量就为30),按照计算出的总的阈值来进行限制。这种方式根据当前的连接数实时计算总的阈值,对于机器经常进行变更的环境非常适合。

这里要说明的是:qps是每秒查询数, tps是每秒内的事务数, pv 是指页面被浏览的次数。

Sentinel流控模式

  • 直接模式: 接口达到限流条件时,开启限流
  • 关联模式: 当关联的资源达到限流条件时,开启限流
  • 链路模式:当从某个接口过来的资源达到限流条件时,开启限流

Sentinel限流的方式

  • Sentinel控制台中根据url进行限流设置
  • 通过注解的方式进行自定义限流,又可以分为:自定义url限流和自定义资源限流。

第一步:部署sentinel-dashboard

sentinel-dashboard(点击下载jar包)是一个单独的应用,通过spring-boot进行启动,主要提供一个轻量级的控制台,它提供机器发现、单机资源实时监控、集群资源汇总,以及规则管理的功能。
这里可以理解为sentinel服务治理中心。

java -Dserver.port=18080 -jar sentinel-dashboard.jar 

在这里插入图片描述

第二步:在项目中整合sentinel

注入依赖

<!--springCloud-Alibaba-->
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-alibaba-dependencies</artifactId>
  <version>2.2.0.RELEASE</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>

<!--sentinel限流-->
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  <version>2.2.1.RELEASE</version>
</dependency>

在application.properties中的相关配置

spring.application.name=imagerepair
server.port=8080
spring.cloud.sentinel.transport.dashboard=127.0.0.1:18080
spring.cloud.sentinel.eager=true

Controller层

@RestController
public class UserController {

    @Autowired
    UserService userService;

    @RequestMapping("/hello")
    public String hello(){
      return userService.sayHello();
    }
}

Service

@Service
public class UserService {

    @SentinelResource(value = "sayHello",fallback = "sayHellofail")
    public String sayHello(){
        return "Hello,World";
    }

    public  String sayHellofail(){
        return "I'am sorry";
    }

}

在这里插入图片描述

设置限流,快速访问,从而触发服务降级

设置Sentinel的资源

在这里插入图片描述

当请求超过设定的阈值,启动限流降级,展示如下:

在这里插入图片描述

项目源码

该项目源码可从我的github中获取。

到此这篇关于SpringCloud中使用Sentinel实现限流的实战的文章就介绍到这了,更多相关SpringCloud Sentinel限流内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一文浅析Java中的值传递

    一文浅析Java中的值传递

    今天在解决一个问题时,程序总是不能输出正确值,分析逻辑思路没问题后,发现原来是由于函数传递导致了这个情况,下面我们就来看看Java中的值传递到底是什么情况吧
    2023-08-08
  • SpringBoot配置线程池的实现示例

    SpringBoot配置线程池的实现示例

    本文主要介绍了SpringBoot配置线程池的实现示例,主要包括在Spring Boot中创建和配置线程池,包括设置线程池的大小、队列容量、线程名称等参数,感兴趣的可以了解一下
    2023-09-09
  • Java实现调用第三方相关接口

    Java实现调用第三方相关接口

    最近在做一个项目,需要调用第三方接口,本文主要介绍了Java实现调用第三方相关接口,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • java中的除法运算和取模运算解读

    java中的除法运算和取模运算解读

    这篇文章主要介绍了java中的除法运算和取模运算,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • SpringMVC 跨重定向请求传递数据的方法实现

    SpringMVC 跨重定向请求传递数据的方法实现

    这篇文章主要介绍了SpringMVC 跨重定向请求传递数据的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • 详解分别用Kotlin和java写RecyclerView的示例

    详解分别用Kotlin和java写RecyclerView的示例

    本篇文章主要介绍了详解分别用Kotlin和java写RecyclerView的示例,详解分别用Kotlin和java写RecyclerView的示例
    2017-12-12
  • Spring处理@Async导致的循环依赖失败问题的方案详解

    Spring处理@Async导致的循环依赖失败问题的方案详解

    这篇文章主要为大家详细介绍了SpringBoot中的@Async导致循环依赖失败的原因及其解决方案,文中的示例代码讲解详细,感兴趣的可以学习一下
    2022-07-07
  • mybatis中使用oracle关键字出错的解决方法

    mybatis中使用oracle关键字出错的解决方法

    这篇文章主要给大家介绍了关于mybatis中使用oracle关键字出错的解决方法,文中通过示例代码将解决的方法介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-08-08
  • Java中的ArrayList.trimToSize()方法详解

    Java中的ArrayList.trimToSize()方法详解

    这篇文章主要介绍了Java中的ArrayList.trimToSize()方法详解,前几天看了Java ArrayList,没有明白trimToSize()这个方法是什么意思,所以看了一下源码并且debug一下自己的一个例子,明白了其中的含义,需要的朋友可以参考下
    2023-11-11
  • Hbase、elasticsearch整合中jar包冲突的问题解决

    Hbase、elasticsearch整合中jar包冲突的问题解决

    本篇文章主要介绍了Hbase、elasticsearch整合中jar包冲突的问题解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12

最新评论