文章已收录Github精选,欢迎Star:https://github.com/yehongzhi/learningSummary
一、什么是Sentinel
Sentinel定位是分布式系统的流量防卫兵。目前互联网应用基本上都使用微服务,微服务的稳定性是一个很重要的问题,而限流、熔断降级是微服务保持稳定的一个重要的手段。
下面看官网的一张图,了解一下Sentinel的主要特性:
在Sentinel之前其实就有Hystrix做熔断降级的事情,我们都知道出现新的事物肯定是原来的东西有不足的地方。
那Hystrix有什么不足之处呢?
- Hystrix常用的线程池隔离会造成线程上下切换的overhead比较大。
- Hystrix没有监控平台,需要我们自己搭建。
- Hystrix支持的熔断降级维度较少,不够细粒,而且缺少管理控制台。
Sentinel有哪些组成部分?
- 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
- 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
Sentinel有哪些特征?
-
丰富的应用场景。控制突发流量在可控制的范围内,消息削峰填谷,集群流量控制,实时熔断下游不可用的应用等等。
-
完备的实时监控。Sentinel 提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
-
广泛的开源生态。Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
-
完善的 SPI 扩展点。Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
二、Hello World
一般要学一种没接触过的技术框架,肯定要先做个Hello World熟悉一下。
引入Maven依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.1</version>
</dependency>
需要提醒一下,Sentinel仅支持JDK 1.8或者以上的版本
定义规则
通过定义规则来控制该资源每秒允许通过的请求次数,例如下面的代码定义了资源 HelloWorld
每秒最多只能通过 20 个请求。
private static void initFlowRules(){
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("HelloWorld");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// Set limit QPS to 20.
rule.setCount(20);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
编写Hello World代码
其实代码编写很简单,首先需要定义一个资源entry,然后用SphU.entry("HelloWorld")
和entry.exit()
把需要流量控制的代码包围起来。代码如下:
public static void main(String[] args) throws Exception {
initFlowRules();
while (true) {
Entry entry = null;
try {
entry = SphU.entry("HelloWorld");
/*您的业务逻辑 - 开始*/
System.out.println("hello world");
/*您的业务逻辑 - 结束*/
} catch (BlockException e1) {
/*流控逻辑处理 - 开始*/
System.out.println("block!");
/*流控逻辑处理 - 结束*/
} finally {
if (entry != null) {
entry.exit();
}
}
}
}
运行结果如下:
我们根据目录查看日志,文件名格式为${appName}-metrics.log.xxx:
|--timestamp-|------date time----|-resource-|p |block|s |e|rt
1616607101000|2021-03-25 01:31:41|HelloWorld|20|11373|20|0|1|0|0|0
1616607102000|2021-03-25 01:31:42|HelloWorld|20|24236|20|0|0|0|0|0
p
代表通过的请求。
block
代表被阻止的请求。
s
代表成功执行完成的请求个数。
e
代表用户自定义的异常。
rt
代表平均响应时长。
三、使用Sentinel的方式
下面结合实际案例,写一个Controller接口进行示范练习。
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
@RequestMapping("/list")
public List<User> getUserList() {
return userService.getList();
}
}
@Service
public class UserServiceImpl implements UserService {
//模拟查询数据库数据,返回结果
@Override
public List<User> getList() {
List<User> userList = new ArrayList<>();
userList.add(new User("1",