目录
观博有逻辑,导航来相助《Spring Cloud Alibaba系列-目录导航》
1. Sentinel: 分布式系统的流量防卫兵
1.1 Sentinel 是什么?
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 的主要特性:
Sentinel 分为两个部分:
- 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
- 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
1.2 Sentinel 基本概念
资源:资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
规则:
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。
1.3 Sentinel 功能和设计理念
1.3.1 流量控制
什么是流量控制:
流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。然而,从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状,如下图所示:
流量控制设计理念:
流量控制有以下几个角度:
- 资源的调用关系,例如资源的调用链路,资源和资源之间的关系;
- 运行指标,例如 QPS、线程池、系统负载等;
- 控制的效果,例如直接限流、冷启动、排队等。
1.3.2 熔断降级
什么是熔断降级:
除了流量控制以外,及时对调用链路中的不稳定因素进行熔断也是 Sentinel 的使命之一。由于调用关系的复杂性,如果调用链路中的某个资源出现了不稳定,可能会导致请求发生堆积,进而导致级联错误。
Sentinel 和 Hystrix 的原则是一致的: 当检测到调用链路中某个资源出现不稳定的表现,例如请求响应时间长或异常比例升高的时候,则对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联故障。
熔断降级设计理念:
在限制的手段上,Sentinel 和 Hystrix 采取了完全不一样的方法。Hystrix 通过 线程池隔离 的方式,来对依赖(在 Sentinel 的概念中对应 资源)进行了隔离。这样做的好处是资源和资源之间做到了最彻底的隔离。缺点是除了增加了线程切换的成本(过多的线程池导致线程数目过多),还需要预先给各个资源做线程池大小的分配。
Sentinel 对这个问题采取了两种手段:
- 通过并发线程数进行限制
和资源池隔离的方法不同,Sentinel 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。这样不但没有线程切换的损耗,也不需要您预先分配线程池的大小。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。
- 通过响应时间对资源进行降级
除了对并发线程数进行控制以外,Sentinel 还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。
1.3.3 系统自适应保护
Sentinel 同时提供系统维度的自适应保护能力。防止雪崩,是系统防护中重要的一环。当系统负载较高的时候,如果还持续让请求进入,可能会导致系统崩溃,无法响应。在集群环境下,网络负载均衡会把本应这台机器承载的流量转发到其它的机器上去。如果这个时候其它的机器也处在一个边缘状态的时候,这个增加的流量就会导致这台机器也崩溃,最后导致整个集群不可用。
针对这个情况,Sentinel 提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。
2. 服务限流算法
要实现限流,就要使用限流算法,下面介绍四种限流的算法。
2.1 计数器算法
计数器算法以周期为单位,在周期内累加访问次数,当周期内访问次数达到阈值,触发限流策略,进入到下一个周期自动清零。
如下图:
限定周期为一分钟,最大阈值为100,在第一个周期内内有60次请求,未触发限流阈值
在第二个一分钟,进行清零,再第二个周期某一时刻达到100次请求,触发限流。
计数算法的问题:
如下图:
同样的场景,但是在第一个周期内的第58秒和第二个周期的第2秒,分别出现99个请求,此时未触发阈值
但是却是在4秒的时间达到接近200的并发,未能进行有效的限流,因此存在这种临界值的问题
2.2 滑动窗口算法
为了解决计数器算法带来的临界值算法,因此引入了活动窗口算法。滑动窗口算法的原理是在固定窗口中分割多个小的时间窗口,分别在每个小的时间窗口中记录访问次数,根据时间往前滑动并删除过期的小时间窗口,只需要统计滑动窗口范围内的所有小时间窗口总的数量。sentinel就是采用此种方式进行限流 。
如下图:
将一分钟拆分四个时间窗口,每个时间窗口处理25个请求,通过虚线表示窗口的滑动。在0~30s是两个时间窗口,代表每30s能通过50个请求。
在经过15秒后,窗口移动到15~45s时间处,在此时间内最多能有50个请求。
2.3 令牌同限流算法
对于每一个请求,需要在令牌桶中取得一个令牌,如果没有获得令牌,则触发限流。
如下图:
系统以恒定速度向令牌桶中放入令牌,如果请求过来,先在令牌桶中获取令牌后才能发送请求。
桶是有固定大小的,如果没有请求,那么桶在填满后就不再放入令牌。但是此时桶是满的,所以令牌桶可以处理突发的流量,在短时间内新增的流量能够正常处理,这是桶令牌的特性。
假设令牌生成速度是每秒100个,就是每秒的QPS为10
请求速度大于令牌生成速度:令牌消耗完毕,后续限流
请求速度等于令牌生成速度:流量处于平稳状态
请求速度小于令牌生成速度:并发不高,能够正常处理
2.4 漏桶限流算法
漏桶限流算法的主要作用是控制数据注入网络的速度,平滑网络的突发流量。
如下图:
与令牌桶相同,维护一个桶容器,容器以恒定速度出水
以恒定的速度出水,不管上面的速度多快,漏桶速度不变
当水流入速度过大会直接溢出(访问频率超过接口响应速率),然后就拒绝请求,可以看出漏桶算法能强行限制数据的传输速率
3. 在windows在安装Sentinel
3.1 控制台简介
Sentinel 控制台提供一个轻量级的控制台,它提供机器发现、单机资源实时监控、集群资源汇总,以及规则管理的功能。您只需要对应用进行简单的配置,就可以使用这些功能。
3.2 安装包获取
3.2.1 源码下载打包
操作步骤如下:
a. 进行源码的下载 https://github.com/alibaba/Sentinel
b. 源码解压:如 F:\spring-cloud-alibaba\Sentinel-master(解压后的目录)
c. 在 F:\spring-cloud-alibaba\Sentinel-master(解压后的目录) 执行“mvn clean”
d. 在 F:\spring-cloud-alibaba\Sentinel-master(解压后的目录) 执行"mvn package -DskipTests"
e. 在 “F:\spring-cloud-alibaba\Sentinel-master\sentinel-dashboard\target” 文件夹中,会看到sentinel-dashboard.jar包
3.2.2 直接下载jar包
下载地址:https://github.com/alibaba/Sentinel/releases
3.3 启动即安装
java -jar sentinel-dashboard-1.7.1.jar
3.4 访问控制台
在浏览器输入http://localhost:8080/即可访问,账号和密码为:sentinel/sentinel
3.5 修改consumer-8001和provider-7001两个微服务
3.5.1. 修改pom文件
在consumer-8001和provider-7001 pom中增加sentinel jar包
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
3.5.2 增加配置
在application.properties中增加如下配置:sentinel控制台地址
# sentinel dashboard
spring.cloud.sentinel.transport.dashboard=localhost:8080
3.5.3 启动服务,发起请求
下图中左侧菜单中的consumer-8001和provider-7001是需要在浏览器发起消费者请求后(http://localhost:8001/echo/feign/1111)在会出现,详情查看之间的博文