前言

从0到1构建分布式秒杀系统打造十万博文系统中,限流是不可缺少的一个环节,在系统能承受的范围内既能减少资源开销又能防御恶意攻击。

在前面的文章中,我们使用了开源工具包 Guava 提供的限流工具类 RateLimiter 和 OpenResty 的 Lua 脚本分别进行 API 和应用层面的限流。今天,我们来聊聊阿里开源的分布式系统的流量防卫兵 Sentinel。

Sentinel 是什么?

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Sentinel 具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。

  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。

  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。

  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel 的主要特性:

Sentinel 的开源生态:

Sentinel 分为两个部分:

  • 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。

  • 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

控制台配置

Sentinel 控制台最少应该包含如下功能:

  • 查看机器列表以及健康情况:收集 Sentinel 客户端发送的心跳包,用于判断机器是否在线。

  • 监控 (单机和集群聚合):通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。

  • 规则管理和推送:统一管理推送规则。

  • 鉴权:生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制。

可以直接从release 页面 下载最新版本的控制台 jar 包,启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。。

启动脚本 sentinel.sh:

  1. #!/bin/bash
  2. java -Dsentinel.dashboard.auth.username=admin \
  3. -Dsentinel.dashboard.auth.password=admin \
  4. -Dserver.port=8084 -Dcsp.sentinel.dashboard.server=localhost:8084 \
  5. -Dproject.name=sentinel-dashboard \
  6. -jar sentinel-dashboard-1.6.3.jar &

用户可以通过如下参数进行配置:

  • -Dsentinel.dashboard.auth.username=admin 用于指定控制台的登录用户名为 admin;

  • -Dsentinel.dashboard.auth.password=admin 用于指定控制台的登录密码为 admin;如果省略这两个参数,默认用户和密码均为 sentinel;

  • -Dserver.servlet.session.timeout=7200 用于指定 Spring Boot 服务端 session 的过期时间,如 7200 表示 7200 秒;60m 表示 60 分钟,默认为 30 分钟;

客户端配置

pom.xml 引入以下依赖:

  1. <!-- https://blog.52itstyle.vip -->
  2. <parent>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-parent</artifactId>
  5. <version>2.1.5.RELEASE</version>
  6. <relativePath/>
  7. </parent>
  8. <dependencies>
  9. <dependency>
  10. <groupId>org.springframework.boot</groupId>
  11. <artifactId>spring-boot-starter-web</artifactId>
  12. </dependency>
  13. <dependency>
  14. <groupId>com.alibaba.cloud</groupId>
  15. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  16. </dependency>
  17. </dependencies>
  18. <dependencyManagement>
  19. <!--注意跟 SpringBoot 保持一致 2.1.x for Spring Boot 2.1.x-->
  20. <dependencies>
  21. <dependency>
  22. <groupId>com.alibaba.cloud</groupId>
  23. <artifactId>spring-cloud-alibaba-dependencies</artifactId>
  24. <version>2.1.0.RELEASE</version>
  25. <type>pom</type>
  26. <scope>import</scope>
  27. </dependency>
  28. </dependencies>
  29. </dependencyManagement>

配置文件:

  1. # 应用名称 https://blog.52itstyle.vip
  2. spring.application.name=blog
  3. spring.cloud.sentinel.transport.port=8720
  4. # 测试请替换为自己的地址
  5. spring.cloud.sentinel.transport.dashboard=116.190.247.112:8084

这里的 spring.cloud.sentinel.transport.port 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了1个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。

代码配置:

  1. /**
  2. * 博文 https://blog.52itstyle.vip
  3. */
  4. @RequestMapping("{id}.shtml")
  5. @SentinelResource("blogView")
  6. public String page(@PathVariable("id") Long id, ModelMap model) {
  7. try{
  8. Blog blog = blogService.getById(id);
  9. String key = "blog_"+id;
  10. Long views = redisUtil.size(key);
  11. blog.setViews(views+blog.getViews());
  12. model.addAttribute("blog",blog);
  13. } catch (Throwable e) {
  14. return "error/404";
  15. }
  16. return "article";
  17. }

@SentinelResource 注解用来标识资源是否被限流、降级。上述例子上该注解的属性 'blogView' 表示资源名。

默认情况,Sentinel 会拦截所有的 Controller 请求,这里标识资源名,是因为所有的文章都会走这个请求,为了方便统计和流控,这里自定义资源标识。

更多注解支持,请参考:Sentinel/wiki/注解支持

访问客户端项目,随便点击几个页面,然后登录 Sentinel 控制台,如果看到以下界面,说明配置成功。

配置限流,搜索我们刚才配置的资源名称,选择流控功能。

输入阈值参数,为了测试方便,这里直接输入2,连续刷新浏览器,如果后台出现以下错误,并伴随着前台页面无法正常显示说明配置生效。

  1. Caused by: com.alibaba.csp.sentinel.slots.block.flow.FlowException: null

当然,Sentinel 流程功能不仅仅这么简单,还支持集群模式,在终极版十万博文中,我们可以为集群中的节点,设置单机均分,也可以设置一个总体的阈值。

生产环境中使用

Sentinel 核心库目前已可用于生产环境,目前除了阿里巴巴以外,也有多家企业在生产环境中使用它们。

规则管理及推送

原生版本的规则管理通过API 将规则推送至客户端并直接更新到内存中,并不能直接用于生产环境。

不过 Sentinel提供了扩展读数据源ReadableDataSource,规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。

监控

Sentinel 会记录资源访问的秒级数据(若没有访问则不进行记录)并保存在本地日志中。Sentinel 控制台可以通过 Sentinel 客户端预留的 HTTP API 从秒级监控日志中拉取监控数据,并进行聚合。

目前 Sentinel 控制台中监控数据聚合后直接存在内存中,未进行持久化,且仅保留最近 5 分钟的监控数据。若需要监控数据持久化的功能,可以自行扩展实现。

注意事项

由于一开始没有认真读文档,把控制台部署到了外网,而客户端在内网启动,导致客户端无法被访问到,实时链路和簇点链路数据无法正常显示。

测试的小伙伴注意了,原始模式下,客户端和控制台必须相互被访问到,客户端会向控制台定时发送心跳请求,控制台会向客户端推送规则、拉取流控数据并聚合。

源码

https://gitee.com/52itstyle/spring-boot-blog

参考

https://github.com/alibaba/Sentinel

SpringBoot 2.0 + 阿里巴巴 Sentinel 动态限流实战的更多相关文章

  1. Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!

    大家好,我是不才陈某~ 这是<Spring Cloud 进阶>第八篇文章,往期文章如下: 五十五张图告诉你微服务的灵魂摆渡者Nacos究竟有多强? openFeign夺命连环9问,这谁受得 ...

  2. Spring Cloud Alibaba | Sentinel:分布式系统的流量防卫兵动态限流规则

    Spring Cloud Alibaba | Sentinel:分布式系统的流量防卫兵动态限流规则 前面几篇文章较为详细的介绍了Sentinel的使用姿势,还没看过的小伙伴可以访问以下链接查看: &l ...

  3. SpringBoot进阶教程(六十八)Sentinel实现限流降级

    前面两篇文章nginx限流配置和SpringBoot进阶教程(六十七)RateLimiter限流,我们介绍了如何使用nginx和RateLimiter限流,这篇文章介绍另外一种限流方式---Senti ...

  4. Spring Cloud Alibaba | Sentinel: 服务限流基础篇

    目录 Spring Cloud Alibaba | Sentinel: 服务限流基础篇 1. 简介 2. 定义资源 2.1 主流框架的默认适配 2.2 抛出异常的方式定义资源 2.3 返回布尔值方式定 ...

  5. Sentinel整合Dubbo限流实战(分布式限流)

    之前我们了解了 Sentinel 集成 SpringBoot实现限流,也探讨了Sentinel的限流基本原理,那么接下去我们来学习一下Sentinel整合Dubbo及 Nacos 实现动态数据源的限流 ...

  6. Spring Cloud Alibaba | Sentinel: 服务限流高级篇

    目录 Spring Cloud Alibaba | Sentinel: 服务限流高级篇 1. 熔断降级 1.1 降级策略 2. 热点参数限流 2.1 项目依赖 2.2 热点参数规则 3. 系统自适应限 ...

  7. Spring Cloud微服务Sentinel+Apollo限流、熔断实战总结

    在Spring Cloud微服务体系中,由于限流熔断组件Hystrix开源版本不在维护,因此国内不少有类似需求的公司已经将眼光转向阿里开源的Sentinel框架.而以下要介绍的正是作者最近两个月的真实 ...

  8. 流量治理神器-Sentinel的限流模式,选单机还是集群?

    大家好,架构摆渡人.这是我的第5篇原创文章,还请多多支持. 上篇文章给大家推荐了一些限流的框架,如果说硬要我推荐一款,我会推荐Sentinel,Sentinel的限流模式分为两种,分别是单机模式和集群 ...

  9. Springboot中使用redis进行api限流

    api限流的场景 限流的需求出现在许多常见的场景中 秒杀活动,有人使用软件恶意刷单抢货,需要限流防止机器参与活动 某api被各式各样系统广泛调用,严重消耗网络.内存等资源,需要合理限流 淘宝获取ip所 ...

随机推荐

  1. 【0802 | Day 7】Python进阶(一)

    目 录  数字类型的内置方法 一.整型内置方法(int) 二.浮点型内置方法(float) 字符串类型内置方法 一.字符串类型内置方法(str) 二.常用操作和内置方法 优先掌握: 1.索引取值 2. ...

  2. SpringBoot:Mybatis + Druid 数据访问

    西部开源-秦疆老师:基于SpringBoot 2.1.7 的博客教程 秦老师交流Q群号: 664386224 未授权禁止转载!编辑不易 , 转发请注明出处!防君子不防小人,共勉! 简介 对于数据访问层 ...

  3. C# 基于NPOI+Office COM组件 实现20行代码在线预览文档(word,excel,pdf,txt,png)

    由于项目需要,需要一个在线预览office的功能,小编一开始使用的是微软提供的方法,简单快捷,但是不符合小编开发需求, 就另外用了:将文件转换成html文件然后预览html文件的方法.对微软提供的方法 ...

  4. C#连接sqlserver分页查询的两个简单的方法

    /// <summary>        /// 分页查询函数        /// </summary>        /// <param name="co ...

  5. (十二)c#Winform自定义控件-分页控件

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  6. ZooKeeper系列(三)—— Zookeeper 常用 Shell 命令

    一.节点增删改查 1.1 启动服务和连接服务 # 启动服务 bin/zkServer.sh start #连接服务 不指定服务地址则默认连接到localhost:2181 zkCli.sh -serv ...

  7. json模块和pickle模块

    json模块和pickle模块 一.json模块 作用:用python写了一个程序,用java写了一门程序,这两个程序需要数据之间交流,就产生了一种多种语言通用的数据类型,json串. 序列化:把对象 ...

  8. poium测试库之JavaScript API封装原理

    poium一直我在维护的一个开源项目,它的定位是以极简的方式在自动化项目中Page Objects设计模式.我在之前的文章中也有介绍. 本篇文章主要介绍一个JavaScript元素操作的封装原理. 为 ...

  9. Flink的Job启动JobManager端(源码分析)

    通过前面的文章了解到 Driver将用户代码转换成streamGraph再转换成Jobgraph后向Jobmanager端提交 JobManager启动以后会在Dispatcher.java起来RPC ...

  10. Minimum spanning tree for each edge(倍增LCA)

    https://vjudge.net/contest/320992#problem/J 暑期训练的题. 题意:给你一个n个点,m条边的无向图.对于每一条边,求包括该边的最小生成树. 思路:首先想到求一 ...