第四次课:基于Sentinel的服务限流及熔断
分类: springboot 专栏: 新版springcloud分布式学习 标签: 限流和熔断
2024-04-27 10:16:47 905浏览
Sentinel简介
Sentinel是阿里巴巴出品的面向分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护等多个维度来保障微服务的稳定性。
主页地址: https://sentinelguard.io/zh-cn/docs/introduction.html
资源级别做限流
什么是限流:拿旅游景点举例子
针对某个微服务的某个接口,属于资源级别的限流
基本使用
依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.7</version>
</dependency>
定义资源——抛出异常的方式
// 1.5.0 版本开始可以直接利用 try-with-resources 特性
try (Entry entry = SphU.entry("storge")) {
// 被保护的逻辑
//商品id和数量 这里就只模拟了 业务代码省略
return "success";
} catch (BlockException ex) {
// 处理被流控的逻辑
return "系统繁忙,请稍后重试";
}
定义规则-编码方式
//定义规则每秒最多只能通过 2个请求。
@PostConstruct
private static void initFlowRules(){
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("storge");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// Set limit QPS to 2
rule.setCount(2);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
定义规则-sentinel控制台操作
https://github.com/alibaba/Sentinel/
去下载控制台jar,然后启动项目
java -Dserver.port=9000 -jar sentinel-dashboard-1.8.7.jar
让微服务项目跟sentinel关联起来
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.8.7</version>
</dependency>
# 设置sentinel控制台的主机地址和端口
-Dcsp.sentinel.dashboard.server=localhost:9000
# 设置本地应用在sentinel控制台中的名称
-Dproject.name=StrogeSentinel
页面上新建流控规则
定义资源——返回布尔值的方式
SphO 提供 if-else 风格的 API。用这种方式,当资源发生了限流之后会返回 false,这个时候可以根据返回值,进行限流之后的逻辑处理。示例代码如下:
// 资源名可使用任意有业务语义的字符串
if (SphO.entry("自定义资源名")) {
// 务必保证finally会被执行
try {
/**
* 被保护的业务逻辑
*/
} finally {
SphO.exit();
}
} else {
// 资源访问阻止,被限流或被降级
// 进行相应的处理操作
}
定义资源——异步调用的方式
Sentinel 支持异步调用链路的统计。在异步调用中,需要通过 SphU.asyncEntry(xxx) 方法定义资源,并通常需要在异步的回调函数中调用 exit 方法。以下是一个简单的示例:
try {
AsyncEntry entry = SphU.asyncEntry(resourceName);
// 异步调用.
doAsync(userId, result -> {
try {
// 在此处处理异步调用的结果.
} finally {
// 在回调结束后 exit.
entry.exit();
}
});
} catch (BlockException ex) {
// Request blocked.
// Handle the exception (e.g. retry or fallback).
}
写一个异步调用接口的步骤
@EnableAsync
public class StorgeApp {
@Async
String doAsync(){
return "success";
}
@GetMapping
public String updateStorge(){
try {
AsyncEntry entry = SphU.asyncEntry("storge3");
try {
// 在此处处理异步调用的结果.
return doAsync();
} finally {
// 在回调结束后 exit.
entry.exit();
}
} catch (BlockException ex) {
return "系统繁忙,请稍后重试";
}
}
定义资源——注解的方式
Sentinel 支持通过 @SentinelResource 注解定义资源并配置 blockHandler 和 fallback 函数来进行限流之后的处理。示例:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>x.y.z</version>
</dependency>
@Configuration
public class SentinelAspectConfiguration {
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
}
@GetMapping
@SentinelResource(value = "storge4",blockHandler = "handler")
public String updateStorge(){
return "success";
}
public String handler(BlockException e){
e.printStackTrace();
return "系统繁忙,请稍后重试";
}
整合springcloud-alibaba
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2022.0.0.0-RC1</version>
</dependency>
@RestController
@RequestMapping("/stroge")
public class StrogeController {
@GetMapping
@SentinelResource(value = "storge",blockHandler = "storgeBlockHandler")
public String update(){
return "success";
}
String storgeBlockHandler(BlockException e){
e.printStackTrace();
return "系统繁忙,请稍后重试";
}
}
spring:
application:
name: storge-service
cloud:
sentinel:
transport:
dashboard: localhost:9000
资源级别熔断机制
针对某个微服务的某个接口,属于资源级别的
平均响应时间rt ,这里设置时间短一点便于测试
编码实现
@PostConstruct
public void initRule(){
List<DegradeRule> rules = new ArrayList<>();
DegradeRule rule = new DegradeRule();
rule.setResource("storge2");
rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
// 定义阈值
rule.setCount(0.01);
rule.setTimeWindow(10);
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}
页面操作
- 最大RT:Response Time 响应时间,超过时间则为慢调用
- 比例阈值:当服务请求数超过最小请求数,那么在统计时长里,如果策略为慢调用比例,那么慢调用占全部请求数的比例超过或等于比例阈值(慢调用/全部请求数),那么就会触发熔断,阈值范围为[0.0,1.0]代表 0% - 100%,如果为0.5则是慢调用占全部请求数的比例为50%或以上则触发熔断。
- 熔断时长:顾名思义,就是触发熔断后,熔断持续的时长。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
- 最小请求数:熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断。
- 统计时长:即在设定的时间内进行统计。
参考文章:https://www.cnblogs.com/Alickx/articles/15298401.html
系统级别的保护机制
Sentinel 系统自适应保护从整体维度对应用入口流量进行控制,结合应用的 Load、总体平均 RT、入口 QPS 和线程数等几个维度的监控指标,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
其实是针对整个微服务
@RestController
@RequestMapping("/storge3")
public class StorgeController3 {
@GetMapping
@SentinelResource(entryType = EntryType.IN)
public String hello(){
return "success";
}
}
出现的问题:系统规则配置添加后没效
https://developer.aliyun.com/ask/570903
可以改用低版本的试试
补充:
各种整合
sentinel整合RestTemplate,也可以整合springcloud 整合后面要学习的Feign,整合gateway网关等。以及sentinel数据持久化。这些就自行学习
熔断和降级的区别
降级(Degradation)降低级别的意思,它是指程序在出现问题时,仍能保证有限功能可用的一种机制。
比如电商交易系统在双 11 时,使用的人比较多,此时如果开放所有功能,可能会导致系统不可用,所以此时可以开启降级功能,优先保证支付功能可用,而其他非核心功能,如评论、物流、商品介绍等功能可以暂时关闭。
所以,从上述信息可以看出:降级是一种退而求其次的选择,而熔断却是整体不可用。
好博客就要一起分享哦!分享海报
此处可发布评论
评论(0)展开评论
展开评论