资源
资源就是Sentinel要保护的东西
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,可以是一个服务,也可以是 一个方法,甚至可以是一段代码。
规则
规则就是用来定义如何进行保护资源的
作用在资源之上, 定义以什么样的方式保护资源,主要包括流量控制规则、熔断降级规则以及系统 保护规则
Sentinel的主要功能就是容错,主要体现为下面这三个
流量控制
流量控制在网络传输中是一个常用的概念,它用于调整网络包的数据。任意时间到来的请求往往是 随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。 Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状。
熔断降级
当检测到调用链路中某个资源出现不稳定的表现,例如请求响应时间长或异常比例升高的时候,则 对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联故障。
Sentinel 对这个问题采取了两种手段:
通过并发线程数进行限制
通过响应时间对资源进行降级
Sentinel 和 Hystrix 的区别
两者的原则是一致的, 都是当一个资源出现问题时, 让其快速失败, 不要波及到其它服务 但是在限制的手段上, 确采取了完全不一样的方法: Hystrix 采用的是线程池隔离的方式, 优点是做到了资源之间的隔离, 缺点是增加了线程 切换的成本。 Sentinel 采用的是通过并发线程的数量和响应时间来对资源做限制。
系统负载保护
总之一句话: 我们需要做的事情,就是在Sentinel的资源上配置各种各样的规则,来实现各种容错的功 能。
Sentinel (分布式系统的流量防卫兵) 是阿里开源的一套用于**服务容错**
的综合性解决方案。它以流量 为切入点, 从流量控制
、熔断降级
、系统负载
等多个维度来保护服务的稳定性。
为微服务集成Sentinel非常简单, 只需要加入Sentinel的依赖即可
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
<version>2.2.3version>
dependency>
Sentinel 提供一个轻量级的控制台, 它提供机器发现、单机资源实时监控以及规则管理等功能。
#直接使用jar命令启动项目(控制台本身是一个SpringBoot项目)
java -Dserver.port=8000 -Dcsp.sentinel.dashboard.server=localhost:8000 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.0.jar
spring:
cloud:
sentinel:
transport:
port: 9999 #跟控制台交流的端口,随意指定一个未使用的端口即可
dashboard: localhost:8000 # 指定控制台服务的地址
@Api(tags = "Sentinel")
@RequestMapping(value = "/sentinel")
@RestController
public class DemoController1 {
@ApiOperation(value = "测试方法1",httpMethod = "GET")
@RequestMapping("/message1")
public String message1() {
return "message1";
}
@ApiOperation(value = "测试方法2",httpMethod = "GET")
@RequestMapping("/message2")
public String message2() {
return "message2";
}
}
登录我们的Sentinel管理平台,查看我们对应的服务,对需要的接口做流量控制
其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
FlowSlot
会根据预设的规则,结合前面 NodeSelectorSlot
、ClusterBuilderSlot
、StatisticSlot
统计出来的实时信息进行流量控制。
限流的直接表现是在执行 Entry nodeA = SphU.entry(resourceName)
的时候抛出 FlowException
异常。FlowException
是 BlockException
的子类,您可以捕捉 BlockException
来自定义被限流之后的处理逻辑。
同一个资源可以创建多条限流规则。FlowSlot
会对该资源的所有限流规则依次遍历,直到有规则触发限流或者所有规则遍历完毕。
一条限流规则主要由下面几个因素组成,我们可以组合这些元素来实现不同的限流效果:
resource
:资源名,即限流规则的作用对象count
: 限流阈值grade
: 限流阈值类型(QPS 或并发线程数)limitApp
: 流控针对的调用来源,若为 default
则不区分调用来源strategy
: 调用关系限流策略controlBehavior
: 流量控制效果(直接拒绝、Warm Up、匀速排队)资源名:唯一名称,默认是请求路径,可自定义
针对来源:指定对哪个微服务进行限流,默认指default,意思是不区分来源,全部限制
阈值类型/单机阈值:
是否集群:暂不需要集群 接下来我们以QPS为例来研究限流规则的配置。
降级规则就是设置当满足什么条件的时候,对服务进行降级。Sentinel提供了三个衡量条件:
@ApiOperation(value = "测试降级,异常", httpMethod = "GET")
@RequestMapping("/message4")
public String message4() {
i++;
if (i % 3 == 0) {
throw new RuntimeException();
}
return "message3";
}
热点参数流控规则是一种更细粒度的流控规则, 它允许将规则具体到参数上。
@ApiOperation(value = "测试热点规则", httpMethod = "GET")
@RequestMapping("/message5")
@SentinelResource("message5")//注意这里必须使用这个注解标识,热点规则不生效
public String message5(String name, Integer age) {
return name + age;
}
参数索引:标识方法参数的下标,从0开始限制热点参数
测试热点规则
分别用两个参数访问,会发现只对第一个参数限流了,下标为0的参数已经被热点规则限制
参数例外项允许对一个参数的具体值进行流控
编辑刚才定义的规则,增加参数例外项,这样进行测试传递name=1 测试不会被限流
很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源访问
控制的功能。来源访问控制根据资源的请求来源(origin)限制资源是否通过:
上面的资源名和授权类型不难理解,但是流控应用怎么填写呢?
其实这个位置要填写的是来源标识,Sentinel提供了 RequestOriginParser 接口来处理来源。
只要Sentinel保护的接口资源被访问,Sentinel就会调用 RequestOriginParser 的实现类去解析
访问来源
@Component
public class RequestOriginParserDefinition implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest request) {
String serviceName = request.getParameter("serviceName");
return serviceName;
}
}
系统保护规则是从应用级别的入口流量进行控制,从单台机器的总体 Load、RT、入口 QPS 、CPU使用
率和线程数五个维度监控应用数据,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。系统
保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量 (进入应用的流量) 生效。
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.csp.sentinel.slots.system.SystemBlockException;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* sentinel 异常处理类
*/
@Component
public class ExceptionHandlerPage implements BlockExceptionHandler {
//BlockException 异常接口,包含Sentinel的五个异常
//@SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。其主要参数如下:
// FlowException 限流异常
// DegradeException 降级异常
// ParamFlowException 参数限流异常
// AuthorityException 授权异常
// SystemBlockException 系统负载异常
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
response.setContentType("application/json;charset=utf-8");
ResponseData data = null;
if (e instanceof FlowException) {
data = new ResponseData(-1, "接口被限流了...");
} else if (e instanceof DegradeException) {
data = new ResponseData(-2, "接口被降级了...");
} else if (e instanceof ParamFlowException) {
data = new ResponseData(-3, "参数限流异常...");
} else if (e instanceof AuthorityException) {
data = new ResponseData(-4, "授权异常...");
} else if (e instanceof SystemBlockException) {
data = new ResponseData(-5, "系统负载异常...");
}
response.getWriter().write(JSON.toJSONString(data));
}
}
@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor
//无参构造
class ResponseData {
private int code;
private String message;
}
推荐文章
Spring Cloud Alibaba 系列学习笔记
SpringCloud Alibaba Nacos
SpringCloud Alibaba Sentinel
@SentinelResource注解总结,异常、降级兜底
SpringCloud Alibaba Sentine 规则持久化
SpringCloud Alibaba RocketMQ
Seata1.4.2分布式事务整合nacos+SpringCloudAlibaba觉得对您有帮助就留下个宝贵的吧!