SpringCloud微服务:Sentinel哨兵组件,管理服务限流和降级
源码地址:GitHub·点这里||GitEE·点这里
一、基本简介
1、概念描述
Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。包括核心的独立类库,监控台,丰富的使用场景验证。(这似乎是阿里开源组件的一贯作风,极其有特点,且特点很规律)
基本特性图:

补刀一句:这种图很多人可能不在意,但是一般官方给这个图就是该中间件的基本使用思路,与核心功能点。
2、基础性概念
- 资源管理
资源是Sentinel组件中的核心概念之一。应用服务器上脚本,静态页面,API接口,文件图片等都可以理解为资源,对于Java开发者而言,API接口就是这里资源的概念。
- 规则配置
Sentinel组件通过流控规则的配置,来指定允许该资源(API接口)通过的请求次数,IP黑白名单,应用服务等。
- 测试效果
QPS:每秒查询率,是一台服务器每秒能够处理的查询次数。
TPS:每秒处理事务数,事务处理整体倾向于整个过程。
二、框架环境整合
这里的环境主要整合Nacos注册中心,Feign服务,Sentinel哨兵,和Sentinel控制台。
1、基本依赖
这里的依赖需要参考官方文档,不同的环境使用不同的依赖,这里主要适配SpringCloud环境,所以使用如下包即可。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
2、控制台面板
这里直接从GitHub下载一个控制台服务包即可,也可以自己下载源码,按照需求修改后自行打包。
java -jar sentinel-dashboard-1.7.1.jar
下载并启动控制台服务。
3、服务配置
这里主要是把用到的两个服务9001和9002连接到监控台。
spring:
application:
name: node09-nacos-9001
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
sentinel:
transport:
port: 9001
dashboard: localhost:8080
最下面四行文件是哨兵控制台的主要配置,注意刚启动之后控制台是看不到连接的,有资源被触发之后才能看到。(附一张首页效果图)

三、流量控制
1、基本描述
流量控制(flow control),其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
2、限流规则
限流规则主要由下面几个因素组成。
- resource:资源名,即限流规则的作用对象,对于Java服务端开发而言就是执行的方法;
- count: 限流阈值,单位时间内能按照规则通过的请求量;
- grade: 限流阈值类型,QPS 或并发线程数 ;
- limitApp: 流控限制的指定应用来源,若为default则不区分调用来源;
- strategy: 调用关系限流策略,直连,链路等;
- controlBehavior: 流量控制效果,直接拒绝、Warm Up、匀速排队;
3、基本案例
- 硬编码
配置规则
public class FlowRuleConfig {
public static void initFlowQpsRule(String resourceName) {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule(resourceName);
// 修改这里参数,查看效果
rule.setCount(100);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}
该规则参考上面的限流因素,不难理解。
使用方式
@RequestMapping(value = "/web/getOrder",method = RequestMethod.GET)
public String getOrder (@RequestParam("id") Integer id){
FlowRuleConfig.initFlowQpsRule("getOrder");
Entry entry = null;
try {
// 定义资源,埋点
entry = SphU.entry("getOrder");
// 保护的业务逻辑
return "Order=" + id ;
} catch (Exception e){
e.printStackTrace();
} finally {
if (entry != null){entry.exit();}
}
return "Order Error" ;
}
测试的时候修改规则中count值,测试效果明显。
- 编码简化
SphU.entry中可以设置处理类型,限流阈值。
@RequestMapping(value = "/web/getState",method = RequestMethod.GET)
public String getState (@RequestParam("id") Integer id){
Entry entry = null;
try {
entry = SphU.entry("getOrder",EntryType.IN,2);
return "state=" + id;
}
catch (BlockException e){
e.printStackTrace();
} finally {
if (entry != null){entry.exit();}
}
return "State Error" ;
}
不过这种模式依旧是代码入侵严重,不太符合现在编程的大趋势。Sentinel支持通过@SentinelResource注解定义资源并配置。
4、测试效果
请求上述的两个测试接口,之后看控制台中9001服务的簇点链路。

可以基于控制台实时配置资源的:流控、降级、热点、授权等核心功能,服务重启之后配置也会重置。
四、服务熔断降级
1、注解详解
核心注解SentinelResource
用于定义资源,并提供可选的异常处理和 fallback 配置项。 @SentinelResource 注解包含以下属性:
- value
资源名称,核心概念不能为空;
- entryType
entry 类型,可选项默认为 EntryType.OUT;
- blockHandler
对应处理BlockException的函数名称,可选项。blockHandler函数访问范围需要是public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为BlockException。blockHandler函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass为对应的类的Class对象,注意对应的函数必须为 static 函数,否则无法解析。
- fallback
fallback函数名称,可选项,用于在抛出异常的时候提供fallback处理逻辑。fallback函数可以针对所有类型的异常(除了 exceptionsToIgnore里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:返回值类型必须与原函数返回值类型一致;方法参数列表需要和原函数一致,或者可以额外多一个;
注意:这里可以这样理解blockHandler和fallback,fallback处理业务逻辑的异常,服务降级,blockHandler处理sentinel组件控制的阻断异常。
2、使用案例
9001接口服务
@Service
public class FlowServiceImpl implements FlowService {
@Resource
private JdbcTemplate jdbcTemplate ;
@SentinelResource(value = "getPhone",blockHandler = "exceptionHandler", fallback = "fallback")
@Override
public String getPhone(Integer id) {
String sql = "select phone from d_phone WHERE id="+id ;
Integer.parseInt("hand") ;
return jdbcTemplate.queryForList(sql,String.class).get(0) ;
}
// 降级处理
public String fallback(Integer id) {
return "服务降级,id="+id ;
}
// 异常处理
public String exceptionHandler(Integer id,BlockException be) {
be.printStackTrace();
return "服务抛异常,id="+id ;
}
}
9002请求服务
@RequestMapping(value = "/web/getJdbc",method = RequestMethod.GET)
public String getJdbc () {
return msgFeign.getJdbc() ;
}
3、效果测试
通过控制台配置9001的限流规则,然后刷接口看效果。

注意阻断异常和业务异常的返参区别。
4、对比Hystrix组件
Hystrix的核心点在于以隔离和熔断为主的容错机制,超时或被熔断的调用将会快速失败,并可以提供 fallback 机制;
Sentinel核心点在于流量控制多样化,熔断降级服务,系统负载保护,实时监控和控制台;
补刀一句:对于流量控制类的组件,大部分场景是使用限流,服务降级这两块核心功能。
五、源代码地址
GitHub地址:知了一笑
https://github.com/cicadasmile/spring-cloud-base
GitEE地址:知了一笑
https://gitee.com/cicadasmile/spring-cloud-base

微服务系列组件
SpringCloud微服务:Sentinel哨兵组件,管理服务限流和降级的更多相关文章
- 高可用服务设计之二:Rate limiting 限流与降级
<高可用服务设计之二:Rate limiting 限流与降级> <nginx限制请求之一:(ngx_http_limit_conn_module)模块> <nginx限制 ...
- WCF 项目应用连载[8] - 绑定、服务、行为 大数据传输与限流 - 下 (ServiceThrottlingAttribute)
因为ORM的原因,对Attribute编程有一种情节..所以这节的出现,完全是因为在WCF对自定义Attribute的一种应用. WCF 项目应用连载[7] - 绑定.服务.行为 大数据传输与限流 - ...
- 0.9.0.RELEASE版本的spring cloud alibaba sentinel限流、降级处理实例
先看服务提供方的,我们在原来的sentinel实例(参见0.9.0.RELEASE版本的spring cloud alibaba sentinel实例)上加上限流.降级处理,三板斧只需在最后那一斧co ...
- Sentinel限流、降级配置详解
安装Sentinel 下载sentinel-dashboard-1.8.2.jar 安装有jdk环境,8080端口未被占用 在jar包所在目录打开cmd,输入命令启动:java -jar sentin ...
- Spring Cloud 微服务五:Spring cloud gateway限流
前言:在互联网应用中,特别是电商,高并发的场景非常多,比如:秒杀.抢购.双11等,在开始时间点会使流量爆发式地涌入,如果对网络流量不加控制很有可能造成后台实例资源耗尽.限流是指通过指定的策略削减流量, ...
- 微服务架构spring cloud - gateway网关限流
1.算法 在高并发的应用中,限流是一个绕不开的话题.限流可以保障我们的 API 服务对所有用户的可用性,也可以防止网络攻击. 一般开发高并发系统常见的限流有:限制总并发数(比如数据库连接池.线程池). ...
- Dubbo学习系列之十(Sentinel之限流与降级)
各位看官,先提个问题,如果让你设计一套秒杀系统,核心要点是啥???我认为有三点:缓存.限流和分离.想当年12306大面积崩溃,还有如今的微博整体宕机情况,感觉就是限流降级没做好,"用有限的资 ...
- 从-99打造Sentinel高可用集群限流中间件
接上篇Sentinel集群限流探索,上次简单提到了集群限流的原理,然后用官方给的 demo 简单修改了一下,可以正常运行生效. 这一次需要更进一步,基于 Sentinel 实现内嵌式集群限流的高可用方 ...
- SpringCloud之Zuul高并发情况下接口限流(十二)
高并发下接口限流技术gauva(谷歌的框架) MySql最大连接数3000: 原理:框架每秒向桶里放100个令牌,接口请求来了先去拿令牌,拿到令牌后才能继续向后走,否则不允许向后执行:当接口请求太频繁 ...
随机推荐
- 控制webbrowser滚动到指定位置
在构造函数中添加事件: webBrowser.DocumentCompleted+=new WebBrowserDocumentCompletedEventHandler(webBrowser_Doc ...
- Junit 单元测试在 intelliJ IDEA 中的安装
1.为什么使用Junit我们都知道,main 方法是一个程序的入口,通常来说,没有main方法,程序就无法运行.我们经常会写一些class文件(如下图所示),他们并没有自己的main方法.那么我们如何 ...
- 吴裕雄--python学习笔记:爬虫
import chardet import urllib.request page = urllib.request.urlopen('http://photo.sina.com.cn/') #打开网 ...
- 为啥java要使用 set ()和get()方法---封装
封装性:属性封装,方法封装,类封装,组件封装等 例如:如果属性没有封装,那么在本类对象之外创建对象后,可以直接访问属性 private关键字,只能在本类中访问,想要在外部访问私有属性,我们需要提供公有 ...
- Apache虚拟机的配置文件解说
1.为了方便管理虚拟主机,我决定使用一种方法,那就是修改httpd-vhosts.conf文件. 第一步首先要使扩展文件httpd-vhosts.conf生效: 1. 打开 apache/conf/h ...
- [JS奇怪的世界]No.55 危險小叮嚀:陣列與for in
前言 前面已經瞭解了使用內建函數建構子的某些危險地方,但其實陣列與for in,也是有一些危險的地方. 陣列與for in 在前面幾個章節有講過陣列就是物件,所以我們一樣可以使用 for in來做處理 ...
- 用Python搭建简单的HTTP服务 · Zhangxu's Blog
分享一个快速用Python搭建简单的HTTP服务的方法. 平时我们可能有需要,传输某个文件到手机,或者工作中某台服务器的电脑. 假如这个手机是个测试手机/服务器,并没有微信QQ之类的软件,而且你也不想 ...
- 新冠疫情下,亚德诺(ADI)全面加速
前言:亚德诺Analog Devices, Inc.(简称ADI),公司总部设在美国马萨诸塞州诺伍德市,设计和制造基地遍布全球.ADI公司被纳入标准普尔500指数(S&P 500 Index) ...
- swagger 以及swaggerUI使用的步骤
1.swagger,可以这么理解swagger是接口规范.Rest Api 传递参数的除了get请求外,put post,需要传递json.或者就是直接都通过传递json到后台 这里主要介绍一下spr ...
- Python 存储数据到json文件
1 前言 很多程序都要求用户输入某种信息,程序一般将信息存储在列表和字典等数据结构中. 用户关闭程序时,就需要将信息进行保存,一种简单的方式是使用模块json来存储数据. 模块json让你能够将简单的 ...