搞懂限流算法这一篇就够了 No.154
点击上方“方志朋”,选择“设为星标”
做积极的人,而不是积极废人
TL;DR(too long don't read)
限流算法:计数器、滑动窗口、漏桶、令牌桶。
限流方案:Guava的RateLimiter、Alibaba Sentinel
大家都知道,对于高并发的业务场景,我们为了保障服务的稳定,经常会祭出三大利器:缓存、熔断降级和服务限流。
服务限流作为一个核心的自保护机制,能够在非常高并发的情况下,其他机制都无法保障降级的情况下,保护系统不崩溃,以免产生雪崩效应。
我们设想这么一个场景。
名词解析,QPS(query per second 每秒查询数)
单台机器可以承受的最高QPS为 100,我们有5台机器,日常服务 QPS 为 300。
那么其实我们是毫无压力,根据前置的负载均衡服务器,每台 300/5 = 60 。可以完美提供服务。
今天,老板突然搞了一波促销,QPS 达到了 800。
好了,机器 A 的 QPS 达到了 160,已经完全扛不住了,直接宕机了。这时候集群只剩下4台机器,QPS依然是 800。平均分配到剩下的 4 台机器上,每台机器 200。就这样,机器一台一台倒下,雪崩了。
那如果我们的系统有限流,会是什么样的场景呢?
QPS 达到了800。好了,机器 A 的 QPS 达到了 160,但因为限流了100,所以机器依然正常运行,只是损失了 60 QPS 的客户,整个集群整体还是正常运行的。这时候就给开发和运营们留下时间开始降级扩容 bala bala....
可见,限流对于系统的自保护是非常重要的存在,然而很多工程师并没有正视它,或者说只是会用,并不清楚背后的原理。先说下结论。
常见的限流算法有:计数器、滑动窗口、漏桶、令牌桶。
常见的限流方案有:Guava的RateLimiter、基于分布式锁的令牌桶、Alibaba Sentinel
<计数器>
一般来说,计数器比较粗暴,就是看单位时间内,所接受的 QPS 的请求有多少,如果超过阈值,则直接拒绝服务。大概场景是这样的。
有这么一个煎饼果子摊,摊主叫老王,上面的老板说你一分钟只许卖 6 个饼(计数限流1分钟6个)。如果在前 0.1 秒已经有人预定了6个饼而且老王刚好神来之笔也已经做完了,那么老王在接下来的 59.59 秒只能坐在凳子上,等待下一分钟的到来。
看,简单粗暴的计数器,在系统性能允许的情况下,可能会浪费非常多的资源
<滑动窗口>
滑动窗口可以看做计数器的精细化实现,之前只能一分钟一分钟往前赶,现在可以根据实现的精细化 一秒一秒往前赶,虽然整体原理还是靠计数器。既往不咎,是一个适当时间里懂得忘记的计数器。
<漏桶>
看这张图可以看到漏桶的基础原理,我们会用一个桶作为缓冲区,所有的请求都先丢到桶里。系统以恒定速率慢慢消化这些请求。比较常见的实现就是队列,用一个缓冲区来保存没处理的请求,然后消费者恒定速度抓取一些请求进行处理。
有这么一个煎饼果子摊,摊主叫老王,老王一秒钟只能做一个饼。现在来了 100个顾客,那怎么办呢?就排队啊。老王的老婆啊潘,把这批顾客引导到了旁边的空地上站着,并给他们一个一个标记了号码。老王做完一个,就大喊一声号码,对应的的顾客就过来把饼拿走。
你看看这里的要求,要求有空地(桶),而且顾客等得起(等待时间)。
<令牌桶>
我们会有一个令牌管理员,按照一定的策略往令牌桶里放令牌。系统每接受到一个请求的时候,都会请求要一个令牌。如果拿到令牌,那么就处理这个请求,拿不到就直接拒绝这个请求。那么只要令牌发放的策略正确,这个系统就不会被拖垮,也能对机器的利用率更高。
有这么一个煎饼果子摊,摊主叫老王,老王也不知道自己能做几个饼。老王的老婆阿潘在老王旁边放了一个桶,里边放了一些牌子,并告诉老王,"我帮你看着,你看见有令牌你就做就是了"。 现在来了 100个顾客,老王挖粪涂墙,原来一秒钟只能做一个,现在一秒钟可以做好多个,老王不看顾客了,每次能拿到令牌就直接做。老王的老婆啊潘,眼睛一直看着老王,看看他手抖没是不是要上厕所了。如果手抖了或者可能扛不住了,那就少放一点令牌歇一歇。但如果一次性来了五个 vip 客户,那阿潘就不管那么多了,就直接丢多几个令牌让老王忙一点。
我们看到,令牌桶的方法可以根据系统负载,实时调节系统的处理能力,能够允许一定量级的瞬时高峰流量的快速消化。
好嘞。方案和算法基本上就说完了,现在聊聊限流关于现有的实现,我们当然是非常希望可以不做过多的开发,开箱即用完事,幸运的是,我们已经有不少的开源实现,就算自己实现也不会特别难。
<RateLimiter>
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>25.1-jre</version></dependency>
使用Guava的RateLimiter进行限流控制,主要有两种核心模式,SmoothBursty 和 SmoothWarmingUp。SmoothBursty 每秒钟发放N个令牌,也允许预先借用一定数量的令牌。SmoothWarmingUp,在系统刚刚启动的时候,只会按最低阈值发放令牌,然后逐渐增加到设定的最高阈值。
RateLimiter smoothBuisty = RateLimiter.create(1);
RateLimiter smoothWarmingUp = RateLimiter.create(1 , 1 , TimeUnit.SECONDS);
smoothBuisty.acquire();
smoothWarmingUp.acquire(5);
acquire() 方法会阻塞,直到令牌桶返回,还可以一次性拿到N个令牌。但是 RateLimiter 是单机版的,如果我们想要实现分布式,那可以基于 RateLimiter 的原理,实现以下分布式的,可以使用 Redis 等分布式锁来进行实现。
<Alibaba Sentinel>
https://github.com/alibaba/Sentinel.git
Sentinel 是一个带配置中心的分布式缓存,以 "资源名称" 为统计点,提供了多种方式的限流方案,可以基于 QPS、线程数,甚至系统 load 进行集群规模的限流。Sentinel 在整个生态的位置是这样的。
使用限流的代码非常简单,只需要定义一个 String 类型的资源,作为唯一标识,Sentinel 会根据规则进行限流。
try (Entry entry = SphU.entry("HelloWorld")) {// Your business logic here.System.out.println("hello world");
} catch (BlockException e) {// Handle rejected request.e.printStackTrace();
}
定义限流规则的也代码非常简单,只需要定义一个 String 类型的资源,作为唯一标识,Sentinel 会根据规则进行限流。
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);
}
也提供了 DashBoard 进行实时规则调整。
最后总结一下今天的结论
限流算法:计数器、滑动窗口、漏桶、令牌桶。
限流方案:Guava的RateLimiter、基于分布式锁的令牌桶、Alibaba Sentinel
热门内容:
那些年,我们见过的 Java 服务端乱象
Linus 谈 Git 的设计思想,顺带骂了一堆人(视频)
彻底透析SpringBoot jar可执行原理
分享:手把手教你如何免费且光荣地使用正版IntelliJ IDEA
面试官:谈谈你对 Spring AOP 的了解?请加上这些内容,绝对加分!
国内拉取google Kubernetes镜像
Apache架构师的30条设计原则!
盘点阿里巴巴 15 款开发者工具
喜欢就点个"在看"呗^_^
搞懂限流算法这一篇就够了 No.154相关推荐
- 搞懂限流算法这一篇就够了
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 TL;DR(too long don't read) 限流算法:计 ...
- springaop事务逻辑原理_搞懂Spring AOP,这一篇就够了
看了这篇文章,如果你还是不会用AOP来写程序,请你打我!! =.=||| 引言 Spring AOP是一个对AOP原理的一种实现方式,另外还有其他的AOP实现如AspectJ等. AOP意为面向切面编 ...
- 【PCB干货】是开窗还是盖油?想搞懂过孔工艺,看这篇就够了!
过孔,即在覆铜板上钻出所需要的孔,它承接着层与层之间的导通,用于电气连接和固定器件.过孔是PCB生产至关重要且不可缺少的一环. 在PCB生产中,常见的过孔工艺有:过孔盖油.过孔塞油.过孔开窗.树脂塞孔 ...
- 想要搞懂数据可视化,看这篇就够了!
最近很多朋友跟我抱怨:为了公司数据好看,老板一个劲地想要数据可视化,以为可视化就是画画图表这么简单,可苦了自己天天加班做数据,但其实老板根本不懂可视化! 确实,数据可视化无疑是当今最火热的词,不管是做 ...
- 亿级流量治理系列:常用的限流算法有哪些?
前言 上篇文章<为什么大公司都要做流量治理?>跟大家聊了下做流量治理的真正目的是什么.如果你要开发一个流量治理的平台或者一个限流的框架,那么必不可少的就是要选择一种合适的限流算法.本篇文章 ...
- 【限流01】限流算法理论篇
微服务就是将复杂的大应用拆分成小的应用,这样做的好处是各个应用之间独立开发.测试.上线,互不影响.但是服务拆分之后,带来的问题也很多,我们需要保障微服务的正常运行,就需要进行服务治理.常用手段有:鉴权 ...
- 【限流02】限流算法实战篇 - 手撸一个单机版Http接口通用限流框架
本文将从需求的背景.需求分析.框架设计.框架实现几个层面一步一步去实现一个单机版的Http接口通用限流框架. 一.限流框架分析 1.需求背景 微服务系统中,我们开发的接口可能会提供给很多不同的系统去调 ...
- 服务高可用利器——限流算法介绍与示例
文章目录 0.前言 1.计数器 1.1 简介 1.2 示例 2.滑动窗口 2.1 简介 2.2 示例 3.漏桶 3.1 简介 3.2 示例 4.令牌桶 4.1 简介 4.2 示例 5.小结 参考文献 ...
- 限流算法-常见的4种限流算法
首先我们先来看看什么是限流? 限流是指在系统面临高并发.大流量请求的情况下,限制新的流量对系统的访问,从而保证系统服务的安全性. 另一种解释:在计算机网络中,限流就是控制网络接口发送或接收请求的速率, ...
最新文章
- Red Hat Linux 安装教程
- windows server 2008 r2 enterprise ,惠普DL 580 G7服务器报,事件 ID: 47错误。
- 【Android 逆向】整体加固脱壳 ( 脱壳点简介 | 修改系统源码进行脱壳 )
- 野火开发版屏幕_盘一盘那些年我们常用的物联网开发板!
- 高并发01_synchronized
- python修改excel后打印_python 处理excel并打印excel
- ssl1063-统计数字【哈希表】
- JavaScript 设计模式——策略模式
- python 更换列名
- gaussdb 日常运维命令总结【01】
- The requested URL /xxxx.html was not found on this server web项目报错
- 与卿共赴鸿蒙是什么意思,《山河令》看来周子舒是真的很爱温客行,君心似我心,此生无憾...
- LeetCode题解系列--309. Best Time to Buy and Sell Stock with Cooldown
- 【学生毕业设计】基于web学生信息管理系统网站的设计与实现(13个页面)
- Unity可编程渲染管线系列(七)反射(镜面和环境)
- datatable 属性介绍
- 基于微信小程序的汽车租赁系统源码
- Layui-五星好评
- 鸡尾酒疗法(C语言)
- 7-20 电话聊天狂人(25 分)(Hash模板)
热门文章
- [bzoj4562][Haoi2016]食物链_记忆化搜索_动态规划
- 2017 Multi-University Training Contest 3 hdu 6063
- HDU 1877 另一个版本 A+B
- [置顶] 单例模式lua实现
- 动软代码生成器教程——懒人有福了
- 【组队学习】【34期】Python(一级)
- 如何利用离散Hopfield神经网络进行数字识别(1)
- 联邦学习应用思考:需求还是方法?
- 从最强AI算力到“元脑”2.0,智算加速产业变革
- 3行Python代码就能获取海量数据?