spring cloud alibaba meetup(Spring Cloud Alibaba组件之Sentinel)
目录
一 引入Sentinel学习
二 Sentinel入门
三 搭建SentinelDashboard
四 Springboot项目接入Sentinel
五 接入限流埋点
六 限流配置
七 熔断降级
八 熔断降级Spring Cloud示例
九 黑白名单(授权规则)
十 持久化
十一Spring Cloud Alibaba Sentinel三种保护应用方式
一 引入Sentinel学习
提起Spring Cloud的限流降级组件 ,一般首先想到的是Netflix的Hystrix 。
不过就在2018年底 ,Netflix宣布不再积极开发Hystrix ,该项目将处于维护模式 。官方表示1.5.18 版本的Hystrix已经足够稳定 ,可以满足Netflix 现有应用的需求 ,所以接下来其会把焦点转向对于自适应的实现 ,更多关注对应用程序的实时性能做出响应 。对于新应用的熔断需求 ,将采用其它项目实现 ,Netflix推荐了Resilience4j 。
作为Spring Cloud Netflix重要套件 ,Hystrix已经成为保障微服务稳定性的首选应用 。其实除了Netflix和Resilience4j ,限流降级还有一个新的选择 ,就是阿里巴巴的Sentinel组件 。
二 Sentinel入门
官方文档:https://sentinelguard.io/zh-cn/docs/introduction.html
1 什么是Sentinel?
1.1 问题:
随着微服务的流行 ,服务与服务之间的调用稳定性变得越来越重要;
1 、当服务访问量达到一定程度,流量扛不住的时候 ,该如何处理?(限流)
2 、服务之间相互依赖 ,当服务B出现响应时间过长,影响到服务A的响应(A调用B) ,进而产生连锁反应 ,直至影响整个依赖链上的所有服务(雪崩) ,该如何处理?(熔断降级)
这是分布式 、微服务开发不可避免的问题 。
1.2 Sentinel是什么?
Sentinel(分布式系统的流量防卫兵)是阿里开源的一套用于服务容错的综合性解决方案 ,随着微服务的流行 ,服务和服务之间的稳定性变得越来越重要 。它以流量为切入点 ,从流量控制 ,熔断降级 ,系统负载保护等多个维度来保护服务的稳定性 。
2Sentinel的特征
1 、丰富的应用场景:Sentinel承接了阿里巴巴近10年的双十一大促流量的核心场景 ,例如秒杀(即突发流量控制在系统容量可以承受的范围) ,消息削峰填谷 。集群流量控制 ,实时熔断下游不可用应用等 。
2 、完备的实时监控:Sentinel提供了实时的监控功能 。通过控制可以看到接入应用的单台机器秒级数据 ,甚至500台以下规模的集群的汇总运行情况。
3 、广泛的开源生态:Sentinel提供开箱即用的与其他开源框架/库的整合模块,例如与SpringCLoud ,Dubbo ,gRPC的整合 。只需要进入相应的依赖并进行简单的配置即可快速地接入Sentinel 。
4 、完善的SPI扩展点:Sentinel提供简单易用,完善的SPI扩展接口。您可以通过实现扩展接口来快速地定制逻辑 。例如定制规则管理 ,适配动态数据源等 。
3Sentinel组成
Sentinel分为两个部分 ,具体如下:
1 、核心库(Java客户端):不依赖任何框架/库 ,能够运行于所有Java运行时环境 ,同时对Dubbo/Spring Cloud等框架也有比较好的支持(你的微服务程序 ,可以直接添加sentinel.jar包) 。
2 、控制台(Dashboard)基于Spring Boot开发 ,打包后可以直接运行 ,不需要额外的Tomcat等应用容器(因为控制台是使用springboot开发 ,springboot内嵌了tomcat容器) 。
这里我们先学习一下控制台的使用方式 。
三 搭建SentinelDashboard
将应用接入Sentinel ,最好搭建Sentinel控制台 ,可以在控制台上配置规则 。
Dashboard是Alibaba写好的SpringBoot程序 ,我们直接下载启动即可.
1 下载SentinelDashboard
下载地址:https://github.com/alibaba/Sentinel/releases
2 启动控制台
我们可以在Linux系统或者Windows系统启动Sentinel控制台 ,这里是直接在Windows上启动
3 访问控制台
启动Sentinel Dashboard通过地址和端口号控制台
输入默认用户名和密码(sentinel/sentinel) ,之后控制台可以看到sentinel-dashboard监控的指标 。
如果要自定义用户名和密码 ,在启动命令加上设置用户名和密码参数即可,如下:
注意:默认启动后 ,控制台上没有任何服务被注册到控制台 。在启动控制台时 ,可以通过参数设置将控制台本身注册到控制台上
我们可以看到控制台自身的服务已经注册到了控制台上 。
默认情况下 ,Sentinel Dashboard 中的增加的配置规则是存储在内存中 ,重启后就会丢失;
Sentinel 会在客户端首次调用的时候进行初始化 ,开始向控制台发送心跳包 ,所以要确保客户端有访问量;
Sentinel Dashboard是一个独立的web应用(springboot开发的) ,可以接受客户端(微服务)的连接 ,然后与客户端(微服务)之间进行通讯 ,他们之间使用http协议进行通讯 。
四 Springboot项目接入Sentinel
1 添加Sentinel依赖
项目其他关联的部分配置
2 配置文件信息
配置文件说明:
spring.cloud.sentinel.transport.port端口配置会在应用对应的机器上启动一个Http Server ,该 Server会与Sentinel控制台做交互 。比如Sentinel控制台添加了1个限流规则 ,会把规则数据 push给这个Http Server接收 ,Http Server 再将规则注册到Sentinel 中。
spring.cloud.sentinel.transport.port:指定应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer 。
客户端需要添加jar包
spring-cloud-starter-alibaba-sentinel依赖已经包含了上面的依赖 ,所以上面的依赖不需要再单独添加 。
3 新建控制类
4 启动项目 ,访问控制类接口
http://localhost:8081/demo/message
五 接入限流埋点
1 HTTP埋点
Sentinel starter 默认为所有的HTTP服务提供了限流埋点,如果只想对HTTP服务进行限流 ,那么只需要添加依赖 ,无需修改代码。(简单说就是所有的 controller 层接口默认提供限流埋点)
2 自定义埋点
如果需要对某个特定的方法进行限流或降级 ,可以通过 @SentinelResource 注解来完成限流的埋点 ,示例代码如下:
六 限流配置
1 认识流控规则
资源名:一般是我们的请求路径url或注解@SentinelResource的value属性值;
针对来源:来自于哪个应用;
阈值类型:分为QPS(每秒查询数)或并发线程数;
单机阈值:单个节点的QPS或线程数阈值;
是否集群:被请求的服务是否集群部署;
流控模式:
直接 ,就是直接对该资源进行控制; 关联 ,关联某一个资源(/app2) ,被关联的资源/app2达到阈值 ,则限制当前资源/test路径的访问; 链路 ,记录指定链路上的流量;流控效果:
快速失败 ,直接限制; Warm Up ,根据coldFactor(默认为3)的值 ,从阈值/coldFactor,经过预热的时长 ,才达到设置的QPS阈值 ,比如设置QPS阈值为100,那么100/3 =33 ,用33作为最初的阈值 ,然后在10秒到达100后再开始限流; 排队等待 ,在QPS阈值到达后 ,新的请求就等待 ,直到超时 ,可以适用于突发流量的请求;2 直接限流
流量控制 ,其原理是监控应用流量的QPS(每秒查询率) 或并发线程数等指标 ,当达到指定的阈值时 ,对流量进行控制 ,以避免被瞬时的流量高峰冲垮 ,从而保障应用的高可用性 。
2.1 添加限流规则
在Sentinel dashboard配置/demo/message的限流规则 ,每秒最多允许访问一次,超出访问 ,就会限流 ,返回默认的提示:Blocked by Sentinel (flow limiting)
说明:
QPS(Query Per Second),QPS 其实是衡量吞吐量(Throughput)的一个常用指标 ,就是说服务器在一秒的时间内处理了多少个请求 —— 我们通常是指 HTTP 请求 ,显然数字越大代表服务器的负荷越高 、处理能力越强 。作为参考 ,一个有着简单业务逻辑(包括数据库访问)的程序在单核心运行时可以提供 50 - 100 左右的 QPS ,即每秒可以处理 50 - 100 个请求 。
TPS(Transaction Per Second) 每秒钟系统能够处理的事务的数量 。
QPS(TPS):每秒钟 request/事务的数量 (此处 / 表示 或的意思)
并发数: 系统同时处理的request/事务数 (此处 / 表示 或的意思)
响应时间RT(Response Time): 一般取平均响应时间
理解了上面三个要素的意义之后 ,就能推算出它们之间的关系:
QPS(TPS)= 并发数/平均响应时间 并发数除以平均响应时间
2.2 快速访问 ,查看效果
打开浏览器频繁访问(使用F5 刷新浏览器访问)(1秒内必须超过一次请求)
3 关联限流
3.1 新建controller类
3.2 新建关联限流规则
这里关联的资源是 /related/b(即保护接口b) ,上图设置表示:如果接口b的QPS达到单机阈值“1 ” ,则开始通过限流接口“a ” ,从而保护“b ” 。
3.3 测试
测试时 ,可以快速的使用F5 来刷新b ,快速的切换到a ,F5再刷新a,发现a被限流了
当接口b发送并发流量QPS值小于1时 ,接口“a ”可以正常访问 。
关联限流规则是保护重要服务的措施 ,即:如果某个服务(b)达到临界值,则代表b资源不足 ,需要先限制不重要的服务(a) ,防止服务(a)继续调用服务(b) 。
4 链路限流
4.1 新建服务类
4.2 新建controller类
4.3 新增配置文件application.yml
4.4 新建链路流控规则
4.5 测试链路流控规则
访问接口a ,当超过QPS设定值1 ,则接口“a ”被限流 ,接口b同样调用方法 ,但是不会被限流 。
限流时会出现500错误
七 熔断降级
上面实现了实现接口限流 。但是在实际应用中 ,当我们的某个服务接口出现了问题 ,不能正常提供服务 ,或者该接口响应速度很慢 ,导致调用方大量请求堆积 ,此时需要将该接口降级服务,从而保护调用该接口的服务(消费者) ,快速返回降级结果 ,防止因为过多的服务等待该接口的返回,导致系统雪崩 。
熔断策略
1 Sentinel熔断策略:慢调用比例
慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值 ,需要设置允许的慢调用 RT(即最大的响应时间) ,请求的响应时间大于该值则统计为慢调用 。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目 ,并且慢调用的比例大于阈值 ,则接下来的熔断时长内请求会自动被熔断 。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态) ,若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断 ,若大于设置的慢调用 RT 则会再次被熔断。
1.1 名词解释:
调用:一个请求发送到服务器 ,服务器给与响应 ,一个响应就是一个调用
RT(Response Time):响应时间 ,指系统对请求作出响应的时间
慢调用:当调用的时间(响应的实际时间)>设置的RT时 ,这个调用叫做慢调用
慢调用比例:在所有调用中 ,慢调用占有实际的比例 ,= 慢调用次数 / 总调用次数
比例阈值:自己设定的 , 慢调用次数 / 总调用次数>=比例阈值
阈值(threshold value)又叫临界值 ,比如:水变成冰和水蒸气
统计时长:时间的判断依据
最小请求数:设置的调用最小请求数
1.2 状态转换
进入熔断状态判断依据:当统计时长内 ,实际请求数目大于最小请求数目,慢调用比例> 比例阈值 ,进入熔断状态
熔断状态:在接下来的熔断时长内请求会自动被熔断
探测恢复状态:熔断时长结束后进入探测恢复状态
结束熔断:在探测恢复状态 ,如果接下来的一个请求响应时间小于设置的慢调用 RT ,则结束熔断;否则 ,继续熔断 ,等待进入探测恢复状态
1.3 实例测试
1.3.1 新建controller类
1.3.2 配置熔断规则
注意:Sentinel默认统计的RT上限是4900ms ,超出此阈值的都会算作4900ms ,若需要变更此上限可以通过启动配置项-Dcsp.sentinel.statistic.max.rt=xxx来配置 。
熔断推测:
在1000毫秒 ,也就是1秒内 ,如果发送到/polly 的请求数数量大于1 ,并且在这些请求中 ,所有请求的响应时长(因为比例阈值为1 ,所以是所有的请求响应时长)都大于500毫秒,也就是都大于0.5秒的时候 ,进入熔断状态 。
1.3.3 使用浏览器测试熔断
2 Sentinel熔断策略:异常比例
异常比例:当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目 ,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态) ,若接下来的一个请求成功完成(没有错误)则结束熔断 ,否则会再次被熔断 。异常比率的阈值范围是[0.0, 1.0] ,代表 0% - 100% 。
2.1 新建controller类
2.2 配置熔断规则
2.3 使用浏览器测试熔断
3 Sentinel熔断策略:异常数
异常数 (ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断 。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态) ,若接下来的一个请求成功完成(没有错误)则结束熔断 ,否则会再次被熔断 。
3.1 配置熔断规则
3.2 使用浏览器测试熔断
八 熔断降级Spring Cloud示例
1 新建服务提供者工程
1.1 添加nacos依赖
1.2 添加配置文件
1.3 新建controller类
1.4 启动服务提供者
2 新建服务消费者工程
2.1 添加主要依赖
2.2 添配置文件
2.3 新建feign接口
2.4 新建FallbackFactory类
2.5 新建controller类
2.6 启动服务消费者 ,使用浏览器进行测试
http://localhost:8082/hello/jack
可以正常访问
停止服务提供者 ,降级起作用了
九 黑白名单(授权规则)
很多时候 ,我们需要根据调用来源来判断该次请求是否允许放行 ,这时候可以使用Sentinel 的来源访问控制(黑白名单控制)的功能 。来源访问控制根据资源的请求来源(origin)限制资源是否通过 。
若配置白名单则只有请求来源位于白名单内时才可通过; 若配置黑名单则请求来源位于黑名单时不通过 ,其余的请求通过 。1 配置规则
来源访问控制规则(AuthorityRule)非常简单 ,主要有以下配置项:
resource:资源名,即限流规则的作用对象 。
limitApp:对应的黑名单/白名单 ,不同origin 则用“ , ” 分隔,如 appA ,appB 。
strategy:限制模式 ,AUTHORITY_WHITE 为白名单模式 ,AUTHORITY_BLACK 为黑名单模式 ,默认为白名单模式 。
2 新建controller类
3 新增接口来源类
流控应用:Sentinel提供了RequestOriginParser来处理接口来源 。
4 配置白名单规则(黑名单的作用与白名单相反)
5 启动应用 ,使用浏览器访问
只有当参数值与规则中配置的流控应用相等时 ,才能正常访问
十 持久化
默认情况下 ,sentinel-dashboard 中的规则是存储在微服务内存中 ,重启后就会丢失 。
持久化指的是 ,一旦重启sentinel的微服务 ,sentinel配置的各种规则不会丢失。
1Sentinel结合Nacos持久化配置
Sentinel持久化支持的类型有 ,详情见:
1.1 添加依赖
1.2 添加配置文件
1.3登陆nacos ,新建配置规则sentinel-datasource-nacos.json
配置说明:
resource:资源名称
limitApp:来源应用
grade:阀值类型,0---线程数 ,1---QPS
count:单机阀值
strategy:流控模式 ,0---直接 ,1---关联 ,2---链路
controlBehavior:流控效果 ,0---快速失败 ,1---warmUp ,2---排队等待
clusterMode:是否集群
参考官方文档:https://sentinelguard.io/zh-cn/docs/flow-control.html
注意:
此时如果是Nacos集群 ,每个节点务必要配置到同一个数据库上 。并且保证每个节点都可用。如果有的节点宕掉了可能会导致配置持久化失败 。 部署在nacos上的配置文件的名字并没有太多要求 ,只需要跟微服务项目中yml文件中配置的dataId一致即可 。1.4 查看sentinel流控规则 ,并测试访问
将配置规则持久化进Nacos保存 ,重启使用sentinel的微服务 ,只要访问一下基于流控规则的url,流控规则就会显示在sentinel的界面上 。此时 ,持久化生效 ,只要Nacos里面的配置不删除,针对微服务上Sentinel上的流控规则持续
有效 。
1.5 问题
目前有一个小问题 ,当我们在sentinel dashboard控制台更新或者新加规则 ,nacos里面的规则并不能得到更新;
2 其他限流规则
2.1Sentinel熔断降级规则说明
参考地址:https://sentinelguard.io/zh-cn/docs/circuit-breaking.html
2.2Sentinel【热点规则】热点参数规则
参考地址:https://sentinelguard.io/zh-cn/docs/parameter-flow-control.html
2.3Sentinel系统规则
参考地址:https://sentinelguard.io/zh-cn/docs/origin-authority-control.html
十一Spring Cloud Alibaba Sentinel三种保护应用方式
1 直接拦截我们所有controller的请求url路径
Sentinel为springboot程序提供了一个starter依赖 ,由于sentinel starter依赖默认情况下就会为所有的HTTP服务提供限流埋点 ,所以在springboot 中的Controller都可以受到Sentinel的保护;
只需为应用添加 spring-cloud-starter-alibaba-sentinel依赖 ,所有的HTTP接口都能获得Sentinel保护 ,当然 ,我们还需要为Sentinel配置保护的规则;底层通过一个拦截器对请求url进行拦截:
com.alibaba.csp.sentinel.adapter.spring.webmvc.SentinelWebInterceptor
可以通过如下配置关闭对微服务的保护:
#关闭sentinel对controller的url的保护
spring.cloud.sentinel.filter.enabled=false
2 通过代码方式保护应用(只是了解)
这种方式就是手动写代码 ,稍微比较繁琐
3 通过@SentinelResource(value = "app")注解保护应用
属性
作用
是否必须
value
资源名称
是
entryType
entry类型 ,标记流量的方向 ,取值IN/OUT ,默认是OUT
否
blockHandler
处理BlockException的函数名称 。函数要求:
1. 必须是public
2.返回类型与原方法一致
3. 参数类型需要和原方法相匹配 ,并在最后加BlockException类型的参数 。
4. 默认需和原方法在同一个类中 。若希望使用其他类的函数,可配置blockHandlerClass ,并指定blockHandlerClass里面的方法 。否
blockHandlerClass
存放blockHandler的类 。对应的处理函数必须static修饰 ,否则无法解析,其他要求:同blockHandler 。
否
fallback
用于在抛出异常的时候提供fallback处理逻辑 。fallback函数可以针对所有类型的异常(除了exceptionsToIgnore里面排除掉的异常类型)进行处理 。函数要求:
1. 返回类型与原方法一致
2. 参数类型需要和原方法相匹配 ,Sentinel 1.6开始 ,也可在方法最后加Throwable类型的参数。
3.默认需和原方法在同一个类中 。若希望使用其他类的函数 ,可配置fallbackClass ,并指定fallbackClass里面的方法 。否
fallbackClass
存放fallback的类。对应的处理函数必须static修饰 ,否则无法解析 ,其他要求:同fallback 。
否
defaultFallback
用于通用的 fallback 逻辑 。默认fallback函数可以针对所有类型的异常(除了exceptionsToIgnore里面排除掉的异常类型)进行处理 。若同时配置了 fallback 和 defaultFallback ,以fallback为准 。函数要求:
1. 返回类型与原方法一致
2. 方法参数列表为空 ,或者有一个Throwable类型的参数 。
3. 默认需要和原方法在同一个类中 。若希望使用其他类的函数 ,可配置fallbackClass ,并指定fallbackClass里面的方法 。否
exceptionsToIgnore
指定排除掉哪些异常 。排除的异常不会计入异常统计 ,也不会进入fallback逻辑 ,而是原样抛出 。
否
exceptionsToTrace
需要trace的异常
Throwable
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!