在上文Sentinel流量防卫兵中讲到了Sentinel入门以及流控规则一小部分,而Sentinel还有以下规则:

  • 熔断降级规则
  • 热点参数规则
  • 系统规则
  • 黑白名单规则

本文要讲的是流控规则

流量控制规则

原理

监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

QPS限流

这里我们访问一下/foo/test接口,触发Sentinel控制台初始化,就可以看到在簇点链路中刷新出了该接口的资源

然后我们点击+流控添加流控规则,选择QPS,并且限流为2

在高级选项中还有流控模式和流控效果两个选择,默认为直接和快速失败,具体含义见下面解释

新增之后,在页面上快速点击几次,就会看到我们之前预设好的限流提示

流控效果

流控效果只针对于QPS的流量控制

快速失败

当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。

案例见上

Warm Up

预热/冷启动方式,当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。

在控制台中删除到刚刚测试的快速失败规则,新增一个Warm up效果的规则

这里我设置的qps阈值为10,预热3秒,等效于想要达到10qps,需要预热3秒。

这里测试需要用到一些压测工具,比如我用的是jmeter,毕竟在3秒内每秒连点10下我是做不到,认为自己行的可以自己试试。

以10qps进行压测之后,可以实时监控中看到这么一张效果图

在左边的线性图中可以看到通过的qps(绿线)是在匀速上升状态,直到3秒后达到10变为平稳状态,具体的数值可以从右边的表格看到。

排队等待

排队等待即为匀速排队,该方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。

同样的,在控制台新增规则

排队等待的阈值最高只能配1000哦,至于为什么小伙伴就自己想啦

以12qps进行压测,查看实时监控面板

qps一直保持在10, 规则生效了

流控模式

流控模式和调用关系有关,调用关系包括调用方、被调用方;一个方法又可能会调用其它方法,形成一个调用链路的层次关系。

直接

根据调用来源进行限流,默认为default,即针对所有的来源,这里面还可以配置自定义的来源。

1.自定义来源

自定义来源需要修改我们的配置代码,更改方式如下

private void addSpringMvcInterceptor(InterceptorRegistry registry) {
SentinelWebMvcConfig config = new SentinelWebMvcConfig(); config.setBlockExceptionHandler(new MyBlockExceptionHandler());
// 区分请求方式
config.setHttpMethodSpecify(true);
// 请求来源解析
config.setOriginParser(request -> request.getHeader("User-Agent"));
registry.addInterceptor(new SentinelWebInterceptor(config)).addPathPatterns("/**");
}

在原来的配置中增加来源解析的配置,比如我这里就是获取请求头中的User-Agent作为请求来源,你也可以根据自己的需求决定,比如获取客户端的ip

修改完毕后,重启服务,在控制台新增一个来源为test的规则

然后在请求上加上User-Agent的header,测试

这里如果把User-Agent换成其他的,则不会被限流

2. 其他

其他的意思除了指定的来源都会被限流,看到这里的就会让人有所疑问

  • 控制台增加了other来源的配置,之前的test来源就不会限流了吗?

其实它的意思是这样的:除了test来源的请求,其他来源的qps都不能超过其他这条配置,举个例子

test来源限流的qps为2,other来源限流的qps为1,那么此时如果是来自test2来源的请求,qps超过1则会提示已被限流,test来源的请求仍旧是超过2之后才会提示被限流。

在控制台增加一条其他来源的配置

设置User-Agenttest2进行测试

可以看到,我这里只请求了1次就被限流了

关联

关联这个模式指的是如果一个资源被两个接口所访问,那么在一个接口超过qps阈值时,可以对另一个接口进行限流。

举个例子来说,FooService同时被A接口和B接口所访问,由于FooService总体能够接受的qps是恒定的,如果A接口qps过高,那么B接口的就会受到影响,如果我们想要B接口优先,此时我们就可以配置一条当B接口超过qps阈值时,就把A接口限流。

听起来是不是特别别扭, 如果这俩接口有思考能力,我自行脑补出了以下场景:

B接口:我超速了,警察,快把A接口逮捕了,它影响到我超速了。

A接口:???

在代码里面新增一个foo/test2接口,重启服务

在控制台增加配置

以上配置表示:当/foo/test接口达到qps为10的阈值时,就对/foo/test2进行限流

测试方式:使用jmeter对/foo/test接口进行压测,然后再请求/foo/test2看看是否被限流了

假装已经开始对/foo/test接口进行压测了,请求/foo/test2

可以看到,这里随便请求了一下就返回了限流提示

链路

链路模式和关联模式有点像,但是不再是我影响你这种关系了。而指的是如果一个资源被两个接口所访问,那么我们可以指定只对其中某个接口进行限流。

还是那个例子,FooService同时被A接口和B接口所访问,此时如果想对UserService作qps为10的限流,之前的方式就是直接配置一个FooServiceqps阈值为10的规则,这样A,B两个接口都会被限制访问,但是如果我只想对A接口的访问进行限流,B接口的不管,那么就需要使用链路模式了。

但是但是,在目前最新的版本(1.8.2)里,这个规则不生效!

并发线程数

概念

不同于qps,并发线程数限定的是某个资源的线程数并发上线,用于保护业务线程池不被慢调用耗尽。

前段时间我的同事就刚好遇上了这样的问题:

某个接口因为一个bug,线程被阻塞了, 导致所有打到这个接口的请求全部陷入阻塞状态。我们知道tomcat的总线程数是有限的,出现这个问题之后的一小会,这个服务的所有线程都阻塞在这个接口上了,tomcat线程池直接耗尽,所有接口502

如果当时该接口的并发数存在一个阈值,那这个bug所涉及的范围就可以控制在很小的范围内了。

演示

新增一个接口,用于模拟线程并发情况

public String test3() throws InterruptedException {
// 线程停顿1秒,
TimeUnit.SECONDS.sleep(1);
return "ok";
}

重启服务,访问/foo/test3接口触发初始化

在控制台添加配置

开启jmeter进行压测该接口,然后在其他地方访问一下(为了好观察)

规则生效了。

其他的流控模式与qps方式相同,这里就不演示了

小结

本文介绍了Sentinel的流控规则,其中根据场景分为QPS限流以及并发线程数限流。

这两个限流策略的共同点为:可以对来源进行针对限流,支持直接,关联,链路三种流控模式。

QPS限流还包含了三种流控效果: 快速失败、预热、排队等待。

至于是否集群那个选项小伙伴就当没看到哈,我搞不定这个,我认怂

实在想研究,官方文档在此:https://github.com/alibaba/Sentinel/wiki/集群流控

本文案例代码:https://gitee.com/lzj960515/my-micro-service-demo

追更,想要了解更多精彩内容,欢迎关注公众号:程序员阿鉴

个人博客空间:https://zijiancode.cn

Sentinel之流控规则的更多相关文章

  1. Sentinel Dashboard(基于1.8.1)流控规则持久化到Nacos——涉及部分Sentinel Dashboard源码改造

    前言 之前虽然也一直在使用sentinel实现限流熔断功能,但却没有好好整理之前看的源码与资料,今天有时间将之前自己整理过的资料写成一篇博文,或者是是一篇关于Sentinel(基于目前最近版本1.8, ...

  2. 一个名叫Sentinel-Rules-SDK的组件,使得Sentinel的流控&熔断规则的配置更加方便

    原文链接:一个名叫Sentinel-Rules-SDK的组件,使得Sentinel的流控&熔断规则的配置更加方便 1 Sentinel 是什么? 随着微服务的流行,服务和服务之间的稳定性变得越 ...

  3. Spring Cloud & Alibaba 实战 | 第十二篇: 微服务整合Sentinel的流控、熔断降级,赋能拥有降级功能的Feign新技能熔断,实现熔断降级双剑合璧(JMeter模拟测试)

    目录 一. Sentinel概念 1. 什么是Sentinel? 2. Sentinel功能特性 3. Sentinel VS Hystrix 二. Docker部署Sentinel Dashboar ...

  4. SpringBoot 2.0 + Nacos + Sentinel 流控规则集中存储

    前言 Sentinel 原生版本的规则管理通过API 将规则推送至客户端并直接更新到内存中,并不能直接用于生产环境.不过官方也提供了一种 Push模式,扩展读数据源ReadableDataSource ...

  5. 线上应用接入sentinel的第一个流控规则

    sentinel接入第1个应用A以及控制台,已经上线一段时间了,本周接入了第2个应用B: 因为测试同学只有几个,没有压测团队.测试平台.. 各接口能承载的最大qps不确定 ,接入的应用暂时都没有配置规 ...

  6. Sentinel流控规则

    流控规则 注:Sentinel的监控页面一开始是没有东西,需要对监控的服务发起请求后才会出现 资源名:唯一名称,默认请求路径 针对来源:Sentinel可以针对调用者进行限流,填写微服务名,指定对哪个 ...

  7. sentinel流控规则校验之源码分析

    前言: 上节给大家把sentinel流控整个执行大致过了,但涉及到最核心的流控算法还没有讲,先提前说明一下 sentinel用的流控算法是令牌桶算法,参考了Guava的RateLimiter,有读过R ...

  8. 什么!Sentinel流控规则可以这样玩?

    项目源码地址:公众号回复 sentinel,即可免费获取源码 前言 上一篇文章中,我们讲解了关于sentinel基本介绍以及流控规则中直接和快速失败的效果,有兴趣的可以去看上一篇文章,今天,我们给大家 ...

  9. sentinel的四种流控规则介绍

    sentinel的四种流控规则介绍 今天的内容我们主要围绕四个点进行展开介绍. 流控模式 :关联.链路 流控效果 :Warm Up.排队等待 这四点具体是什么意思呢? 首先启动项目:cloud-ali ...

随机推荐

  1. 在Vs code中使用sftp插件以及连接windows远程sftp协议部署指导(解决vscode的sftp插件中文目录乱码问题)

    一.启动SFtp 二.上手vs code SFTP插件 2.1 初始配置 2.2解决乱码问题 三.SFTP配置 3.1常用配置 3.2示例配置 四.SFTP使用 五.扩展阅读 一.启动SFtp 话说小 ...

  2. js 开始

    hello world 开始JavaScript 是一种脚本语言,它的解释器被称为 JavaScript 引擎.JavaScript 被发明用于在 HTML 网页上使用,给HTML网页增加动态功能.J ...

  3. Maven 依赖调解源码解析(一):开篇

    本文是系列文章<Maven 源码解析:依赖调解是如何实现的?>第一篇,主要做个开头介绍.并为后续的实验做一些准备.系列文章总目录参见:https://www.cnblogs.com/xia ...

  4. myeclipse trial expired暂时解决办法

    运行以下程序,生成key: import java.io.*; public class MyEclipseGen { private static final String LL = "D ...

  5. [cf1168E]Xor Permutations

    (与题目中下标不同,这里令下标为$[0,2^{k})$来方便运算) 根据异或的性质,显然有解的必要条件是$\bigoplus_{i=0}^{2^{k}-1}a_{i}=0$ 在此基础上,我们考虑构造- ...

  6. 微信小程序的优点(水一篇)

    - 快速的加载 - 更强大的能力 - 原生的体验 - 易用且安全的微信数据开放 - 高效和简单的开发 摘自微信官方文档 https://developers.weixin.qq.com/minipro ...

  7. springboot启动流程1

    public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.res ...

  8. Spring Cloud Alibaba微服务一站式解决方案-开篇v2.2.1.RELEASE

    学习路线 **本人博客网站 **IT小神 www.itxiaoshen.com 生态概述 架构演进 什么是微服务 https://martinfowler.com/microservices/ Mic ...

  9. 深入理解Redis 数据结构—简单动态字符串sds

    Redis是用ANSI C语言编写的,它是一个高性能的key-value数据库,它可以作用在数据库.缓存和消息中间件.其中 Redis 键值对中的键都是 string 类型,而键值对中的值也是有 st ...

  10. Redis基本数据类型底层数据结构

    Redis数据类型底层数据结构 Redis目前基本的数据类型有String.List.Set.ZSet.Hash五种,首先Redis是C语言开发的,所以底层就是用C语言封装数据结构或者C语言本身提供的 ...