Sentinel分布式系统的流量防卫兵
Posted 幸福丶如此
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sentinel分布式系统的流量防卫兵相关的知识,希望对你有一定的参考价值。
项目官方地址:https://github.com/alibaba/Sentinel.git
一、Sentinel 具有以下特征:
丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
Sentinel 的主要特性:
二、Sentinel 基本概念:
资源: 资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
规则: 围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。
三、Sentinel 功能和设计理念:
流量控制: 流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。然而,从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状,如下图所示:
流量控制设计理念,流量控制有以下几个角度:
① 资源的调用关系,例如资源的调用链路,资源和资源之间的关系;
② 运行指标,例如 QPS、线程池、系统负载等;
③ 控制的效果,例如直接限流、冷启动、排队等。
④ Sentinel 的设计理念是让您自由选择控制的角度,并进行灵活组合,从而达到想要的效果。
熔断降级: 除了流量控制以外,降低调用链路中的不稳定资源也是 Sentinel 的使命之一。由于调用关系的复杂性,如果调用链路中的某个资源出现了不稳定,最终会导致请求发生堆积。Sentinel 和 Hystrix 的原则是一致的: 当检测到调用链路中某个资源出现不稳定的表现,例如请求响应时间长或异常比例升高的时候,则对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联故障。
熔断降级设计理念: 在限制的手段上,Sentinel 和 Hystrix 采取了完全不一样的方法。Hystrix 通过 线程池隔离 的方式,来对依赖(在 Sentinel 的概念中对应 资源)进行了隔离。这样做的好处是资源和资源之间做到了最彻底的隔离。缺点是除了增加了线程切换的成本(过多的线程池导致线程数目过多),还需要预先给各个资源做线程池大小的分配。
Sentinel 对这个问题采取了两种手段:
① 通过并发线程数进行限制 : 和资源池隔离的方法不同,Sentinel 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。这样不但没有线程切换的损耗,也不需要您预先分配线程池的大小。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。
② 通过响应时间对资源进行降级 : 除了对并发线程数进行控制以外,Sentinel 还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。
系统负载保护: Sentinel 同时提供系统维度的自适应保护能力。防止雪崩,是系统防护中重要的一环。当系统负载较高的时候,如果还持续让请求进入,可能会导致系统崩溃,无法响应。在集群环境下,网络负载均衡会把本应这台机器承载的流量转发到其它的机器上去。如果这个时候其它的机器也处在一个边缘状态的时候,这个增加的流量就会导致这台机器也崩溃,最后导致整个集群不可用。针对这个情况,Sentinel 提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。
Sentinel 分为两个部分:
① 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
② 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
四、Sentinel 基本使用:
1.首先,我们需要导入依赖:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.2</version>
</dependency>
2.定义资源限流规则:
资源 是 Sentinel 中的核心概念之一。最常用的资源是我们代码中的 Java 方法。 当然,您也可以更灵活的定义你的资源
//初始化规则
private static void initFlowRules() {
List<FlowRule> rules = new ArrayList<>(); //限流规则的集合
FlowRule flowRule = new FlowRule();//限流规则
flowRule.setResource("ruleTest");//资源(可以是方法名称、接口)
//线程数(FLOW_GRADE_THREAD)与QPS (FLOW_GRADE_QPS)
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS); //限流的阈值的类型
flowRule.setCount(18);// QPS数
rules.add(flowRule);
FlowRuleManager.loadRules(rules);
}
3.启动测试类,官网提供了以下代码做演示:
public static void main(String[] args) {
initFlowRules(); //初始化一个规则
while(true){
Entry entry=null;
try{
entry= SphU.entry("ruleTest");
System.out.println("Hello Word");
}catch (BlockException e){//如果被限流了,那么会抛出这个异常
e.printStackTrace();
}finally {
if(entry!=null){
entry.exit();// 释放
}
}
}
}
4.Demo 运行之后,我们可以在日志 ~/logs/csp/${appName}-metrics.log.xxx
里看到下面的输出:
其中 p
代表通过的请求, block
代表被阻止的请求, s
代表成功执行完成的请求个数, e
代表用户自定义的异常, rt
代表平均响应时长。可以看到,这个程序每秒稳定输出 "hello world"
18 次,和规则中预先设定的阈值是一样的。
五、Sentinel 控制台:
下载 https://github.com/alibaba/Sentinel/releases
,下载 sentinel-dashboard-1.8.2.jar 。(启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。)
1、启动控制台:
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
其中 -Dserver.port=8080
用于指定 Sentinel 控制台端口为 8080
。从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码
都是 sentinel
。
2、客户端接入控制台:
将刚刚演示的Demo 接入控制台,首秀按要导入依赖:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.8.2</version>
</dependency>
启动时加入 JVM 参数 -Dcsp.sentinel.dashboard.server=consoleIp:port
指定控制台地址和端口。若启动多个应用,则需要通过 -Dcsp.sentinel.api.port=xxxx 指定客户端监控 API 的端口(默认是 8719)。其他配置项见:https://github.com/alibaba/Sentinel/wiki/%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE%E9%A1%B9
配置如下:
port1:想要指定的应用接口端口,默认是8719,可自定义
ip:控制台的ip
port2:控制台的端口
Dproject.name:自定义的应用名
-Djava.net.preferIPv4Stack=true
-Dcsp.sentinel.api.port=port1
-Dcsp.sentinel.dashboard.server=ip:port2
-Dproject.name=dubbo-service-demo
这样子启动Demo,客户端配置好了与控制台的连接参数之后,并不会主动连接上控制台,需要触发一次客户端的规则才会开始进行初始化,并向控制台发送心跳和客户端规则等信息。就能再控制台上看到效果。
以上是关于Sentinel分布式系统的流量防卫兵的主要内容,如果未能解决你的问题,请参考以下文章
Spring Cloud Alibaba | Sentinel:分布式系统的流量防卫兵基础实战
#私藏项目实操分享#Alibaba中间件技术系列「Sentinel技术专题」分布式系统的流量防卫兵的基本介绍(入门源码介绍)
SpringCloud实战(十九)-Sentinel 流量控制