目录
介绍
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 的特征
丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷(对于突然到来的大量请求,您可以配置流控规则,以稳定的速度逐步处理这些请求,从而避免流量突刺造成系统负载过高)、集群流量控制、实时熔断下游不可用应用等
完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况
广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架 / 库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel
完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等
Sentinel 的组成
核心库(Java 客户端): 不依赖任何框架 / 库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持
控制台(Dashboard): 基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器
实战使用
简单实例
准备一个springboot项目.这里不再演示如何创建一个新的springboot项目
添加sentinle必备依赖
<!-- sentinel核心依赖-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.6</version>
</dependency>
书写接口限流测试
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import jakarta.annotation.PostConstruct;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
public class TestController {
@GetMapping("hello")
public String hello(){
//使用限流规则
try (Entry entry = SphU.entry("Hello")){ //限流入口
System.out.println("你好");
return "你好 sentinel"; //被保护的资源
}catch (BlockException e){
e.printStackTrace();
return "系统繁忙,请稍后"; //被限流或者被降级的操作处理
}
}
/**
* 定义限流规则
* @PostConstruct 当前类的构造函数执行之后执行
*/
@PostConstruct
public void initFlowRule(){
//创建存放限流规则的集合
List<FlowRule> ruleList = new ArrayList<>();
//创建限流规则
FlowRule rule = new FlowRule();
//定义资源 表示Sentinel会对哪个资源生效 相当于做一个标记
rule.setResource("Hello");
//定义限流规则类型 RuleConstant.Flow_GRADE_QPS: QPS限流类型
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
//定义QPS每秒能通过的请求个数
rule.setCount(2);
//将限流规则存放到集合中
ruleList.add(rule);
//加载限流规则
FlowRuleManager.loadRules(ruleList);
}
}
这里配置限流规则为1秒中最多可以通过2次,启动测试:
可以看到请求过快的话会直接返回接口中配置限流规则后的异常信息,说明sentinel已经初步使用成功
配置本地控制台
sentinel可以通过配置本地控制台ui来进行接口限流的可视化管理,首先需要下载官网提供的可视化jar包
Releases · alibaba/Sentinel · GitHub
当然有下载比较慢的问题,所以也可以在本博主提供的链接里进行下载
下载后在cmd窗口中运行启动
java -Dserver.port=9000 -jar sentinel-dashboard-1.8.6.jar
浏览器地址栏输入localhost:9000进行访问,账号密码默认都是sentinel
此时登录后会发现没有被监控的服务,因为该控制台还没有和本地项目进行关联
关联本地项目需要添加控制台所需依赖
<!-- 本地sentinel控制台依赖-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.8.6</version>
</dependency>
然后在idea启动配置中添加启动配置
-Dcsp.sentinel.dashboard.server=localhost:9000 Sentinel控制台的地址和端口号
-Dproject.name=SentinelQuickStart 本地应用在控制台中的名称
这里博主使用的是idea新版ui,和旧版ui可能有些许不同
命令配置以空格隔开即可
启动项目后发现sentinel中可能还是没有检测到服务,这里需要重新调用下之前配置的限流规则接口,也就是前面的hello接口,调用后再刷新sentinel页面就可以看到监听的本地服务了
使用可视化ui配置简单流控
前面的流控是在底层书写代码进行限流控制的,还可以使用可视化ui来配置接口的限流策略
首先注释掉之前书写的限流规则
重启项目再测试接口
可以看到此时手写的限流规则已失效,切换到sentinel控制台
注意此处的资源名要和后台接口中配置的资源名一致
点击保存
再测试接口
可以看到和之前的手动书写的限流规则一样都起到了接口限流的作用,而且在控制台中也可以看到接口的监控情况
配置异步任务限流
在主启动类中开启允许异步任务
新建书写一个服务层,并书写异步方法
在sentinel中新增流控规则:
启动测试:
可以看到异步任务的限流也成功监控
使用注解定义限流资源
前面都是使用的代码方式来进行接口资源的定义,下面使用注解的形式来进行资源定义
首先导入所需依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.8.6</version>
</dependency>
书写sentinel注解定义配置类
书写接口
测试:
可以看到基于注解定义的流控资源也已生效
SpringCloud整合Sentinel
简单整合
新建一个springboot项目,引入依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
书写配置:
server.port=8083
# 设置本地应用名称
spring.application.name=SentinelSpringCloud
# 设置sentinel控制台的地址和端口
spring.cloud.sentinel.transport.dashboard=localhost:9000
#Spring表达你允许循环依赖存在,并且希望Spring能够自动解决这些循环依赖关系。启用此配置后,
# Spring会尝试自动解决循环依赖,以支持相关Bean之间的相互引用。
spring.main.allow-circular-references=true
书写接口:
启动项目
输入之前的 命令启动下载的可视化jar包
java -Dserver.port=9000 -jar sentinel-dashboard-1.8.6.jar
在控制台中添加限流策略资源
调用接口测试
并发线程流控
并发线程数
并发数控制用于保业务线程池不被慢调用耗尽,例如,当应用所依赖的下游应用由于某种原因导致服务不稳定、响应延增加对于调用者来说,意味着否叫量下降和更多的线程教占用,极端值下其至导致线程池耗尽,为应对大多线程占用的情况,业内有使用隔离的方案,比通过不同业务逻使用不同线程池来隔富业务自身之间的资源争抢线程池离),这种属富方案虽然爆宫性比较好,但是代价就是线程数目大多,线程上下文切换的 ovehead 比大,特别是对低延的调用有比较的影响,Sein 并发控制不负责创建和管理池,而是简单统计当前请求上下文的线数目(正在执行的调用数目),如果超出闻值,新的请求会被立即拒绝,效果类似于信号量隔离。并发数控制涌常在调用端进行配置
调整接口
新增流控规则时选择并发线程数
启动测试:
关联模式
关联当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。比如对数一个字段的读和写操作存在争抢,读的速度过高会影响写得速度,写的违度过高会影响读的速度如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的否量,可使用关联限流来避免具有关联关系的资源之间过度的争抢,举例来说,tead h 和 mite h 这两个资源分别代表数车读写,我们同以给 read 设置限流规达到优先的目的:设置 strate 为 1etatSIRTECT L时设置 eert 为 te这当/于时教据的会被限流
举例 生成订单和查询订单,当生成订单接口访问过高时,被关联的查询订单接口被限流
书写接口:
控制台中创建限流规则
正常测试:
这里手动点击很难看到限流作用,所以使用一些压测工具进行测试.可以使用传统压测工具jemter进行压测,这里使用apipost进行压测
对生成订单进行接口压测,然后查看查询订单接口是否服务降级
可以看到对生成订单进行压测,关联的查询订单却受到了流控服务降级
整合openFeign使用
首先准备一个最少有两个服务的微服务项目并将服务注册到nacos中,这样可以进行服务之间的远程调用,从而使用openFeign再整合sentinel 这里不再从头演示,具体使用openFeign可以查看博主之前文章
这里准备一个生产者服务,一个消费者服务
在生产者中新建接口
在消费者中创建fen接口进行远程调用生产者接口
控制层书写接口调用
启动测试:
调用消费者接口,消费者通过openFeign调用生产者的接口,说明此时接口已经调通
更改接口,手动添加错误异常,从而模拟服务降级场景,从而使用sentinel进行整合服务降级
重启调用接口查看异常效果:
整合sentinel进行服务降级
配置中开启fen对sentinel使用
创建服务降级服务实现fen服务
设置服务降级服务接口
启动测试: