sentinel---微服务保护

什么是sentinel

Sentinel 是由阿里巴巴中间件团队开发的开源项目,是一种面向分布式微服务架构的轻量级高可用流量控制组件。
Sentinel 主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度帮助用户保护服务的稳定性。

Sentinel 具有以下优势:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的“双十一”大促流量的核心场景,例如秒杀(将突发流量控制在系统可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用服务等。
  • 完备的实时监控:Sentinel 提供了实时监控功能。用户可以在控制台中看到接入应用的单台机器的秒级数据,甚至是 500 台以下规模集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供了开箱即用的与其它开源框架或库(例如 Spring Cloud、Apache Dubbo、gRPC、Quarkus)的整合模块。我们只要在项目中引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。此外,Sentinel 还提供 Java、Go 以及 C++ 等多语言的原生实现。
  • 完善的 SPI 扩展机制:Sentinel 提供简单易、完善的 SPI 扩展接口,我们可以通过实现这些扩展接口快速地定制逻辑,例如定制规则管理、适配动态数据源等。

Sentinel 的组成

Sentinel 主要由以下两个部分组成:

  • Sentinel 核心库:Sentinel 的核心库不依赖任何框架或库,能够运行于 Java 8 及以上的版本的运行时环境中,同时对 Spring Cloud、Dubbo 等微服务框架提供了很好的支持。
  • Sentinel 控制台(Dashboard):Sentinel 提供的一个轻量级的开源控制台,它为用户提供了机器自发现、簇点链路自发现、监控、规则配置等功能。

Sentinel 核心库不依赖 Sentinel Dashboard,但两者结合使用可以有效的提高效率,让 Sentinel 发挥它最大的作用。

Sentinel 的开发流程

  1. 引入 Sentinel 依赖:在项目中引入 Sentinel 的依赖,将 Sentinel 整合到项目中;
  2. 定义资源:通过对主流框架提供适配或 Sentinel 提供的显式 API 和注解,可以定义需要保护的资源,此外 Sentinel 还提供了资源的实时统计和调用链路分析;
  3. 定义规则:根据实时统计信息,对资源定义规则,例如流控规则、熔断规则、热点规则、系统规则以及授权规则等。
  4. 检验规则是否在生效:运行程序,检验规则是否生效,查看效果。

雪崩问题

微服务中的某服务故障,导致整个连链路中的所有微服务都不可用

解决雪崩问题的常见方式有四种:

  1. 超时处理:设定超时时间,请求超过--定时间没有响应就返回错误信息,不会无休止等待
  2. 舱壁模式:限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,因此也叫线程隔离。
  3. 熔断降级:由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求。
  4. 流量控制:限制业务访问的QPS,避免服务因流量的突增而故障。

安装sentinel

下载好jar包后解压直接使用

sentinel---微服务保护_第1张图片

 通过CMD命令

java -jar sentinel-dashboard-1.8.1.jar

默认端口号8080,由于我的8080被使用,所以使用下面的命令更改端口号,并解压

java -Dserver.port=8123 -jar sentinel-dashboard-1.8.1.jar

sentinel---微服务保护_第2张图片

 解压成功通过端口号直接访问

sentinel---微服务保护_第3张图片

使用sentinel

第一步 添加依赖

在需要的微服务中添加依赖


    com.alibaba.cloud
    spring-cloud-starter-alibaba-sentinel

第二步 

在配置文件中指定sentinel地址

spring.cloud.sentinel.transport.dashboard=localhost:8123

sentinel---微服务保护_第4张图片

 重启微服务并测试

sentinel---微服务保护_第5张图片

sentinel---微服务保护_第6张图片

限流规则

簇点链路

就是项目内的调用链路,链路中被监控的每个接口就是一个资源。默认情况下sentinel会监控SpringMVC的每一个端点(Endpoint),因此SpringMVC的每一个端点(Endpoint)就是调用链路中的一个资源

sentinel---微服务保护_第7张图片

流控模式

在添加限流规则时,点击高级选项,可以选择三种流控模式:

直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式
关联:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流
链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流
sentinel---微服务保护_第8张图片

sentinel---微服务保护_第9张图片

直接 

sentinel---微服务保护_第10张图片

sentinel---微服务保护_第11张图片

使用jmeter压测工具进行测试

sentinel---微服务保护_第12张图片

结果只有五次通过 

sentinel---微服务保护_第13张图片

 关联

使用场景:比如用户支付时需要修改订单状态,同时用户要查询订单。查询和修改操作会争抢数据库锁,产生竞争。业务需求是有限支付和更新订单的业务,因此当修改订单业务触发阈值时,需要对查询订单业务限流。

sentinel---微服务保护_第14张图片

限制谁的流量就操作谁,假如需要设定C达到阈值限制B的流量,就需要在B上添加流控规则。

 sentinel---微服务保护_第15张图片

测试 

设置规则

sentinel---微服务保护_第16张图片

添加测试

sentinel---微服务保护_第17张图片

 sentinel---微服务保护_第18张图片

 开启测试后通过浏览器访问read接口,发现被限流

sentinel---微服务保护_第19张图片

 链路

Sentinel默认只标记Controller中的方法为资源,如果要标记其它方法,需要利用@SentinelResource注解

准备测试环境

创建两个controller层接口,调用同一个service层方法

sentinel---微服务保护_第20张图片

给service层的接口添加注解

添加此注解后,sentinel会将他也识别到

sentinel---微服务保护_第21张图片

Sentinel默认会将Controller方法做context整合,导致链路模式的流控失效,需要修改application文件

sentinel---微服务保护_第22张图片

重启服务进行测试 

sentinel---微服务保护_第23张图片sentinel---微服务保护_第24张图片

 添加流控规则

sentinel---微服务保护_第25张图片

 sentinel---微服务保护_第26张图片

使用压测工具进行测试

创建两个测试访问两个接口 

sentinel---微服务保护_第27张图片 sentinel---微服务保护_第28张图片

 sentinel---微服务保护_第29张图片

 sentinel---微服务保护_第30张图片

流控效果

流控效果是指请求达到流控阈值时应该采取的措施,包括三种:

  1. 快速失败:达到阈值后,新的请求会被立即拒绝并抛出FlowException异常。是默认的处理方式。
  2. warm up预热模式,对超出阈值的请求同样是拒绝并抛出异常。但这种模式阈值会动态变化,从一个较小值逐渐增加到最大阈值。
  3. 排队等待:让所有的请求按照先后次序排队执行,两个请求的间隔不能小于指定时长

sentinel---微服务保护_第31张图片

快速失败

当达到阈值时,请求会被直接拒绝。上面的例子用的都是快速失败,这里不再举例。

warm up 预热模式

大白话来讲,刚开始把 阈值调低,不要让过多的请求访问服务器,导致冲垮服务器,先让服务器一点一点处理,再慢慢加量。经典的例子:一个好久没运动的人,你刚开始让他跑10圈,他可能会累死,但是你给他一个预热时间,比如 第一天跑 2圈,第三天跑 3 圈,第四天跑4圈,以此类推...

默认coldFactor为3,即请求QPS从(threshold / 3)开始,经多少预热时长才逐渐升至设定的QPS阈值。
如下案例,阀值为10,预热时长设置5秒。

我设置QPSthreshold10,预热时间为5秒,那么初始阈值就是 10 / 3 ,也就是3,然后在5秒后逐渐增长到10

准备测试环境

建立接口

sentinel---微服务保护_第32张图片

添加流控模式

sentinel---微服务保护_第33张图片

通过压测工具测试

可以看到刚开始放行的请求少,逐渐加多

sentinel---微服务保护_第34张图片

 sentinel---微服务保护_第35张图片

 通过sentinel的实时监控可以更直观看到,阈值逐渐加大,没有像山峰一样忽高忽低。

sentinel---微服务保护_第36张图片

 排队等待

先进行测试在阐述原理

定义流控效果

sentinel---微服务保护_第37张图片

定义测试

sentinel---微服务保护_第38张图片

sentinel---微服务保护_第39张图片

基于漏桶算法的排队等待模式

Sentinel排队等待只支持QPS在1000以下。

 它的中心思想是,以固定的间隔时间让请求通过。当请求到来的时候,如果当前请求距离上个通过的请求通过的时间间隔不小于预设值,则让当前请求通过。否则,计算当前请求的预期通过时间,如果该请求的预期通过时间小于规则预设的 timeout 时间,则该请求会等待直到预设时间到来通过(排队等待处理);若预期的通过时间超出最大排队时长,则直接拒接这个请求。
sentinel---微服务保护_第40张图片

 代码逻辑
@1 计算请求通过的间隔时间
假如设置的阈值为count=100即每秒允许100个请求,每次通过一个请求acquireCount=1,套入公式costTime=10。即两次请求的时间间隔为10秒
@2 计算这次请求通过的预期时间=上次请求通过的时间+时间间隔
@3 当前时间大于预期时间,则允许通过并更新上次请求时间戳
@4 当前时间小于预期时间,则需要等待;计算需要等待的时间
@5 需要等待的时间大于超时时间则拒绝,默认超时时间为500毫秒
@6 再算一遍等待时间,算法跟第4步一样,并再次判断是否超过等待时间
@7 线程sleep等待时间后允许请求通过

我自己的理解:

我们给定等待时间为2秒,假如他每一秒能处理5个请求,200毫秒处理一个,那假如每一秒都会有11个请求进来,处理掉5个后,剩下的6个的都会排队,这时,时间来到下一秒,他继续处理上一秒未能处理掉的去排队的请求,这时又进来11个请求,由于上一秒的11个请求还没处理完,所以这一秒的11个请求会继续去排队,以此类推,但排队的队伍长度是我们定好的,我们定了2秒,因为他一秒处理五个,所以2秒能处理掉10个,也就是等待队列只能有10个排队的请求,但这个10是我们人为算出来的,我个人理解的是,程序并不是通过数量去测算的,而是通过时间,超过等待时间的会被直接拒绝,在上边的代码逻辑中提到了时间,这个我并是不是十分理解,我只能认为他每处理完一个请求,都会记录一个时间,然后还会计算出来一个处理一个请求大概需要多久,我这里假定是200毫秒,然后每进来一个请求,他会计算这个等待队列处理到这个新来的请求需要多长时间(怎么算的不理解),然后拿这个时间去跟我们规定的等待时间对比,超过了等待时间就拒绝掉这个请求,他只是拒绝了这个请求,并没有关闭这个服务端口,所以请求还是不断地进来,每进来一个他都会算时间是否等待会超时,而他200毫秒也会处理掉一个请求,一直到计算的等待时间不超时了,新请求就会排到等待队列中,他处理掉一个整个队伍都会往前移动一个,这就空出来一个位置,这就能进来一个新请求。也就是只要我处理完1个请求后,2秒内能处理到你的就会等待。(这个2秒是我们规定的等待时间)。

sentinel---微服务保护_第41张图片

sentinel---微服务保护_第42张图片

参考文章

Sentinel漏桶匀速限流https://blog.csdn.net/gaoliang1719/article/details/109567962?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~Rate-1-109567962-blog-118339191.pc_relevant_multi_platform_whitelistv4eslandingrelevant&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~Rate-1-109567962-blog-118339191.pc_relevant_multi_platform_whitelistv4eslandingrelevant&utm_relevant_index=1

你可能感兴趣的:(sentinel,sentinel,微服务,java)