文章目录
- 一、简介
- 二、下载安装
- 三、编码
- 四、sentinel流控规则
- 五、熔断降级规则
- 六、热点规则
- 七、@SentinelResource 注解
- 案例
- 八、sentinel持久化
一、简介
Github文档
官方文档
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel
以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
服务使用中的各种问题:
- 服务雪崩
- 服务降级
- 服务熔断
- 服务限流
二、下载安装
官方文档
下载jar包到本地运行
命令:
java -jar sentinel-dashboard-1.7.0.jar
访问localhost:8080
登录账号密码均为sentinel
三、编码
依赖
com.alibaba.cloud spring-cloud-starter-alibaba-sentinel
yml
server: port: 8401 spring: application: name: cloudalibaba-sentinel-service cloud: nacos: discovery: server-addr: localhost:8848 #Nacos服务注册中心地址 sentinel: # <----sentinel配置 transport: dashboard: localhost:8080 #配置Sentinel dashboard地址 port: 8719 management: endpoints: web: exposure: include: '*' feign: # <----使用openfeign配置支持 sentinel: enabled: true # 激活Sentinel对Feign的支持
四、sentinel流控规则
- 资源名:唯一名称,默认请求路径。
- 针对来源:Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)。
- 阈值类型/单机阈值:
- QPS(每秒钟的请求数量)︰当调用该API的QPS达到阈值的时候,进行限流。
- 线程数:当调用该API的线程数达到阈值的时候,进行限流。
- 是否集群:不需要集群。
- 流控模式:
- 直接:API达到限流条件时,直接限流。
- 关联:当关联的资源达到阈值时,就限流自己。
-链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)。
- 流控效果:
- 快速失败:直接失败,抛异常。
- Warm up:根据Code Factor(冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值。
- 排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效。
五、熔断降级规则
- RT(平均响应时间,秒级)
- 平均响应时间超出阈值 且 在时间窗口内通过的请求>=最小请求数,两个条件同时满足后触发降级。
- 窗口期过后关闭断路器。
- RT最大4900(更大的需要通过-Dcsp.sentinel.statistic.max.rt=XXXX才能生效)。
- 异常比列(秒级)
- QPS >= 最小请求数且异常比例(秒级统计)超过阈值时,触发降级;时间窗口结束后,关闭降级 。
- 异常数(分钟级)
- 异常数(分钟统计)超过阈值时,触发降级;时间窗口结束后,关闭降级
六、热点规则
官方文档
七、@SentinelResource 注解
官方文档
案例
依赖
ps:
这个依赖是自定义的,含有CommonResult和Payment
com.study.springcloud cloud-api-commons ${project.version}
CommonResult
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class CommonResult{ private Integer code; private String massage; private T data; public CommonResult(Integer code, String message){ this(code,message,null); } }
Payment
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; @Data @AllArgsConstructor @NoArgsConstructor public class Payment implements Serializable { private Long id; private String serial; }
org.springframework.cloud spring-cloud-starter-openfeign com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery com.alibaba.cloud spring-cloud-starter-alibaba-sentinel com.study.springcloud cloud-api-commons ${project.version} org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-devtools runtime true org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
yml
server: port: 84 spring: application: name: nacos-order-consumer cloud: nacos: discovery: server-addr: localhost:8848 sentinel: transport: #配置Sentinel dashboard地址 dashboard: localhost:8080 #默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口 port: 8719 #消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者) service-url: nacos-user-service: http://nacos-payment-provider # 激活Sentinel对Feign的支持 feign: sentinel: enabled: false
启动类
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @EnableDiscoveryClient @SpringBootApplication @EnableFeignClients public class OrderNacosMain84 { public static void main(String[] args) { SpringApplication.run(OrderNacosMain84.class, args); } }
controller
import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; import com.comen.springcloud.entity.CommonResult; import com.comen.springcloud.entity.Payment; import com.comen.springcloud.service.PaymentService; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController @Slf4j public class CircleBreakerController { public static final String SERVICE_URL = "http://nacos-payment-provider"; @RequestMapping("/consumer/fallback/{id}") @SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler", exceptionsToIgnore = {IllegalArgumentException.class}) public CommonResultfallback(@PathVariable Long id) { CommonResult result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id, CommonResult.class,id); if (id == 4) { throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常...."); }else if (result.getData() == null) { throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常"); } return result; } //fallback public CommonResult handlerFallback(@PathVariable Long id,Throwable e) { Payment payment = new Payment(id,"null"); return new CommonResult<>(444,"兜底异常handlerFallback,exception内容 "+e.getMessage(),payment); } //blockHandler public CommonResult blockHandler(@PathVariable Long id,BlockException blockException) { Payment payment = new Payment(id,"null"); return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException "+blockException.getMessage(),payment); } @Resource private PaymentService paymentService; @GetMapping(value = "/consumer/paymentSQL/{id}") public CommonResult paymentSQL(@PathVariable("id") Long id) { return paymentService.paymentSQL(id); } }
service
import com.comen.springcloud.entity.CommonResult; import com.comen.springcloud.entity.Payment; import com.comen.springcloud.service.impl.PaymentFallbackService; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class) public interface PaymentService { @GetMapping(value = "/paymentSQL/{id}") public CommonResultpaymentSQL(@PathVariable("id") Long id); }
service实现类
import com.comen.springcloud.entity.CommonResult; import com.comen.springcloud.entity.Payment; import com.comen.springcloud.service.PaymentService; import org.springframework.stereotype.Component; @Component public class PaymentFallbackService implements PaymentService { @Override public CommonResultpaymentSQL(Long id) { return new CommonResult<>(44444,"服务降级返回,---PaymentFallbackService",new Payment(id,"errorSerial")); } }
八、sentinel持久化
将配置规则持久化进Nacos保存,sentinel控制台就能看到,只要Nacos里面的配置不删除,sentinel上的规则持续有效。
依赖引入
com.alibaba.csp sentinel-datasource-nacos
yml ,重点是给sentinel配置数据源
server: port: 8401 spring: application: name: cloudalibaba-sentinel-service cloud: nacos: discovery: server-addr: localhost:8848 #Nacos服务注册中心地址 sentinel: transport: dashboard: localhost:8080 #配置Sentinel dashboard地址 port: 8719 datasource: #<---------------------------关注点,添加Nacos数据源配置 ds1: nacos: server-addr: localhost:8848 dataId: cloudalibaba-sentinel-service groupId: DEFAULT_GROUP data-type: json rule-type: flow # 对应去sentinel dashboard management: endpoints: web: exposure: include: '*' feign: sentinel: enabled: true # 激活Sentinel对Feign的支持
例:
nacos添加限流规则
配置内容
[{ "resource": "/rateLimit/byUrl", "limitApp": "default", "grade": 1, "count": 1, "strategy": 0, "controlBehavior": 0, "clusterMode": false }]
- resource:资源名称;
- limitApp:来源应用;
- grade:阈值类型,0表示线程数, 1表示QPS;
- count:单机阈值;
- strategy:流控模式,0表示直接,1表示关联,2表示链路;
- controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待;
- clusterMode:是否集群。
sentinel自动加载配置进去了