Sentinel 分布式流量哨兵
Sentinel介绍
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
官网:https://sentinelguard.io/zh-cn/docs/introduction.html
快速使用
引入sentinel依赖
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-core</artifactId> <version>1.8.6</version> </dependency>
定义资源
public class SentinelQuickDemo { public static void main(String[] args) { initFlowRules(); while (true) { // 1.5.0 版本开始可以直接利用 try-with-resources 特性 try (Entry entry = SphU.entry("quick")) { // 被保护的逻辑 System.out.println("hello world"); } catch (BlockException ex) { // 处理被流控的逻辑 System.out.println("blocked!"); } } } }
定义规则
// 初始化限流规则 private static void initFlowRules() { List<FlowRule> rules = new ArrayList<>(); FlowRule rule = new FlowRule(); rule.setResource("quick"); rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // Set limit QPS to 20. rule.setCount(20); rules.add(rule); FlowRuleManager.loadRules(rules); }
Demo 运行之后,我们可以在日志
~/logs/csp/${appName}-metrics.log.xxx
里看到下面的输出:sentinel23
启动Sentinel控制台
下载地址:https://github.com/alibaba/Sentinel/releases 直接下载jar包版本
启动命令
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel
。可以参考 鉴权模块文档 配置用户名和密码。
访问localhost:8080进入sentinel控制台
SpringCloud Alibaba Sentinel
文档:https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
快速使用
maven坐标
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
application.yml
spring: application: # 微服务名称 name: cloud-alibaba-sentinel cloud: sentinel: transport: # sentinel控制台地址 dashboard: localhost:8888
现在启动SpringBoot,访问sentinel控制台 (需要访问一下对应的资源,控制台才会显示)
Controller
@RestController class SentinelController { private static String port; @GetMapping("/sentinel") public Object sentinelTest() { return "SUCCESS"; } }
sentinel控制台显示
蔟点链路
sentinel控制台1 实时监控
sentinel控制台2
sentinel控制台设置流控
点击流控按钮进行设置
sentinel流控1 设置阈值为QPS 1,单秒通过1个请求
sentinel流控2 查看流控规则
sentinel流控8 jemter测试流控,sentinel把流控修改为5,jemter的线程数量100,点击开始
sentinel24 sentinel控制台
sentinel25
注解埋点支持
官方文档https://sentinelguard.io/zh-cn/docs/annotation-support.html
@SentinelResource
用于定义资源,并提供可选的异常处理和 fallback 配置项。一般推荐将 @SentinelResource注解加到服务实现上,而在 Web 层直接使用 Spring Cloud Alibaba 自带的 Web 埋点适配
在刚才的接口上加上@Sentinel注解
@GetMapping("/sentinel") //一般推荐加在Service的实现上,web会有自带了web埋点适配,此处为了演示就不另外增加service @SentinelResource("sentinel") public Object sentinelTest() { return port; }
重启应用,查看控制台
sentinel流控7 后续就可以对此资源进行流控设置,就不用对url进行设置了
代码初始化设置流控
/**
* 自定义流控规则
* 不推荐使用代码模式配置流控和熔断规则,这种方式更适合本地演示和调试
*/
private static void initFlowRules() {
List<FlowRule> flowRules = new ArrayList<>();
FlowRule rule = new FlowRule();
//资源名称,即@SentinelResource注解的value值
rule.setResource("sentinel");
//限流类型
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
//流控阈值
rule.setCount(5);
flowRules.add(rule);
FlowRuleManager.loadRules(flowRules);
}
重启应用,查看控制台。(需要访问一下对应的资源,控制台才会显示)

配置文件方式设置流控
在resource下创建配置文件SentinelResource.json(文件名随意,最好见名知义)
[ { "resource": "sentinel", "controlBehavior": 0, "count": 20.0, "grade": 1, "limitApp": "default", "strategy": 0 } ]
初始化流控规则
/** * 动态规则配置限流和熔断 * 1.拉模式,通过读取文件获取规则 */ try { ClassLoader classLoader = CloudAlibabaSentinelApplication.class.getClassLoader(); String flowRulePath = URLDecoder.decode(classLoader.getResource("SentinelResource.json").getFile(), "UTF-8"); FileRefreshableDataSource<List<FlowRule>> flowRuleDataSource = new FileRefreshableDataSource<>(flowRulePath, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() { })); FlowRuleManager.register2Property(flowRuleDataSource.getProperty()); } catch (Exception e) { }
重启应用,访问对应资源后查看控制台
sentinel流控10
nacos配置中心方式设置流控
生产环境强烈推荐使用推模式。可以实时通过修改配置中心来改变流控规则
引入maven依赖,注意版本需要和sentinel版本一致
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> <version>1.8.6</version> </dependency>
nacos创建限流文件
sentinel流控11 初始化流控规则
/** * 2.推模式,配置中心模式,此处采用nacos。需要引入依赖sentinel-datasource-nacos,版本与sentinel版本保持一直 * 生产环境强烈推荐使用推模式。可以实时通过修改配置中心来改变流控规则 */ //nacos地址 String remoteAddress = "localhost:8848"; //配置组 String groupId = "DEFAULT_GROUP"; //配置文件Data ID String dataId = "sentinel-flow.json"; ReadableDataSource<String, List<FlowRule>> nacosFlowDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() { })); FlowRuleManager.register2Property(nacosFlowDataSource.getProperty());
重启应用,访问对应资源,查看控制台
sentinel流控12 在nacos上修改qps为50
sentinel13流控 刷新sentinel控制台,qps相应改变了
sentinel流控14
@SentinelResource注解的降级和熔断
SentinelResource注解可以通过fallback和blockHandler指定降级和熔断的方法
@GetMapping("/sentinel")
@SentinelResource(value = "sentinel", fallback = "sentinelFallback")
public Object sentinelTest() {
return port;
}
static Object sentinelFallback() {
logger.error("===>sentinelFallback");
return port + "#flowFallback#" + UUID.randomUUID();
}
//演示熔断
@GetMapping("/sentinel_error")
@SentinelResource(value = "sentinel_error", blockHandler = "sentinelBlockHandler")
public Object sentinelError() {
throw new RuntimeException();
}
//熔断
static String sentinelBlockHandler(BlockException ex) {
logger.error("===>sentinelFallback", ex);
return "blockHandler#" + UUID.randomUUID();
}
熔断示例
sentinel控制台给sentinel_error资源设置熔断
sentinel15熔断 设置为统计时长1秒,失败次数1次,超过阈值1次则熔断10s。
sentinel16熔断 sentinel17熔断 快速访问资源,导致熔断。
sentinel18熔断 等待10秒后,可再次访问资源
sentinel19熔断
降级示例
在nacos上,将刚才sentinel资源的qps改为1
sentinel20限流 控制台qps自动更新为1
sentinel21限流 快速刷新资源,可以看到进入了降级方法
sentinel22限流
到此,sentinel的熔断和降级就完成了。具体的业务中肯定比这些复杂,但是思路按照这个实现就可以了