SpringCloud Alibaba微服务之使用Sentinel进行流量控制

前言

本篇文章介绍 Sentinel 的部署以及如何使用 Sentinel 进行服务的流量控制,希望观众老爷们多多支持并在评论区批评指正。

1. 部署并注册服务

1.1. 安装

SentinelNacos 一样,都是独立安装和部署的 ,Sentinel下载[1]。注意我们下载完毕之后是一个 jar 包。

接下来我们就是开始 Sentinel 的安装和部署:


  1. 项目中创建一个文件夹 sentinel ,将我们下载的 jar 包,复制进去:
SpringCloud Alibaba微服务之使用Sentinel进行流量控制
  1. 点击编辑配置-> 添加 JAR 应用程序 -> 命名服务名称并选择 JAR 包路径 -> 并添加环境变量指定 Sentinel 服务端口。
SpringCloud Alibaba微服务之使用Sentinel进行流量控制
  1. 运行 JAR 包,访问 Sentinel 监控页面,用户名和密码都为 sentinel ,访问地址 localhost:8858
SpringCloud Alibaba微服务之使用Sentinel进行流量控制

进入控制台后,我们发现什么也没,那么就需要将我们的服务连接到 Sentinel 控制台。

1.2. 将服务连接至 Sentinel

注意:先启动 nacos

book-service连接至 Sentinel

  1. 首先在 book-service 中引入依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
  1. book-service 的配置文件中配置 sentinel
SpringCloud Alibaba微服务之使用Sentinel进行流量控制
  1. 启动 book-service ,在 Sentinel 监控页面查看服务是否出现。
SpringCloud Alibaba微服务之使用Sentinel进行流量控制

我们发现注销后重新登录 book-service 依旧没有出现,这是怎么回事?原来服务连接至 sentinel 并不会上来就连接,而是当我们访问这个服务的时候,才会连接到 Sentinel(懒加载机制,减少资源的消耗)。

那么我们就访问一次 localhost:8301/book/1

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

然后再查看 Sentinel 监控页面,就发现 book-service 已经出现了,我们可以查看实时监控,我们刚刚的请求:

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

现在我们就可以在Sentinel控制台中对我们的服务运行情况进行实时监控了,可以看到监控的内容非常的多,包括时间点、QPS(每秒查询率)、响应时间等数据。


然后按照上面的方式,将我们的所有微服务注册到 sentinel 中去:

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

2. 流量控制

2.1. 限流策略及算法

前面我们完成了对 Sentinel 的搭建与连接,接着我们来看 Sentinel 的第一个功能,流量控制.

我们的机器不可能无限制的接受和处理客户端的请求,如果不加以限制,当发生高并发情况时,系统资源将很快被耗尽。为了避免这种情况,我们就可以添加流量控制(也可以说是限流)当一段时间内的流量到达一定阈值的时候,新的请求将不再进行处理,这样不仅可以合理地应对高并发请求,同时也能在一定程度上保护服务器不受到外界的恶意攻击。

那么要实现限流,正常情况下,我们该采取什么样的策略呢?

  1. 方案一:「快速拒绝」,既然不再接受新的请求,那么我们可以直接返回一个拒绝信息,告诉用户访问频率过高。
  2. 方案二:「预热」,依然基于方案一,但是由于某些情况下高并发请求是在某一时刻突然到来,我们可以缓慢地将阈值提高到指定阈值,形成一个缓冲保护。
  3. 方案三:「排队等待」,不接受新的请求,但是也不直接拒绝,而是进队列先等一下,如果规定时间内能够执行,那么就执行,要是超时就算了。

针对于是否超过流量阈值的判断,这里我们介绍4种算法:

  1. 「漏桶算法」

顾名思义,就像一个桶开了一个小孔,水流进桶中的速度肯定是远大于水流出桶的速度的,这也是最简单的一种限流思路:
SpringCloud Alibaba微服务之使用Sentinel进行流量控制
我们知道,桶是有容量的,所以当桶的容量已满时,就装不下水了,这时就只有丢弃请求了。
利用这种思想,我们就可以写出一个简单的限流算法。

  1. 「令牌桶算法」

只能说有点像信号量机制。现在有一个令牌桶,这个桶是专门存放令牌的,每隔一段时间就向桶中丢入一个令SpringCloud Alibaba微服务之使用Sentinel进行流量控制牌(速度由我们指定)。当新的请求到达时,将从桶中删除令牌,接着请求就可以通过并给到服务,但是如果桶中的令牌数量不足,那么不会删除令牌,而是让此数据包等待。

可以试想一下,当流量下降时,令牌桶中的令牌会逐渐积累,这样如果突然出现高并发,那么就能在短时间内拿到大量的令牌,那么我们服务也会吃不消。所以我们可以做一个检测,当流量下降时逐级减少令牌的增加。

  1. 「固定时间窗口算法」

我们可以对某一个时间段内的请求进行统计和计数,比如在14:1514:16这一分钟内,请求量不能超过100,也就是一分钟之内不能超过100次请求,那么就可以像下面这样进行划分:
SpringCloud Alibaba微服务之使用Sentinel进行流量控制
虽然这种模式看似比较合理,但是试想一下这种情况:


    • 14:15:59 的时候来了100个请求
    • 14:16:01 的时候又来了100个请求

出现上面这种情况,符合固定时间窗口算法的规则,所以这200个请求都能正常接受,但是,如果你反应比较快,应该发现了,我们其实希望的是60秒内只有100个请求,但是这种情况却是在3秒内出现了200个请求,很明显已经违背了我们的初衷。因此,当遇到临界点时,固定时间窗口算法存在安全隐患。

  1. 「滑动时间窗口算法」

相对于固定窗口算法,滑动时间窗口算法更加灵活,它会动态移动窗口,重新进行计算:
SpringCloud Alibaba微服务之使用Sentinel进行流量控制
虽然这样能够避免固定时间窗口的临界问题,但是这样显然是比固定窗口更加耗时的。

2.2. 演示流量控制

针对 borrow-service 进行演示:

了解完限流策略和判定方法之后,我们在 Sentinel 中进行实际测试一下,打开管理页面的簇点链路模块:

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

点击流控,会看到让我们添加流控规则:

SpringCloud Alibaba微服务之使用Sentinel进行流量控制
  • 阈值类型:QPS就是每秒钟的请求数量,并发线程数是按服务当前使用的线程数据进行统计的。
  • 流控模式:当达到阈值时,流控的对象,这里暂时只用直接(直接表示当前接口)。
  • 流控效果:就是我们上面所说的三种方案。

2.2.1. 流控效果的演示

  1. 这里我们限制请求数,针对当前请求来演示第一种效果:设置阈值类型为 QPS ,单机阈值为 1,流控模式为直接(也就是当前资源),流控效果为快速失败(当达到阈值,不再接收以后的请求,返回拒绝信息)。
SpringCloud Alibaba微服务之使用Sentinel进行流量控制

然后我们请求这个 borrow/{uid} ,快速点击:就会返回失败信息。

SpringCloud Alibaba微服务之使用Sentinel进行流量控制
  1. 当我们改变流控效果为 Warm up (预热模式),其他设置不改变时:假设预热时长为 5s,那么请求限制阈值会在 5s 内增长到 10
SpringCloud Alibaba微服务之使用Sentinel进行流量控制

这样的效果时,会随着预热时长,慢慢达到最终阈值,有一个缓冲时间。

  1. 当我们改变流控效果为排队等待模式时,我们需要设置超时时间,当超过设定的超时时间时不对新的请求进行处理,但是也不直接拒绝,而是进队列先等一下,如果规定时间内能够执行,那么就执行,要是超时就算了。(超时时间单位 ms
SpringCloud Alibaba微服务之使用Sentinel进行流量控制

这里我们使用 apifox,演示这个效果,因为我们使用浏览器进行演示的话,请求不会超过的。

2.2.2. 流控模式的演示

最后我们来看看这些流控模式有什么区别:

SpringCloud Alibaba微服务之使用Sentinel进行流量控制
  1. 直接:只针对于当前接口。
  2. 关联:当其他接口超过阈值时,会导致当前接口被限流。
  3. 链路:更细粒度的限流,能精确到具体的方法。

  1. 直接的流控模式我们已经演示过了,接下来我们就演示一下关联模式,我们设置关联的资源接口为自带的 /error,流控效果为快速失败,单击阈值为 1
SpringCloud Alibaba微服务之使用Sentinel进行流量控制

然后请求 /error 接口,通过 apifox 进行请求,设置请求两次 error 后,请求一次 borrow/1

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

我们可以看到快速请求两次 /error 后,虽然 /error接口正常,但是 /borrow/{uid} 却被流控了,也就是说 /error 造成的后果由 /borrow/{uid} 承担。


  1. 然后我们演示链路模式,它能够更加精准的进行流量控制。链路流控模式指的是,当从指定接口资源请求达到限流条件时,开启限流。

这里得先讲解一下@SentinelResource注解的使用,我们可以对某一个具体方法进行限流控制,无论是谁在何处调用了它。当该方法上标注@SentinelResource 注解后,就会进行监控,比如我们这里创建两个请求映射,都来调用 BorrowService的被监控方法 getUserBorrowDetailByUid(uid)

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

然后我们为 getUserBorrowDetailByUid(uid) 方法上添加@SentinelResource 注解,对该方法进行监控:

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

接着我们在 borrow-serviceapplication.yml 中添加配置,然后重启服务。

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

接着我们对这个接口请求一次 borrow borrow2sentinel 簇点链路就监控到了我们标注@SentinelResource 注解的具体方法了。

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

然后我们对该方法(getBorrow)添加流控,流控模式为直接模式。

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

然后我们请求这两个接口 borrow borrow2,可以发现无论请求那个接口,超过阈值都会被限流,但是返回的不是拒绝信息,而是错误。

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

然后我们选择链路模式,链路选项实际上就是决定只限流从哪个方向来的调用,比如我们只对borrow2这个接口对getUserBorrowDetailByUid方法的调用进行限流,那么我们就可以为其指定链路:

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

然后我们会发现,限流效果只对我们配置的链路接口有效,而其他链路是不会被限流的。

2.2.3. 根据系统资源,对该服务整体进行限流

除了直接对接口进行限流规则控制之外,我们也可以根据当前系统的资源使用情况,是否对请求某个服务的所有请求进行限流:

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

系统规则支持以下的模式:

  • 「Load 自适应」(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5
  • 「CPU usage」(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
  • 「平均 RT」:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
  • 「并发线程数」:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
  • 「入口 QPS」:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

这里我们就演示一下 CPU 模式:本机系统 CPU10% 上下波动,我们就设置 CPU 阈值为 0.1 ,然后进行请求,看是否会限流:

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

在快速点击下,超过了 CPU 阈值,borrow-service 整体被限流了。

SpringCloud Alibaba微服务之使用Sentinel进行流量控制

「注意:」

系统规则在具体服务中,而不是针对所有的微服务。因为我们是在具体的服务的系统规则中进行设置的,只针对当前服务。而且在实际场景中,各个微服务分布在不同的主机中。

Reference

[1]

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

原文始发于微信公众号(yanghi):SpringCloud Alibaba微服务之使用Sentinel进行流量控制

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/226563.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!