文章目录
简介
使用Sentinel要明白
1.先定义你需要保护的资源
这里的资源我们的那些web接口(controller的那些方法)是默认就配置的
我们也可以使用注解标志方法为我们想保护的资源
2.然后定义各种保护规则
3.违反规则后我们要不要处理这个异常,怎么处理这个异常
基础场景展示
这里我们先下一下sentinel的dashboard的jar包
使用java-jar启动
网页输入localhsot:8080就可以到sentinel登录页面
账号密码默认都为sentinel
配置一下sentinel信息
第一个设置sentinel地址
第二个是eager是让sentinel提前加载
再将服务运行,这样这些服务就进来了
这是我们controller的web接口,默认会成为sentinel管理的资源
使用注解标记资源
这样的话你发送请求
就可以在sentinel里看见我们的调用链路,可以对我们的资源进行一些控制
异常处理
比如你个资源加了流控1s只能有一个请求
如果违反,新的请求就会显示被sentinel阻止,默认的这种不符合前后端开发规则
我们一般是返回json数据
分别有流控,热点,熔断,授权和系统阻塞异常,就和我们可以定义的规则匹配
违反我们规则可以抛这个异常
这种异常又会由于定义资源的方式不同会有不同的处理机制
Web接口处理
就是controller处理
web接口底层用sentinelWebInterceptor来拦截
在我们调用前,看我们的请求是否违背规则,没有违背的话返回true放行
违背的话我们捕获异常用我们默认的BlockExecptionHadnler进行处理

而他里面的处理就是帮我们写一个提示语句
我们想要更改异常返回形式,需要自定义BlockExecptionHadnler来实现我们自己的逻辑
ok
@SentinelResource
这里我们把web接口的流控规则删了
然后流控我们的这个设为资源的方法,每秒一次
多次请求会返回springboot的默认错误页
我们所有@SentinelResource都会被一个AOP管理
这个AOP就是看一下我们的请求是否符合规则
符合就原方法直接知悉procced()
不符合抛异常,捕获后
先调用我们在注解上指定的blockHandler标注的方法
如果指定了该值就会执行该方法
没有标注,会走注解标注的fallback指定的方法
这里我们就指定blockHandler方法就行
ok
OpenFegin
远程调用好习惯,一定要射个兜底类实现fegin接口,实现方法调用失败后的兜底数据
我们的createOrder里面使用了Openfegin
这里会识别到,可以对该远程调用进行流控
实现我们的接口,对应重写的方法就是fallback逻辑,正常的话是可以从http请求中获取获取到数据的
流控规则
流控可以针对所有资源

QPS指每秒请求数(推荐)
并发线程数效果和qps差不多,配合线程池使用
单机均摊就是服务部署多个服务器,每一个的qps为1
总体就是所有的服务,1s内只能接受一个请求
流控模式

直接模式
我们默认就是直接模式
链路模式
就是根据不同的调用链进行现在
A和C都要调用B资源,只限制C而不显示A
我们在订单的controller再写一个秒杀创建订单方法
也会调用我们的createOrder的资源(就那个方法)
关闭上下文统一
因为默认会统一web上下文,就是seckill和普通的创建订单为同一个链路
这样就分割不开了,所以下设置为false
这样就可以分成两个链路
然后设置我们的入口资源,就可以做到知对应秒杀进行流控管理
关联
比如说我们读数据库和写数据库
当我们写非常大的时候,我们对读进行一个限流
实现优先写
仅在写的请求量大的情况下,限制读的操作,如果没有写就正常读无限制


读写两个方法,假设他们操作的都是同一个数据
这里你设置readDb的流控关联资源位writeDb
效果就是writeDb访问量多时候这个流控规则才会执行(至于访问量到多少我就不知道了)

流控效果
就这三种流控效果

快速失败
抛出BlockExecption异常
这里一般都是我们进行上面的异常处理,使用blockexecptionhandler进行异常处理,返回默认数据
这里可以用apipost(类似postman),使用压力测试来看我们的请求是否符号流控

Warm Up
逐渐的加热到我们的最大阈值QPS
预热的方式进行流控(冷启动)
我们会设置两个值QPS和Period
比如我们QPS设置为9 冷启动周期Period=3
我们刚开始流控就会设为QPS=9/3=3
如果我们的请求超过3,比如5,这段时间会有两个失败的
然后他就会加大其QPS变为9/3*2=6这样就可以全接受了
如果超过6同理,变为9,9为最大值,超过9都失败
这样不至于请求流量过大时候,系统还没反应过来
就像开车吧,慢慢踩油门和直接油门踩到底
匀速排队
根据你的QPS,来计算大约每ms接受多少个请求
如果你qps>1000的话,就是0.几ms,不支持这种所以qps要<=1000
设置两个参数QPS和tiemout,就是我们的请求不会直接被拒绝
而是分为拒绝和排队两种情况
比如我们qps=2
我们会每搁500ms才处理一个请求(不是上一个请求处理完直接处理下一个)
然后又最高等待时间,超过等待时间就会被拒绝(这里我不知道是直接判断出等待时间拒绝,还是等待完这个时间后才被拒绝)
这里单位为ms,1000ms也就是1s
熔断规则
熔断是针对于远程调用资源的(可能)
断路器工作原理
G调D,D不稳定,G快速返回
就防止服务雪崩
而G通过断路器来进行对D的访问
类似于电路中的开关
闭合就是访问,出现D访问慢就打开(这个有不同的打开策略),打开就连接不到D然后自己快速返回数据
我们通过半开的方式(放一个请求测试)来判断D有没有复活开觉得是否打开
就是我们请求进来
根据我们不同的策略进行打开我们的断路器
比如慢调用比例吧,你发了10个请求有7个调用(70%)很慢,就会打开断路器
比如30s,30s内所有请求都快速失败
然后等待熔断时长后会进入半开状态
释放一个请求去探测,成功的话再次关闭,失败的话还是打开

熔断策略
慢调用比例
当5s内至少有5个请求时,统计5s内,返回时间大于1s的请求标记为慢请求,如果慢请求栈所有请求比例超80%
30s内所有请求都不会请求到该服务,而是直接失败(异常处理那块会兜底回调)
那么进行熔断,30s后半开,放行一个请求(需要自己调用,不是他替我们发的)进行测试,如果是快请求就重新执行上面的规则,如果还是慢请求(大于1s)得到回应的话还是打开状态

异常比例
就是你远程调用B服务
B服务返回里面发生了异常,返回500状态码
然后你A服务就会执行fallback逻辑
其实在B中固定出现异常状态下,有无该熔断,返回的数据结果都是fallbcak的结果
但
不设置熔断会更慢,因为他需要等B失败后返回错误才执行fallbcak,设置完后,断路器打开是直接执行fallback
这里逻辑我们的慢比例其实差不多
5s内如果至少发了5个请求,统计请求中异常请求比例,超80%,熔断
30s后
放行一个请求,如果还是异常继续熔断,正常的话闭合,再执行熔断规则
异常数
和异常比例逻辑是一样的
只是将异常比例换成了异常数,只要达到异常数就进行熔断

热点规则
更细节的流控吧
环境搭建
比如通过热点参数完成这三个需求
我们的web默认不支持热点规则,需要我们自己自定义埋点
就是web默认不是资源吗,但这个资源是不用热点规则,需要自己再标明一次资源
而且这个资源名不能和web本身资源名字重复
然后给这个添加热点规则即可
热点参数
热点参数和限流
携带我们指定参数的参与流控
针对参数的流控,就是同样的参数useid=1,qps=1 1s内你发送两次请求就会失败
但是如果useid=1和userid=2的用户同时发请求的话不会流控的,针对与相同参数才会流控
突然想到这样可以反爬
如果不携带且参数命运默认值就不会参与流控
这里就实现我们的需求1了
实现需求2
点击编写之前创建的,出现高级选项点击后
把我们的6号设成100000(一个很大的值)即可(相当于不限制了)

需求3
先创建一个热点规则,商品服务不受限,但666除外
热点规则添加例外项即可
666商品QPS为0就是无法访问
fallback和blockhandler区别
@SentinelResource注解标识的资源
有block优先使用block,如果没有调用fallback
fallback相比于block最大的好处是
fallback不仅可以处理blockexecption还可以处理我们的业务异常
比如这个逻辑的算数异常
所以fallback指定的兜底回调,参数要写Throwable 指定异常
授权和系统规则
说实话,用得不多
某个资源访问可以添加授权规则
授权里面的授权应用
白名单就是只有写的这些可以访问,黑名单就是写的这些不允许访问
就是从整个系统来限流的
达到这个参数就限流
但是cpu不一定就是运行我们的程序导致利用率高,你打开别的应用也会
所以这个精确率低,用的也不多
注意
这里我们学习的sentinel没有持久化
就是我们新建的规则都会在我们重启项目后消失
之后可以配合nacos实现规则持久化