1、sentinel是什么?
Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助您保障微服务的稳定性。
2、sentinel中的概念
资源
资源是sentinel中的关键,可以是我们应用程序中的任何内容。比如一段Java代码,一个URL请求,一个方法都可以用来作为sentinel的资源。
如何定义一个资源呢?
sentinel提供了两种方法来定义,我们简单将其划分为代码方式和注解方式。
代码方式:
// 资源名可使用任意有业务语义的字符串,比如方法名、接口名或其它可唯一标识的字符串。
// 抛出异常的方式定义资源
Entry entry = null;
try {
entry = SphU.entry("自定义资源名", EntryType.IN, 1);
// Your logic here.
} catch (BlockException ex) {
// Handle request rejection.
} finally {
if (entry != null) {
entry.exit(1);
}
}
// 返回布尔值方式定义资源
if (SphO.entry("自定义资源名")) {
// 务必保证finally会被执行
try {
/**
* 被保护的业务逻辑
*/
} finally {
SphO.exit();
}
} else {
// 资源访问阻止,被限流或被降级
// 进行相应的处理操作
}
注解方式
// 当默认值value为空的时候,sentinel会使用类的全路径+方法名作为资源名称
@SentinelResource
public User getUserById(String id) {
throw new RuntimeException("getUserById command failed");
}
以上两种方式就是sentinel中对于资源的定义方式。
规则
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。
sentinel中的规则包括:
- 流控规则
- 降级规则
- 热点规则
- 系统规则
- 授权规则
在后续的文章中会对各个规则的使用做一个详细的介绍。
如何定义一个规则?
我们可以通过代码方式和sentinel dashboard两种方式去定义。
代码方式定义规则(流控规则)
private static void initFlowQpsRule() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule1 = new FlowRule();
// 设置资源名
rule1.setResource(resource);
// 设置限流QPS阈值
rule1.setCount(20);
// 设置限流模式
rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 设置来源(默认default)
rule1.setLimitApp("default");
rules.add(rule1);
FlowRuleManager.loadRules(rules);
}
通过上面的两个步骤,我们可以达到简单的通过QPS限流的效果,当然我们需要在项目中引入sentinel相关的依赖,这里我使用spring cloud alibaba为例,当然其他的如spring boot,dubbo,spring原生都是支持的,具体的可以参考官网:https://sentinelguard.io/zh-cn/docs/open-source-framework-integrations.html
3、Spring Cloud Alibaba接入sentinel
spring cloud alibaba的接入非常简单,只需要引入对应的sentinel的starter就可以了。
maven dependency坐标
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
新建一个类SentinelFlowControlTest:
@RestController
@Slf4j
public class SentinelFlowControlTest {
@PostMapping("/flowControl")
@SentinelResource("flowControl")
public User flowControlQps(@RequestBody Person user) {
System.out.println("flowControlQps 流控Qps");
return user;
}
// 代码方式等同于上面的注解方式定义限流资源
// @PostMapping("/flowControl")
// public User flowControlCode(@RequestBody Person user) {
// Entry entry = null;
// try {
// entry = SphU.entry("flowControl", EntryType.IN, 1);
// // Your logic here.
// } catch (BlockException ex) {
// throw new RuntimeException("限流异常");
// } finally {
// if (entry != null) {
// entry.exit(1);
// }
// }
// return user;
// }
}
新建一个Runner初始化流控规则:
@Component
public class SentinelConfigRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
// 流控规则-QPS
flowControlQps();
}
private void flowControlQps() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule1 = new FlowRule();
rule1.setResource("flowControl");
rule1.setCount(5);
rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
rules.add(rule1);
FlowRuleManager.loadRules(rules);
System.out.println(JSONObject.toJSONString(Collections.singletonList(rules)));
}
}
简单压测一下,我们的流控规则设置的是接口的qps为5,查看压测结果。
关于sentinel控制台的配置下篇文章会做一个介绍。
到这里,sentinel的入门和简单使用就接受了,接下来会详细介绍每种流控规则的设置以及对应的使用场景。