sentinel教程
服务雪崩效应在分布式系统中,由于网络原因或自身的原因,服务一般无法保证 100% 可用。如果一个服务出现了问题,调用这个服务就会出现线程阻塞的情况,此时若有大量的请求涌入,就会出现多条线程阻塞等待,进而导致服务瘫痪。由于服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的 “雪崩效应” 。雪崩发生的原因多种多样,有不合理的容量设计,或者是高并发下某一个方法响
服务雪崩效应
在分布式系统中,由于网络原因或自身的原因,服务一般无法保证 100% 可用。如果一个服务出现了问题,调用这个服务就会出现线程阻塞的情况,此时若有大量的请求涌入,就会出现多条线程阻塞等待,进而导致服务瘫痪。
由于服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的 “雪崩效应” 。
雪崩发生的原因多种多样,有不合理的容量设计,或者是高并发下某一个方法响应变慢,亦或是某台机器的资源耗尽。我们无法完全杜绝雪崩源头的发生,只有做好足够的容错,保证在一个服务发生问题,不会影响到其它服务的正常运行。也就是"雪落而不雪崩"。
常见的容错思路
1、隔离
它是指将系统按照一定的原则划分为若干个服务模块,各个模块之间相对独立,无强依赖。当有故障发生时,能将问题和影响隔离在某个模块内部,而不扩散风险,不波及其它模块,不影响整体的系统服务。常见的隔离方式有:线程池隔离和信号量隔离。
2、超时
在上游服务调用下游服务的时候,设置一个最大响应时间,如果超过这个时间,下游未作出反应,就断开请求,释放掉线程。
3、限流
限流就是限制系统的输入和输出流量已达到保护系统的目的。为了保证系统的稳固运行,一旦达到的需要限制的阈值,就需要限制流量并采取少量措施以完成限制流量的目的。
4、熔断
在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。这种牺牲局部,保全整体的措施就叫做熔断。
服务熔断一般有三种状态:
熔断关闭状态(Closed)
服务没有故障时,熔断器所处的状态,对调用方的调用不做任何限制
熔断开启状态(Open)
后续对该服务接口的调用不再经过网络,直接执行本地的fallback方法
半熔断状态(Half-Open)
尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率。如果成功率达到预期,则说明服务已恢复,进入熔断关闭状态;如果成功率仍旧很低,则重新进入熔断关闭状态。
5、降级
降级其实就是为服务提供一个托底方案,一旦服务无法正常调用,就使用托底方案。
Sentinel
1、什么是Sentinel
Sentinel (分布式系统的流量防卫兵) 是阿里开源的一套用于服务容错的综合性解决方案。它以流量为切入点, 从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。
基本概念
资源
资源就是Sentinel要保护的东西
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,可以是一个服务,也可以是一个方法,甚至可以是一段代码。
规则
规则就是用来定义如何进行保护资源的
作用在资源之上, 定义以什么样的方式保护资源,主要包括流量控制规则、熔断降级规则以及系统保护规则。
总之一句话: 就是在Sentinel的资源上配置各种各样的规则,来实现各种容错的功能。
2、Sentinel 具有以下特征:
丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景, 例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
完备的实时监控: Sentinel 提供了实时的监控功能。通过控制台可以看到接入应用的单台机器秒
级数据, 甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架/库的整合模块, 例如与 SpringCloud、 Dubbo、 gRPC 的整合。只需要引入相应的依赖并进行简单的配置即可快速地接入Sentinel。
完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
Sentinel 分为两个部分:
核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo /Spring Cloud 等框架也有较好的支持。
控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
3.sentinel流控规则配置
引入依赖(sentinel应用于服务消费方,在消费方添加依赖)
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
1.直接编码方式
首先定义一个配置类,用于加载规则。在Sentinel中,可以定制5种规则:
流量控制规则 FlowRule
熔断降级规则 DegradeRule
访问控制规则 AuthorityRule
系统保护规则 SystemRule
热点规则 ParamFlowRule
@Component
public class SentinelConfig {
private static final String KEY="query";
@PostConstruct
private void init(){
initDegradeRule();
initFlowQpsRule();
initSystemRule();
initAuthorityRule();
initParamFlowRule();
}
//熔断降级规则
private void initDegradeRule(){
List<DegradeRule> rules=new ArrayList<>();
DegradeRule rule=new DegradeRule();
rule.setResource(KEY);
// 80s内调用接口出现 异常 ,次数超过5的时候, 进行熔断
rule.setCount(5);
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
rule.setTimeWindow(80);
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}
//流量控制规则
private void initFlowQpsRule() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule(KEY);
rule.setCount(20);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
//系统保护规则
private void initSystemRule() {
List<SystemRule> rules = new ArrayList<>();
SystemRule rule = new SystemRule();
rule.setHighestSystemLoad(10);
rules.add(rule);
SystemRuleManager.loadRules(rules);
}
//黑白名单控制
private void initAuthorityRule(){
List<AuthorityRule> rules=new ArrayList<>();
AuthorityRule rule = new AuthorityRule();
rule.setResource(KEY);
rule.setStrategy(RuleConstant.AUTHORITY_BLACK);
rule.setLimitApp("nacos-consumer");
rules.add(rule);
AuthorityRuleManager.loadRules(rules);
}
//热点参数规则
private void initParamFlowRule(){
ParamFlowRule rule = new ParamFlowRule(KEY)
.setParamIdx(0)
.setCount(20);
ParamFlowItem item = new ParamFlowItem().setObject(String.valueOf("4"))
.setClassType(String.class.getName())
.setCount(2);
rule.setParamFlowItemList(Collections.singletonList(item));
ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
}
}
2.基于注解的方式定义降级方法和抛出异常时的方法
@Service
public class QueryService {
private static final String KEY="query";
@SentinelResource(value = KEY,blockHandler ="blockHandlerMethod",
fallback = "fallbackMethod")
public String query(String name) {
if(name.equals("3")){
throw new RuntimeException("3 error");
}
return "begin query method, name= " + name;
}
public String blockHandlerMethod(String name, BlockException e){
e.printStackTrace();
return "blockHandlerMethod for Query : " + name;
}
public String fallbackMethod(String name, Throwable e){
e.printStackTrace();
return "fallbackMethod for Query : " + name;
}
}
通过@SentinelResource注解的blockHandler属性指定降级方法(被降级后返回的信息),通过fallback属性指定抛出异常时方法。
3.基于Sentinel控制台
安装控制台
Sentinel 提供一个轻量级的控制台, 它提供机器发现、单机资源实时监控以及规则管理等功能。
1 、下载jar包,解压到文件夹
https://github.com/alibaba/Sentinel/releases
2.启动控制台
#直接使用jar命令启动项目(控制台本身是一个SpringBoot项目)
java -jar sentinel-dashboard-1.8.0.jar
3.在服务消费方的配置文件中加入控制台配置信息
spring:
cloud:
sentinel:
transport:
port: 9999 #跟控制台交流的端口,随意指定一个未使用的端口即可
dashboard: localhost:8080 # 指定控制台服务的地址
4、通过浏览器访问localhost:8080 进入控制台 ( 默认用户名密码是 sentinel/sentinel )
需要先访问服务地址,服务才可以在sentinel控制台中显示出来
4.Sentinel支持多种不同的数据源来配置规则
本地文件配置
Nacos配置
ZooKeeper配置
Apollo配置
1.使用nacos做数据源
使用nacos作为数据源,需要导入nacos存储扩展的依赖:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.0</version>
</dependency>
在yml中添加配置信息,配置nacos作为数据源
spring:
cloud:
sentinel:
transport:
port: 8719
dashboard: localhost:8088
datasource:
ds:
nacos:
server-addr: 127.0.0.1:8848
group-id: DEFAULT_GROUP
rule-type: flow
data-id: sentinel-demo-getSentinelConfig
data-type: json
ds:数据源名,可随意配置
server-addr: nacos连接地址
group-id: nacos连接的分组
rule-type: 指定路由存储规则
data-id: 读取配置文件的 data-id
data-type: 指定读取配置文件的类型
更多推荐
所有评论(0)