一、限流思路

常见的系统服务限流模式有:熔断、服务降级、延迟处理和特殊处理四种。

1、熔断

将熔断措施嵌入到系统设计中,当系统出现问题时,若短时间内无法修复,系统会自动开启熔断开关,拒绝流量访问,避免大流量对后端的过载请求。

除此之外,系统还能够动态监测后端程序的修复情况,当程序已恢复稳定时,就关闭熔断开关,恢复正常服务。

常见的熔断组件有 Hystrix 以及阿里的 Sentinel。

在Spring Cloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制。

熔断机制的注解是@HystrixCommand,Hystrix会找有这个注解的方法,并将这类方法关联到和熔断器连在一起的代理上。

2、服务降级

将系统的所有功能服务进行一个分级,当系统出现问题需要紧急限流时,可将不是那么重要的功能进行降级处理,停止服务,保障核心功能正常运作。

例如在电商平台中,如果突发流量激增,可临时将商品评论、积分等非核心功能进行降级,停止这些服务,释放出机器和 CPU 等资源来保障用户正常下单。

这些降级的功能服务可以等整个系统恢复正常后,再来启动,进行补单/补偿处理。

除了功能降级以外,还可以采用不直接操作数据库,而全部读缓存、写缓存的方式作为临时降级方案。

熔断&降级

  • 相同点:目标一致 都是从可用性和可靠性出发,为了防止系统崩溃;用户体验类似,最终都让用户体验到的是某些功能暂时不可用。
  • 不同点:触发原因不同,服务熔断一般是某个服务(下游服务,即被调用的服务)故障引起;
  • 而服务降级一般是从整体负荷考虑。

3、延迟处理

延迟处理需要在系统的前端设置一个流量缓冲池,将所有的请求全部缓冲进这个池子,不立即处理。后端真正的业务处理程序从这个池子中取出请求依次处理,常见的可以用队列模式来实现。

这就相当于用异步的方式去减少了后端的处理压力,但是当流量较大时,后端的处理能力有限,缓冲池里的请求可能处理不及时,会有一定程度延迟。

4、特权处理

这个模式需要将用户进行分类,通过预设的分类,让系统优先处理需要高保障的用户群体,其它用户群的请求就会延迟处理或者直接不处理。

二、限流算法

常见的限流算法有三类:计数器算法、漏桶算法和令牌桶算法。

1、计数器算法

计数器算法是限流算法中最简单最容易的一种,如上图每分钟只允许100个请求,第一个请求进去的时间为startTime,在startTime + 60s内只允许100个请求 。

当60s内超过十个请求后,则拒绝请求;不超过的允许请求,到第60s 重新设置时间。

View Code

利用计数器算法比如要求某一个接口,1分钟内的请求不能超过100次。

可以在开始时设置一个计数器,每次请求,该计数器+1;如果该计数器的值大于10并且与第一次请求的时间间隔在1分钟内,那么说明请求过多则限制请求直接返回或不处理,反之。

如果该请求与第一次请求的时间间隔大于1分钟,并且该计数器的值还在限流范围内,那么重置该计数器。

计算器算法虽然简单,但它有一个很致命的临界问题。

上图可以看出假若有一个恶意用户,他在0:59时,瞬间发送了100个请求,并且在1:00时,又瞬间发送了100个请求,那么其实这个用户在 1秒后,瞬间发送了200个请求。

而上述计数器算法规定的是1分钟最多100个请求,也就是每秒钟最多1.7个请求,而用户通过在时间窗口的重置节点处突发请求,可以瞬间超过限流的速率限制,这个漏洞可能会瞬间压垮服务应用。

上述漏洞问题其实是因为计数器限流算法统计的精度太低,可以借助滑动窗口算法将临界问题的影响降低。

2、滑动窗口

上图中,整个红色的矩形框表示一个时间窗口。在计数器算法限流的例子中,一个时间窗口就是一分钟。在这里将时间窗口进行划分,比如图中,将滑动窗口划成了6格,每格代表的是10秒钟。每过10秒钟,时间窗口就会往右滑动一格。每一个格子都有自己独立的计数器counter,比如当一个请求在0:35秒的时候到达,那么0:30~0:39对应的counter就会加1。

那么滑动窗口是怎么解决刚才的临界问题的呢?

上图,0:59到达的100个请求会落在灰色的格子中,而1:00到达的请求会落在橘黄色的格子中。当时间到达1:00时,窗口会往右移动一格,那么此时时间窗口内的总请求数量一共是200个,超过了限定的100个,所以此时能够检测出来触发了限流。

经过比较发现发现,计数器算法其实就是滑动窗口算法。只是它没有对时间窗口做进一步地划分,所以只有1格。所以,当滑动窗口的格子划分得越多,则滑动窗口的滚动就越平滑,限流的统计就会越精确。

3、漏桶算法

漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会超过桶可接纳的容量时直接溢出,可以看出漏桶算法能强行限制数据的传输速率。

使用漏桶算法,可以保证接口会以一个常速速率来处理请求,所以漏桶算法必定不会出现临界问题。

漏洞算法实现类:

View Code

使用漏桶限流:

View Code

漏洞算法的两个优点:

  • 削峰:有大量流量进入时,会发生溢出,从而限流保护服务可用。
  • 缓冲:不至于直接请求到服务器,缓冲压力,消费速度固定,因为计算性能固定。

4、令牌桶算法

令牌桶算法思想:以固定速率产生令牌,放入令牌桶,每次用户请求都得申请令牌,令牌不足则拒绝请求或等待。

上图,令牌桶算法会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。

View Code

令牌桶算法默认从桶里移除令牌是不需要耗费时间的,如果给移除令牌设置一个延时时间,那么实际上又采用了漏桶算法的思路。

至于临界问题的场景,在0:59秒的时候,由于桶内积满了100个token,所以这100个请求可以瞬间通过。但是由于token是以较低的速率填充的,所以在1:00的时候,桶内的token数量不可能达到100个,那么此时不可能再有100个请求通过。所以令牌桶算法可以很好地解决临界问题。
漏桶与令牌桶算法的区别

  • 主要区别在于“令牌桶算法”能够强行限制数据的传输速率,而“令牌桶算法”在能够限制数据的平均传输速率外,还允许某种程度的突发传输。
  • 在“令牌桶算法”中,只要令牌桶中存在令牌,那么就允许突发地传输数据直到达到用户配置的门限,因此它适合于具有突发特性的流量。
  • 令牌桶算法由于实现简单,且允许某些流量的突发,对用户友好,所以被业界采用地较多。
  • 具体情况具体分析,只有最合适的算法,没有最优的算法。

基于谷歌RateLimiter实现限流

Google开源工具包Guava提供了限流工具类RateLimiter,该类基于令牌桶算法(Token Bucket)来完成限流,非常易于使用。RateLimiter经常用于限制对一些物理资源或者逻辑资源的访问速率,它支持两种获取permits接口,一种是如果拿不到立刻返回false(tryAcquire()),另一种会阻塞等待一段时间看能不能拿到(tryAcquire(long timeout, TimeUnit unit))。

View Code

三、集群限流

前面几种算法都属于单机限流的范畴,但简单的单机限流仍无法满足复杂的场景。比如为了限制某个资源被每个用户或者商户的访问次数,5s只能访问2次,或者一天只能调用1000次,这种场景单机限流是无法实现的,这时就需要通过集群限流进行实现。

可以使用Redis实现集群限流,大概思路是每次有相关操作的时候,就向redis服务器发送一个incr命令。

redisOperations.opsForValue().increment()

比如需要限制某个用户访问某个详情/details接口的次数,只需要拼接用户id和接口名,加上当前服务名的前缀作为redis的key,每次该用户访问此接口时,只需要对这个key执行incr命令,再这个key带上过期时间,就可以实现指定时间的访问频率。

原文链接:
https://www.cnblogs.com/taojietaoge/p/15744243.html

作者:涛姐涛哥

如果觉得本文对你有帮助,可以转发关注支持一下

赶紧趁着金三银四的尾巴来学习,钻五直接面阿里。阿里教你怎么玩转限流方案。相关推荐

  1. 抓住金三银四的尾巴,解锁程序员面试《刷题神器》

    点赞 ➕ 评论 ➕ 收藏 = 三连再看你最帅 刷题 不仅能掌握知识,快速学习进步. 更能轻松搞定面试,尤其是有的大厂 钟爱问算法题,你不刷就不会,就会被pass.同时,刷题能陶冶情操,避免老年痴呆

  2. 二位四进制计数器_金三银四还在看JVM这一块?看完这篇万字JVM面试解析就够了...

    金三银四你必备的学习笔记 Java面试核心知识点笔记+高级架构面试知识点整理+互联网Java工程师必备的1080道面试解析​shimo.im Java内存区域 说一下 JVM 的主要组成部分及其作用? ...

  3. 金三银四跳槽面试季,我整理前端知识做了个网站

    每年的金三银四,都将迎来求职面试的一个高峰期,为什么会有那么多的求职需求? 多是因为以下几个来源: 已拿 offer 等年终奖的:年前已经找到机会,领了年终奖辞职要到新公司报到的 临时起意要辞及裸辞的 ...

  4. springboot listener_Springboot 全套面试提升宝典,为金三银四冲刺

    简介: Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配 ...

  5. 【金三银四】一个问题就知道你会不会CSS了

    引言 金三银四,特地整理一份面试题,现介绍本文特色: 1.适合前端,需要面试找工作 2.即将毕业面临实习,积累经验 3.从务实基础到彻底弄懂 4.探索框架源码,研究前端必备算法 5.直击阿里.腾讯.美 ...

  6. 程序员一年中最佳跳槽时间是什么时候?真的是金三银四?

    普遍说法是金三银四.金九银十,三四.九十月份是跳槽旺季,但是我感觉不一定是性价比最佳的时候. 就拿我管理的技术团队来说吧,我们团队有100多人.每年3.4月份跳槽的人确实是最多,原因也很简单.一般来说 ...

  7. 金三银四跳槽的正确姿势你掌握了么?

    金三银四跳槽的正确姿势,一文带你职场转型!金三银四这的是跳槽的黄金期吗?还有你是真的做好跳槽的准备了吗? 人在职场身不由己,跳槽亦一个无法回避的问题.大部分人跳槽是因为有了更好的工作机会或者诱人的薪酬 ...

  8. 金三银四跳槽季求职指南

    又到了一年一度的金三银四跳槽季了.大家伙儿肯定都有一定的想法. "出去试试水,看看自己市场价值" "这家早干烦了,赶紧换,不想当工具人了" "老板有毛 ...

  9. 金三银四,写个漂亮的技术简历

    金三银四跳槽季马上就要来了,最近招聘和求职市场明显火热了. 这几天有些朋友找我内推工作,我也使劲推了一波.不过我发现大家的简历还是需要修饰一下,虽然有些朋友已经工作多年了,但是简历里面依然看不出招聘团 ...

最新文章

  1. [MATLAB]从已知矩阵中取出子阵
  2. [LeetCode] Single Number 单独的数字
  3. UA OPTI512R 傅立叶光学导论 衍射例题
  4. 全局组、域本地组、通用组到底有什么区别?它们之间的关系如何?
  5. Resources.getResourceAsStream用法
  6. Linux 6.8 源码安装MySQL8.0
  7. 想有一个自己的WEB产品
  8. lol服务器维修2020,lol2020年5月29日停机维护到几点 英雄联盟维护公告是什么
  9. Java实现常见的排序算法
  10. java解析魔兽争霸3录像_《魔兽争霸》的录像,为什么长达半小时的录像大小只有几百 KB?...
  11. mac苹果电脑如何读取ntfs格式软件?
  12. 华为手机怎么连接苹果电脑?
  13. 工作经验的Java学习心得
  14. 移动端APM网络监控与优化实践
  15. Mysql DBA 高级运维学习之路-mysql数据库乱码问题
  16. openwrt广告屏蔽大师修复补丁luci-app-adbyby plus + lite
  17. 电脑无法连接WiFi,一直显示无法连接此网络
  18. ESXi 社区版网卡驱动
  19. 如何将数据库中text字段中返回的数据转换成数组的形式,并且将字符串的数字转换成数字的形式显示
  20. Capl编程xml标签语法(4) —— CAN报文周期检测/错误帧检测/信号改变检测。。。

热门文章

  1. 数学建模二:TOPSIS法(优劣解距离法) 附代码详解
  2. vue-lazyload使用
  3. 分布式专题(六)分布式事物
  4. 先于服务器端的Android开发,基于mock和fiddler(win)和whistle(linux)
  5. 2010-2020年农业农村重要经济指标
  6. mw310r无线路由器怎么设置虚拟服务器,水星MW310R V3路由器无线桥接怎么设置
  7. java 基础 ppt_Java基础培训课件.ppt
  8. 影响论文发表的因素有哪些
  9. 极客编程小挑战#30:用CSS3实现各种钟表的显示效果
  10. Mybatis-plus操作json字段实战