09-Sentinel限流熔断应用实践

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

检测启动过程,如图所示:

<>访问Sentinal服务


第一步:假如Sentinal启动ok,通过浏览器进行访问测试,如图所示:

第二步:登陆sentinel,默认用户和密码都是sentinel,登陆成功以后的界面如图所示:

<>Sentinel限流入门

======================================================================

<>概述


我们系统中的数据库连接池,线程池,nginx的瞬时并发,MQ消息等在使用时都会跟定一个限定的值,这本身就是一种限流的设计。限流的目的防止恶意请求流量、恶意攻击,或者防止流量超过系统峰值。

<>Sentinel集成


第一步:Sentinel 应用于服务消费方(Consumer),在消费方添加依赖如下:

com.alibaba.cloud

spring-cloud-starter-alibaba-sentinel

org.springframework.boot

spring-boot-starter-actuator

第二步:打开服务消费方配置文件application.yml,添加sentinel配置,代码如下:

spring:

cloud:

sentinel:

transport:

port: 8099 #跟sentinel控制台交流的端口,随意指定一个未使用的端口即可

dashboard: localhost:8180 # 指定sentinel控制台地址。

第三步:启动服务提供者,服务消费者,然后在浏览器访问消费者url,如图所示:

第四步:刷新sentinel 控制台,检测服务列表,如图所示:

Sentinel的控制台其实就是一个SpringBoot编写的程序,我们需要将我们的服务注册到控制台上,即在微服务中指定控制台的地址,并且还要在消费端开启一个与sentinel控制台传递数据端的端口,控制台可以通过此端口调用微服务中的监控程序来获取各种信息。

<>Sentinel限流快速入门


我们设置一下指定接口的流控(流量控制),QPS(每秒请求次数)单机阈值为1,代表每秒请求不能超出1次,要不然就做限流处理,处理方式直接调用失败。

第一步:选择要限流的链路,如图所示:

第二步:设置限流策略,如图所示:

第三步:反复刷新访问消费端端服务,检测是否有限流信息输出,如图所示:

<>Sentinel流控规则分析

========================================================================

<>阈值类型分析


  • QPS(Queries Per Second):当调用这个api的时,QPS达到单机阈值时,就会限流。

  • 线程数:当调用这个api的时,线程数达到单机阈值时,就会限流。

<>设置限流模式


Sentinel的流控模式代表的流控的方式,默认【直接】,还有关联,链路。

直接模式:

Sentinel默认的流控处理就是【直接->快速失败】。

![在这里插入图片描述]( )

链路模式

链路模式只记录指定链路入口的流量。也就是当多个服务对指定资源调用时,假如流量超出了指定阈值,则进行限流。被调用的方法用@SentinelResource进行注解,然后分别用不同业务方法对此业务进行调用,假如A业务设置了链路模式的限流,在B业务中是不受影响的。例如现在设计一个业务对象,代码如下(为了简单,可以直接写在启动类内部):

@Service

public class ConsumerService{

@SentinelResource("doGetResource")

public String doGetResource(){

return "doGetResource";

}

}

接下来我们在/consumer/doRestEcho1对应的方法中对ConsumerService中的doGetResource方法进行调用(应用consumerService对象之前,要先在doRestEcho01方法所在的类中进行consumerService值的注入)。例如:

@GetMapping("/consumer/doRestEcho1")

public String doRestEcho01() throws InterruptedException {

consumerService.doGetResource();

//Thread.sleep(200);

String url="http://localhost:8081/provider/echo/"+server;

//远程过程调用-RPC

return restTemplate.getForObject(url,String.class);//String.class调用服务响应数据类型

}

其路由规则配置如下:

说明,流控模式为链路模式时,假如是sentinel 1.7.2以后版本,Sentinel Web过滤器默认收敛所有URL的入口上下文(sentinel_spring_web_context),因此互连限流不生效,需要在application.yml添加如下语句来关闭URL PATH聚合(了解,可以自己尝试):

sentinel:

web-context-unify: false

修改配置以后,重新sentinel,并设置链路流控规则,然后再频繁对链路/consumer/doRestEcho1进行访问,检测是否会出现500异常。

<>设计限流效果(了解)


此模块做为课后了解内容,感兴趣自学即可.

快速失败

流量达到指定阀值,直接返回报异常。(类似路前方坍塌,后面设定路标,让后面的车辆返回)

WarmUp (预热)

WarmUp也叫预热,根据codeFactor(默认3)的值,(阀值/codeFactor)为初始阈值,经过预热时长,才到达设置的QPS的阈值,假如单机阈值为100,系统初始化的阈为 100/3 ,即阈值为33,然后过了10秒,阈值才恢复到100。这个预热的应用场景,如:秒杀系统在开启的瞬间,会有很多流量上来,很有可能把系统打死,预热方式就是把为了保护系统,可慢慢的把流量放进来,慢慢的把阈值增长到设置的阈值。例如:

排队等待

从字面上面就能够猜到,匀速排队,让请求以均匀的速度通过,阈值类型必须设成QPS,否则无效。比如有时候系统在某一个时刻会出现大流量,之后流量就恢复稳定,可以采用这种排队模式,大流量来时可以让流量请求先排队,等恢复了在慢慢进行处理,例如:

<>小节面试分析


  • Sentinel是什么?(阿里推出一个流量控制平台,防卫兵)

  • 类似Sentinel的产品你知道有什么?(hystrix-一代微服务产品)

  • 你了解哪些限流算法?(计数器、令牌桶、漏斗算法,滑动窗口算法,...)

  • Sentinel 默认的限流算法是什么?(滑动窗口算法)

  • 你了解sentinel中的阈值应用类型吗?(两种-QPS,线程数)

  • Sentinel 限流规则中默认有哪些限流模式?(直连,关联,链路)

  • Sentinel的限流效果有哪些?(快速失败,预热,排队)

  • Sentinel 为什么可以对我们的业务进行限流,原理是什么?

我们在访问web应用时,在web应用内部会有一个拦截器,这个拦截器会对请求的url进行拦截,拦截到请求以后,读取sentinel 控制台推送到web应用的流控规则,基于流控规则对流量进行限流操作。

<>Sentinel降级入门

======================================================================

<>概述


除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积。

Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)。

<>准备工作


修改ConumserController 类中的doRestEcho01方法,假如没有创建即可,基于此方法演示慢调用过程下的限流,代码如下:

//AtomicLong 类支持线程安全的自增自减操作

private AtomicLong atomicLong=new AtomicLong(1);

@GetMapping("/consumer/doRestEcho1")

public String doRestEcho01() throws InterruptedException {

//consumerService.doGetResource();

//获取自增对象的值,然后再加1

long num=atomicLong.getAndIncrement();

if(num%2==0){//模拟50%的慢调用比例

Thread.sleep(200);

}

String url="http://localhost:8081/provider/echo/"+server;

//远程过程调用-RPC

return restTemplate.getForObject(url,String.class);//String.class调用服务响应数据类型

}

<>Sentinel降级入门


第一步:服务启动后,选择要降级的链路,如图所示:

第二步:选择要降级的链路,如图所示:

这里表示熔断策略为慢调用比例,表示链路请求数超过3时,假如平均响应时间假如超过200毫秒的有50%,则对请求进行熔断,熔断时长为10秒钟,10秒以后恢复正常。

第三步:对指定链路进行刷新,多次访问测试,假如出现了降级熔断,会出现如下结果:

我们也可以进行断点调试,在DefaultBlockExceptionHandler中的handle方法内部加断点,分析异常类型,假如异常类型为DegradeException则为降级熔断。

<>Sentinel 异常处理


系统提供了默认的异常处理机制,假如默认处理机制不满足我们需求,我们可以自己进行定义。定义方式上可以直接或间接实现BlockExceptionHandler接口,并将对象交给spring管理。

@Component

public class ServiceBlockExceptionHandler implements BlockExceptionHandler {

@Override

public void handle(HttpServletRequest request, HttpServletResponse response,BlockException e) throws Exception {

//response.setStatus(601);

//设置响应数据的编码

response.setCharacterEncoding("utf-8");

//告诉客户端要响应的数据类型以及客户端以什么编码呈现数据

response.setContentType("text/html;charset=utf-8");

PrintWriter pw=response.getWriter();

Map<String,Object> map=new HashMap<>();

if(e instanceof DegradeException){//降级、熔断

map.put("status",601);

map.put("message", "服务被熔断了!");

}else if(e instanceof FlowException){

map.put("status",602);

map.put("message", "服务被限流了!");

}else{

map.put("status",603);

map.put("message", "Blocked by Sentinel (flow limiting)");

}

//将map对象转换为json格式字符串

String jsonStr=new ObjectMapper().writeValueAsString(map);

pw.println(jsonStr);

pw.flush();

}

}

<>小节面试分析


  • 何为降级熔断?(让外部应用停止对服务的访问,生活中跳闸,路障设置-此路不通)

  • 为什么要进行熔断呢?(平均响应速度越来越慢或经常出现异常,这样可能会导致调用链堆积,最终系统崩溃)

  • Sentinel中限流,降级的异常父类是谁?(BlockException)

  • Sentinel 出现降级熔断时,系统底层抛出的异常是谁?(DegradeException)

  • Sentinel中异常处理接口是谁?(BlockExceptionHandler)

  • Sentinel中异常处理接口下默认的实现类为? (DefaultBlockExceptionHandler)

  • 假如Sentinel中默认的异常处理规则不满足我们的需求怎么办?(自己定义)

  • 我们如何自己定义Sentinel中异常处理呢?(直接或间接实现BlockExceptionHandler )

<>Sentinel降级策略分析(重点)

============================================================================

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

<>慢调用比例


慢调用指耗时大于阈值RT(Response Time)的请求称为慢调用,阈值RT由用户设置。其属性具体含义说明如下:

慢调用逻辑中的状态分析如下:

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

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

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

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

<>异常比例


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

异常比例中的状态分析如下:

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

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

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

<>异常数量


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

基于异常数的状态分析如下:

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

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

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

<>小节面试分析


  • Sentinel 降级熔断策略有哪些?(慢调用,异常比例,异常数)

  • Sentinel 熔断处理逻辑中的有哪些状态?(Open,HalfOpen,Closed)

  • Sentinel 对服务调用进行熔断以后

【一一帮助Java学习,所有资源获取处一一】

①互联网大厂面试真题解析

②进阶开发核心学习笔记

③全套讲解视频

④实战项目源码讲义

处于什么状态?(熔断打开状态-Open)

  • Sentinel 设置的熔断时长到期以后,Sentinel的熔断会处于什么状态?(探测-HalfOpen,假如再次访问时依旧响应时间比较长或依旧有异常,则继续熔断)

  • Sentinel 中的熔断逻辑恢复正常调用以后,会出现什么状态?(熔断关闭-closed)

<>Sentinel热点规则分析(重点)

============================================================================

<>概述


何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top N 数据,并对其访问进行限制。比如:

  • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制。

  • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制。

热点参数限流会统计传入参数中的热点数据,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。其中,Sentinel会利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。

4.8.2 快速入门

第一步:定义热点业务代码,如图所示:

//http://ip:port/consumer/doFindById?id=10

@GetMapping("/consumer/findById")

@SentinelResource("res")

public String doFindById(@RequestParam("id") Integer id){

return "resource id is "+id;

}

第二步:服务启动后,选择要限流的热点链路,如图所示:

![在这里插入图片描述]( )

热点规则的限流模式只有QPS模式(这才叫热点)。参数索引为@SentinelResource注解的方法参数下标,0代表第一个参数,1代表第二个参数。单机阈值以及统计窗口时长表示在此窗口时间超过阈值就限流。

第四步:多次访问热点参数方法,前端会出现如下界面,如图所示:

然后,在后台出现如下异常表示限流成功。

com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException: 2

其中,热点参数其实说白了就是特殊的流控,流控设置是针对整个请求的;但是热点参数他可以设置到具体哪个参数,甚至参数针对的值,这样更灵活的进行流控管理。

一般应用在某些特殊资源的特殊处理,如:某些商品流量大,其他商品流量很正常,就可以利用热点参数限流的方案。

总结

对于面试还是要好好准备的,尤其是有些问题还是很容易挖坑的,例如你为什么离开现在的公司(你当然不应该抱怨现在的公司有哪些不好的地方,更多的应该表明自己想要寻找更好的发展机会,自己的一些现实因素,比如对于我而言是现在应聘的公司离自己的家更近,又或者是自己工作到达了迷茫期,想跳出迷茫期等等)

Java面试精选题、架构实战文档

整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断!

S模式(这才叫热点)。参数索引为@SentinelResource注解的方法参数下标,0代表第一个参数,1代表第二个参数。单机阈值以及统计窗口时长表示在此窗口时间超过阈值就限流。

第四步:多次访问热点参数方法,前端会出现如下界面,如图所示:

然后,在后台出现如下异常表示限流成功。

com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException: 2

其中,热点参数其实说白了就是特殊的流控,流控设置是针对整个请求的;但是热点参数他可以设置到具体哪个参数,甚至参数针对的值,这样更灵活的进行流控管理。

一般应用在某些特殊资源的特殊处理,如:某些商品流量大,其他商品流量很正常,就可以利用热点参数限流的方案。

总结

对于面试还是要好好准备的,尤其是有些问题还是很容易挖坑的,例如你为什么离开现在的公司(你当然不应该抱怨现在的公司有哪些不好的地方,更多的应该表明自己想要寻找更好的发展机会,自己的一些现实因素,比如对于我而言是现在应聘的公司离自己的家更近,又或者是自己工作到达了迷茫期,想跳出迷茫期等等)

[外链图片转存中...(img-ok7DE7GW-1717908919691)]

Java面试精选题、架构实战文档

整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断!

相关推荐
bohu832 天前
sentinel学习笔记7-熔断降级
笔记·sentinel·熔断降级·degradeslot·circuitbreaker
suweijie7682 天前
SpringCloudAlibaba | Sentinel从基础到进阶
java·大数据·sentinel
向阳12183 天前
sentinel来源访问控制(黑白名单)
java·sentinel
bohu833 天前
sentinel学习笔记1-为什么需要服务降级
笔记·学习·sentinel·滑动窗口
一个儒雅随和的男子3 天前
微服务详细教程之nacos和sentinel实战
微服务·架构·sentinel
bohu833 天前
sentinel学习笔记5-资源指标数据统计
笔记·sentinel·statisticslot
bohu834 天前
Sentinel 学习笔记3-责任链与工作流程
笔记·sentinel·责任链·processorslot
mengml_smile6 天前
Sentinel一分钟
java·开发语言·sentinel
LightOfNight13 天前
【Sentinel Go】新手指南、流量控制、熔断降级和并发隔离控制
开发语言·golang·sentinel
XMYX-013 天前
使用 Kubernetes 部署 Redis 主从及 Sentinel 高可用架构(未做共享存储版)
redis·kubernetes·sentinel