Sentinel
Sentinel 是阿里巴巴开源的,面向分布式服务架构的高可用防护组件,主要以流量为切入点,从限流,流量整形、熔断降级、系统负载保护、热点防护等多个维度保护服务的稳定性
官方文档地址
启动 Sentinel 控制台
下载链接:https://github.com/alibaba/Sentinel/releases
启动控制台
java -Dserver.port=8858 -Dcsp.sentinel.dashboard.server=localhost:8858 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
其中 -Dserver.port=8858 用于指定 Sentinel 控制台端口为 8858。
控制台地址:http://127.0.0.1:8858/#/dashboard/home
整合springcloud alibaba
- 引入依赖
<!--sentinel启动器-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
- 添加yml配置,为微服务设置sentinel控制台地址
添加sentinel后,需要暴露/actuator/sentinel端点,而Springboot默认是没有暴露该端点的,所以需要设置,测试http://localhost:8800//actuator/sentinel
server:
port: 8821
spring:
application:
name: order-sentinel
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8858
流量控制
概述:
同一个资源可以对应多条限流规则。FlowSlot 会对该资源的所有限流规则依次遍历,直到有规则触发限流或者所有规则遍历完毕。
一条限流规则主要由下面几个因素组成,我们可以组合这些元素来实现不同的限流效果:
- resource:资源名,即限流规则的作用对象
- count: 限流阈值
- grade: 限流阈值类型,QPS 或线程数
- strategy: 根据调用关系选择策略
基于QPS/并发数的流量控制
流控规则:
Field | 说明 | 默认值 |
---|---|---|
resource | 资源名,资源名是限流规则的作用对象 | |
count | 限流阈值 | |
grade | 限流阈值类型,QPS模式(1)或并发线程模式(0) | QPS模式 |
limitApp | 流控针对的调用来源 | default,代表不区分调用来源 |
strategy | 调用关系限流策略:直接、链路、关联 | 根据资源本身(直接) |
controlBehavior | 流控效果(快速失败,WarmUp冷启动,排队等待) 不支持按调用关系限流 | 直接拒绝 |
clusterMode | 是否集群限流 | 否 |
WarmUp-----解决:激增流量
排队等待-----解决:脉冲流量
- QPS流量控制
- 并发线程数流量控制
基于调用关系的流量控制
熔断降级
概述:
除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方 API 等。
熔断策略
Sentinel 提供以下几种熔断策略:
- 慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。
- 异常比例 (ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
- 异常数 (ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
熔断降级规则说明
熔断降级规则(DegradeRule)包含下面几个重要的属性:
Field | 说明 | 默认值 |
---|---|---|
resource | 资源名,即规则的作用对象 | |
grade | 熔断策略,支持慢调用比例/异常比例/异常数策略 | 慢调用比例 |
count | 慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值 | |
timeWindow | 熔断时长,单位为 s | |
minRequestAmount | 熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入) | 5 |
statIntervalMs | 统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入) | 1000 ms |
slowRatioThreshold | 慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入) |
sentinel整合openfeign降级
- 依赖引入
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--nacos服务注册发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--1.添加openfeign依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--sentinel依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
- application.yml
server:
port: 8041
# 应用名称(nacos会将该名称当做服务名称)
spring:
application:
name: order-service
cloud:
nacos:
server-addr: 127.0.0.1:8848
discovery:
username: nacos
password: nacos
namespace: public
feign:
sentinel:
# openfeign整合sentinel
enabled: true
- openfeign接口
/**
* 添加feign接口和方法
* name 指定调用rest接口所对应的服务名
* path 指定调用rest接口所在的StockController指定的@RequestMapping
*/
@FeignClient(name = "stock-service", path = "/stock", fallback = StockFeignServiceFallback.class)
public interface StockFeignService {
/**
* 声明需要调用的rest接口对应的方法
* @return
*/
@RequestMapping("/reduct2")
String reduct2();
}
- openfeign的fallback实现类
@Component
public class StockFeignServiceFallback implements StockFeignService{
@Override
public String reduct2() {
return "降级了~~~~~";
}
}
系统自适应保护
概述:
Sentinel 系统自适应保护从整体维度对应用入口流量进行控制,结合应用的 Load、总体平均 RT、入口 QPS 和线程数等几个维度的监控指标,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统规则
- Load(仅对 Linux/Unix-like 机器生效):当系统 load1 超过阈值,且系统当前的并发线程数超过系统容量时才会触发系统保护。系统容量由系统的 maxQps * minRt 计算得出。设定参考值一般是 cpu cores * 2.5。
- cpu usage(1.5.0+ 版本):当系统 cpu 使用率超过阈值即触发系统保护(取值范围 0.0-1.0)。
- RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
- 线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
- 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
异常处理
单个接口异常处理使用 @SentinelResource
package com.example.order.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/order")
public class OrderController {
@RequestMapping("/add")
public String add(){
System.out.println("下单成功");
return "Hello World ";
}
@RequestMapping("/flow")
@SentinelResource(value = "flow",blockHandler = "flowBlockHandler")
public String flow(){
return "正常访问";
}
public String flowBlockHandler(BlockException e){
return "被流控了";
}
@RequestMapping("/flowThread")
@SentinelResource(value = "flowThread",blockHandler = "flowBlockHandler")
public String flowThread() throws InterruptedException {
TimeUnit.SECONDS.sleep(5);
return "正常访问";
}
}
设置统一异常处理
设置统一异常处理适合对BlockException返回的信息处理是一样的,如果不一样则还是需要使用@SentinelResource
package com.example.order.domain;
public class Result<T> {
private Integer code;
private String msg;
private T data;
public Result(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public Result(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public static Result error(Integer code,String msg){
return new Result(code,msg);
}
}
package com.example.order.exception;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.fastjson.JSON;
import com.example.order.domain.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {
Logger log = LoggerFactory.getLogger(this.getClass());
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
//getRule返回资源、规则的详细信息
log.info("BlockExceptionHandler BlockException================"+e.getRule());
Result r = null;
if(e instanceof FlowException){
r = Result.error(100,"接口被限流了");
}else if (e instanceof DegradeException){
r = Result.error(101,"服务降级了");
}else if (e instanceof ParamFlowException){
r = Result.error(102,"热点参数限流了");
}else if (e instanceof AuthorityException){
r = Result.error(104,"授权规则不通过");
}
//返回Json数据
httpServletResponse.setStatus(500);
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
PrintWriter writer=null;
try {
writer=httpServletResponse.getWriter();
writer.write(JSON.toJSONString(r));
writer.flush();
} catch (IOException ioException) {
log.error("异常:{}",ioException);
}finally {
if(writer!=null) {
writer.close();
}
}
}
}
sentinel规则持久化
- 基于Nacos配置中心控制台实现推送
引入依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
-
nacos配置中心配置流控规则
-
application.yml配置
server:
port: 8861
spring:
application:
name: order-sentinel
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8858
web-context-unify: false # 默认将调用链路收敛
datasource:
flow-rule: # 可以自定义
nacos:
server-addr: 127.0.0.1:8848
username: nacos
password: nacos
dataId: order-sentinel-flow-rule
rule-type: flow
原文地址:https://www.jb51.cc/wenti/3283308.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。