文章目录
- sentinel
- sentinel介绍
- 重要的核心概念
- 引入依赖
- 限流的规则
- 熔断规则
- yaml 项目配置
- 使用注解 @SentinelResource讲解
- 类的静态方法
sentinel
sentinel介绍
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
重要的核心概念
资源
- 资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。
- 只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
规则 - 围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。
引入依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>
</dependencies>
限流的规则
[{"resource":"addOrder","count":"1","grade":"1","strategy":"1","limitApp":"queryOrder","controlBehavior":"0"}
]
- resource: 定义当前规则绑定限制的资源id 名称
- count: 限流的阈值,grade=1 表示qps上限,grade=0 表示并发上限
- grade: 1 qps类型的限流 0 并发类型限流
- strategy: 限流策略.以哪种方案和逻辑来限流 0直接 1关联 2链路
- limitApp: 流控针对的调用来源,默认default不区分调用来源,配合strategy=1的是后和2的时候使用.
- controlBehavior: 限流效果(0直接拒绝,1Warm up,2排队)
- strategy:
- 0 直接限制,针对当前定义资源,限制访问
- 1 关联,和limitApp有关系,如果当前资源流量,超过限流规则,限制limitApp定义的资源.
- 2 链路 决定限制流量的时候,先判断一下链路的入口,和limitApp有关,表示入口的资源
熔断规则
[{"resource": "serviceHi","count": 1,"grade": 0,"timeWindow": 10,"minRequestAmount": 1,"slowRatioThreshold": 0.5,"statIntervalMs": 10000}
]
- count: 熔断触发的阈值(不再调用这个资源,而是访问降级策略),如果grade=0 count表示慢调用临界RT(响应时间单位毫秒),超过这个数字,就记录一次慢调用.grade是1,count值应该是>0小于1的小数,表示异常比例,grade=2 count配置整数,表示异常出现的次数
- slowRatioThreshold: 慢调用比例,在grade=0时生效.当满足count记录成慢调用时,达到这个阈值,触发熔断.
- minRequestAmount: 最少统计的请求数量.没达到最少数量,不会触发熔断
- statIntervalMs: 统计时长,在同一个统计时长之内的数据,才能触发熔断.单位毫秒数.
- timeWindow: 如果触发熔断,持续时间,单位秒
- grade: 熔断类型 0 默认值 慢调用比例 1 异常比例 2异常数
当前熔断规则定义:
在10秒钟之内,最少达到1次请求前提下,超过1毫秒的资源处理时间记录为慢调用,如果所有调用请求的慢调用比例达到50%,则资源会熔断,熔断持续时间10秒,10秒后,断路器半开,尝试访问资源,再次计算熔断规则.
- 熔断规则中的异常数.
[{"resource": "serviceHi","count": 1,"grade": 2,"timeWindow": 10,"minRequestAmount": 1,"slowRatioThreshold": 0.5,"statIntervalMs": 10000}
]
表示内容:
10秒内统计异常数的熔断策略,如果最小请求达到1,并且异常数超过1,进入熔断持续时间10秒.
yaml 项目配置
spring:cloud:sentinel:datasource:#定义一个数据源的名称key1:nacos:#数据源具体属性 nacos address namespace group-id 文件名称server-addr: localhost:8848data-id: flowRules.jsondata-type: json#namespace: f033ea8e-15ca-4f37-b112-127edc03de9e#每一个数据源的规则类型必须配置rule-type: flow#如果sentinel版本高于1.7 必须配置nacos用户名密码username: nacospassword: nacoskey2:nacos:#数据源具体属性 nacos address namespace group-id 文件名称server-addr: localhost:8848data-id: degradeRules.jsondata-type: json#namespace: f033ea8e-15ca-4f37-b112-127edc03de9e#每一个数据源的规则类型必须配置rule-type: degrade#如果sentinel版本高于1.7 必须配置nacos用户名密码username: nacospassword: nacos
使用注解 @SentinelResource讲解
@Service
public class HelloService {//定义一个方法为sentinel资源使用的注解//value 定义资源名称//blockhandler 会在本类中,寻找一个同名的方法,做降级的处理 要求//方法参数和方法返回值要和当前目标方法一致,并且要求添加一个异常对象的参数//fallbackpublic String aaa(String name,BlockException e){//异常 BlockException 有可能是所有不同规则对应的异常类型//DegradeExceptionreturn "sorry,sayHi方法熔断了,"+name;}public String bbb(String name,Throwable e){return "sorry,sayHi出现了异常,"+name;}@SentinelResource(value = "serviceHi",blockHandler="aaa",fallback = "bbb")public String sayHi(String name){System.out.println("进入到service的saiHi");String result="你好啊!"+name;int a=1/0;return result;}
}
类的静态方法
- 为了减少业务代码类中,降级处理逻辑的代码繁杂,提供了简化,静态方法提取
- sentinel允许我们将降级逻辑的代码方法,放到指定的类中,提供静态方法调用.节省本类代码,看起来更整洁.
- 限流目的: 根据预估/压测的数据 实现并发或者qps设置,保护服务器
- 熔断目的: 在保证主要业务功能成功实现前提下,附属,不重要的业务,可以做降级处理,避免他们问题影响主要业务功能
/**
远程调用时,和cart购物车有关的方法单独封装一个bean对象*/
@Component
@Slf4j
public class DubboCartService {@DubboReferenceprivate ICartService cartService;/*** 熔断降级的资源方法* @param orderAddDTO*/@SentinelResource(value="serviceHi",blockHandler ="aaa" ,fallback = "bbb")public void HelloServiceBlockHanlder(OrderAddDTO orderAddDTO){cartService.deleteUserCart(orderAddDTO.getUserId(), orderAddDTO.getCommodityCode());}public void aaa(OrderAddDTO orderAddDTO, BlockException e){log.error("熔断规则生效,断路器打开状态,orderAddDTO:{},异常信息e:{}",orderAddDTO,e.getMessage());}public void bbb(OrderAddDTO orderAddDTO,Throwable e){log.error("业务调用异常,orderAddDTO:{},异常信息e:{}",orderAddDTO,e.getMessage());}
}