美文网首页程序员专栏Spring-Boot
Gateway结合Sentinel1.8限流熔断管理以及自定义异

Gateway结合Sentinel1.8限流熔断管理以及自定义异

作者: 享学课堂 | 来源:发表于2020-11-03 16:01 被阅读0次

享学课堂特邀作者:老顾
转载请声明出处!!!

前言

之前老顾介绍了gateway集合sentinel1.8的整体概念介绍,今天老顾就来介绍一下,gateway如何与sentinel相结合,sentinel1.8降级规则的变化,以及dashboard源码的bug。

POM依赖

我们先创建一个gateway项目,要与Sentinel结合需要依赖一下jar包。

说明一下老顾把以前文章中的案例依赖的jar包进行了升级,针对SpringCloud Alibaba的版本需要升级到2.2.3.RELEASE版本;spring boot也升级到了2.3.3.RELEASE;spring cloud升级到Hoxton.SR8

<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
    
<dependency>  
    <groupId>com.alibaba.cloud</groupId>  
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>  
</dependency>
        
<dependency>
    <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>

不要搞错了哦,网上有些资料有坑

配置

网关项目中增加一个配置类,我们需要添加一个SentinelGatewayFilterSentinelGatewayBlockExceptionHandler实例

img 下载并安装sentinel-dashboard

之前老顾的文章已经介绍过了

1、下载地址:https://github.com/alibaba/Sentinel/releases根据自己需要下载对应版本,这里以sentinel-dashboard-1.8.0.jar为例

2、上传控制台jar包至linux服务器,启动sentinel控制台命(端口被占用请修改端口):

nohup java -Dserver.port=8081 -Dcsp.sentinel.dashboard.server=localhost:8081 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.0.jar &

3、访问后台:http://localhost:8081,用户名、密码默认都为:sentinel,也可在启动命令中自行配置

img 网关启动参数

为网关增加JVM启动参数

-Dcsp.sentinel.dashboard.server=localhost:8081
-Dproject.name=qy-tribe-gateway
-Dcsp.sentinel.api.port=8719
-Dcsp.sentinel.app.type=1

参数说明: -Dcsp.sentinel.dashboard.server:指定控制台地址和端口

-Dproject.name:在sentinel控制台中展示的项目名称

-Dcsp.sentinel.api.port:指定客户端监控 API 的端口(默认是 8719),如控制台修改规则,则会向该端口推送规则信息

-Dcsp.sentinel.app.type:从 1.6.3 版本开始,控制台支持网关流控规则管理。该启动参数会将您的服务标记为 API Gateway,在接入控制台时您的服务会自动注册为网关类型,然后您即可在控制台配置网关规则和 API 分组。

配置方案

上面的jvm启动参数,另一个方案就是在yml配置文件中配置

##Sentinel 控制台地址
spring.cloud.sentinel.transport.dashboard = localhost:8081
##客户端监控API的端口
spring.cloud.sentinel.transport.port = 8719
##取消Sentinel控制台懒加载,即项目启动即连接
sentinelspring.cloud.sentinel.eager = true

上面的dashboard地址的配置,以及transport.port配置和用启动参数的方案是一样的效果。

注意:网上有些资料说spring.cloud.sentinel.app.type = 1 可以标示为网关项目,但亲测试无效,所以必须在启动网关项目的时候,一定要加上-Dcsp.sentinel.app.type=1

img

我们发现网关项目的Sentinel菜单和普通微服务项目菜单是不一样的。小伙伴们要记住哦。

API 分组和route维度

Sentinel 1.6.0引入了Sentinel API Gateway Adapter Common模块,此模块中包含网关限流的规则自定义 API 的实体和管理逻辑:

1、GatewayFlowRule:网关限流规则,这个根据网关的自身的路由场景设计的,可以针对不同 route 或自定义的 API 分组进行限流,支持针对请求中的参数、Header、来源 IP 等进行定制化的限流。

2、ApiDefinition:用户自定义的 API 定义分组,可以看做是一些 URL 匹配的组合。比如我们可以定义一个 API 叫 myapi,请求 path 模式为 /foo/* 和 /baz/* 的都归到 myapi 这个 API 分组下面。限流的时候可以针对这个自定义的 API 分组维度进行限流

网关限流规则 GatewayFlowRule

img

字段解释如下:

1、resourceMode:API类型

规则是针对 API Gateway 的route(RESOURCEMODEROUTEID)还是用户在 Sentinel 中自定义的API 分组(RESOURCEMODECUSTOMAPINAME),默认是route。

2、resource:API名称

网关中的 route 名称或者用户自定义的API 分组名称。

3、请求属性:可选,paramItem参数限流配置

若不提供,则代表不针对参数进行限流,该网关规则将会被转换成普通流控规则;否则会转换成热点规则。

其中的字段:parseStrategy:从请求中提取参数的策略,目前支持五种模式提取来源 IP 、Host 、 Header 、 URL 参数、Cookie pattern 和 matchStrategy:为参数匹配特性预留,匹配模式,匹配串 fieldName:若提取策略选择 Header 模式或 URL 参数模式,则需要指定对应的 header 名称或 URL 参数名称。

img

4、grade:阈值类型

限流阈值类型,是按照 QPS 还是线程数

5、count:限流阈值

6、intervalSec:间隔时间

统计时间窗口,单位是秒,默认是1 秒

7、controlBehavior:流控方式

目前支持快速失败和匀速排队两种模式,默认是快速失败。

8、burst

应对突发请求时额外允许的请求数目

9、maxQueueingTimeoutMs

匀速排队模式下的最长排队时间,单位是毫秒,仅在匀速排队模式下生效。

网关流控实现原理

img

上图的整体流程如下:

1、外部请求进入API Gateway时会经过Sentinel实现的filter,其中会依次进行 路由/API 分组匹配、请求属性解析和参数组装。

2、Sentinel 会根据配置的网关流控规则来解析请求属性,并依照参数索引顺序组装参数数组,最终传入SphU.entry(res, args) 中。

3、Sentinel API Gateway Adapter Common模块向 Slot Chain 中添加了一个 GatewayFlowSlot,专门用来做网关规则的检查。

4、GatewayFlowSlot会从GatewayRuleManager中提取生成的热点参数规则,根据传入的参数依次进行规则检查。若某条规则不针对请求属性,则会在参数最后一个位置置入预设的常量,达到普通流控的效果。注意:

当通过 GatewayRuleManager 加载网关流控规则GatewayFlowRule时,无论是否针对请求属性进行限流,Sentinel底层都会将网关流控规则转化为热点参数规则ParamFlowRule,存储在GatewayRuleManager 中,与正常的热点参数规则相隔离。转换时Sentinel会根据请求属性配置,为网关流控规则设置参数索引idx,并同步到生成的热点参数规则中

熔断降级

img

Sentinel在1.8.0版本对熔断降级做了大的调整,可以定义任意时长的熔断时间,引入了半开启恢复支持。下面梳理下相关特性。

一、熔断状态

熔断有三种状态,分别为OPEN、HALF_OPEN、CLOSED

img

二、熔断策略

熔断降级支持慢调用比例、异常比例、异常数三种熔断策略

先明确下面两个概念:慢调用:指耗时大于阈值RT的请求称为慢调用,阈值RT由用户设置

最小请求数:允许通过的最小请求数量,在最小请求数量内不发生熔断,由用户设置

1.慢调用比例

img

执行逻辑

熔断(OPEN):请求数大于最小请求数并且慢调用的比率大于比例阈值则发生熔断,熔断时长为用户自定义设置。

探测(HALFOPEN):当熔断过了定义的熔断时长,状态由熔断(OPEN)变为探测(HALFOPEN)。

  • 如果接下来的一个请求小于最大RT,说明慢调用已经恢复,结束熔断,状态由探测(HALF_OPEN)变更为关闭(CLOSED)
  • 如果接下来的一个请求大于最大RT,说明慢调用未恢复,继续熔断,熔断时长保持一致

注意Sentinel默认统计的RT上限是4900ms,超出此阈值的都会算作4900ms,若需要变更此上限可以通过启动配置项-Dcsp.sentinel.statistic.max.rt=xxx来配置

2.异常比例

通过计算异常比例与设置阈值对比的一种策略。

当资源的每秒请求数大于等于最小请求数,并且异常总数占通过量的比例超过比例阈值时,资源进入降级状态。

img

执行逻辑

熔断(OPEN):当请求数大于最小请求并且异常比例大于设置的阈值时触发熔断,熔断时长由用户设置。

探测(HALFOPEN):当超过熔断时长时,由熔断(OPEN)转为探测(HALFOPEN)

  • 如果接下来的一个请求未发生错误,说明应用恢复,结束熔断,状态由探测(HALF_OPEN)变更为关闭(CLOSED)
  • 如果接下来的一个请求继续发生错误,说明应用未恢复,继续熔断,熔断时长保持一致

3.异常数

通过计算发生异常的请求数与设置阈值对比的一种策略

当资源近1分钟的异常数目超过阈值(异常数)之后会进行服务降级。注意由于统计时间窗口是分钟级别的,若熔断时长小于60s,则结束熔断状态后仍可能再次进入熔断状态。

img img

执行逻辑

熔断(OPEN):当请求数大于最小请求并且异常数量大于设置的阈值时触发熔断,熔断时长由用户设置。

探测(HALFOPEN):当超过熔断时长时,由熔断(OPEN)转为探测(HALFOPEN)

  • 如果接下来的一个请求未发生错误,说明应用恢复,结束熔断,状态由探测(HALF_OPEN)变更为关闭(CLOSED)
  • 如果接下来的一个请求继续发生错误,说明应用未恢复,继续熔断,熔断时长保持一致

规则参数说明

熔断降级DegradeRule中的属性进行说明

img

Dashboard源码Bug

上面的规格参数中有个statIntervalMs这个属性默认1000ms,统计时长无法在dashboard中进行修改。

注意:1.8版本的Sentinel dashboard降级页面有个bug,就是统计时长属性维护 丢失,有望再下一个版本中修复;也可以自行修改dashboard源码
修改/sentinel-dashboard/src/main/webapp/resources/app/views/dialog/degrade-rule-dialog.html

增加一段html代码,统计时长代码

<div class="form-group">
<label class="col-sm-2 control-label">统计时长</label>
<div class="col-sm-4">
  <div class="input-group">
  <input type='number' min="1" class="form-control highlight-border" ng-model='currentRule.statIntervalMs'
       placeholder="统计时长(ms)" />
  <span class="input-group-addon">ms</span>
  </div>
</div>
</div>

异常处理

当触发限流后页面显示的是Blocked by Sentinel: FlowException。

这个原理是DefaultBlockRequestHandler;实现了BlockRequesthandler接口

img

为了展示更加友好的限流提示, Sentinel支持自定义异常处理。

可以在GatewayCallbackManager注册回调进行定制:

setBlockHandler :注册函数用于实现自定义的逻辑处理被限流的请求,对应接口为 BlockRequestHandler 。默认实现为 DefaultBlockRequestHandler ,当被限流时会返回类似 于下面的错误信息:Blocked by Sentinel: FlowException 。

方案一:yml配置

spring.cloud.sentinel.scg.fallback.mode = response
spring.cloud.sentinel.scg.fallback.response-body = '{"code":403,"mes":"限流了"}'

上面的配置就可以达到自定义异常的效果。

方案二:注入Bean

img 总结

Sentinel1.8对降级的重新进行的改造,变化相对比较大,小伙伴们需要进行详细学习哦!!!下面老顾会介绍Sentinel的规则持久化,对源码进行相应的改造,谢谢!

img

相关文章

  • Gateway结合Sentinel1.8限流熔断管理以及自定义异

    享学课堂特邀作者:老顾转载请声明出处!!! 前言 之前老顾介绍了gateway集合sentinel1.8的整体概念...

  • Spring Cloud 系列文章

    2019-01-26springcloud(十七):服务网关 Spring Cloud GateWay 熔断、限流...

  • Gateway

    功能:Gateway提供了如下功能:路由、隔离、限流、熔断、返回、监控熔断。 路由:路由是核心功能,需要根据各种条...

  • Spring Cloud Gateway -- 熔断限流

    微服务系统中熔断限流环节,对保护系统的稳定性起到了很大的作用,作为网关,Spring Cloud Gateway也...

  • 限流算法

    前言 保障服务稳定的三大利器:熔断降级、服务限流和故障模拟。限流包括Nginx层面的限流以及业务代码逻辑上的限流。...

  • 第3篇:gateway限流和熔断

    术语解释 限流 就是限制某个请求的访问动作, 也许是访问速度, 也许直接让这个用户不能访问. 举个大家最耳熟能详而...

  • 自定义SPI使用JDK动态代理遇到UndeclaredThrow

    前言 上一篇文章我们聊了聊聊自定义SPI如何与sentinel整合实现熔断限流[https://mp.weixin...

  • 深入学习spring cloud gateway 限流熔断

    目前,Spring Cloud Gateway是仅次于Spring Cloud Netflix的第二个最受欢迎的S...

  • 今日份打卡 195/365

    技术文章限流熔断技术Sentinel

  • 熔断限流

    服务雪崩效应: 是一种因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程。 原因: 策略:

网友评论

    本文标题:Gateway结合Sentinel1.8限流熔断管理以及自定义异

    本文链接:https://www.haomeiwen.com/subject/nuxivktx.html