专栏首页码洞关于服务限流的一些思考

关于服务限流的一些思考

限流的价值感

限流必然是很有价值的,在系统资源不足时面对外部世界的不确定性(突发流量,超预期的用户)而形成的一种自我保护机制。

但是价值感是很低的,因为99.99%的时候系统总是工作在安全线之下,甚至一年到头都碰不到一次撞线的机会。这就好比法律,它始终存在,但是大部分时候对于大多数人它几乎不存在,或者说感知不到它的存在。

一个软件系统往往会存在很多隐藏的bug,最常用的功能bug往往很少。不常用的功能因为长时间不被人关注缺少重现的机会会一直隐藏在那里伺机爆发。而且随着软件系统的迭代更新,不受关注的功能极有可能被测试人员忽视从覆盖测试中被遗忘了。结果一旦遇到了突发的场景(墨菲定律),这一段被忽视的存在bug的代码逻辑被唤醒的,然后就会导致系统出错甚至奔溃。限流功能就是这些不被关注的功能之一。

为了解决限流的价值感问题,工程师们需要对限流功能进行周期性演练,需要使用单元测试和压力测试进行多次重演。总之就是想尽各种办法来触发限流功能撞线,以重现那一段生产环境几乎不会被执行的 else 逻辑。

限流算法

业界较为常见的两个基础限流算法是漏斗算法和令牌算法,这两个算法大同小异。漏斗算法可以理解为每一个请求都会消耗一定的空气,而漏斗里的空气是有限的,通过漏水的方式获得空气的速率也是有限的。令牌算法可以理解为每一个请求都会消耗一个令牌,而令牌桶生产令牌的能力是有限的,存放令牌的桶容量也是有限的。

生产环境的请求QPS在曲线上看是平滑的,因为大多数统计系统都采用了平滑算法(一段时间内的均值),但是在实际的运行过程中会有一定的随机性和波动性,会有突发的一些离群点,这个一般被称之为突发流量。

限流算法需要考虑这种突发流量,它应该可以短期内容忍,容忍也是有上限的,就是容忍时间必须很短。上面两个算法都具有这个容忍能力,这个容忍就体现在漏斗中空气的积蓄,令牌桶中令牌的积蓄,积蓄耗光就达到了容忍的上限。

分布式限流

如果你的应用是单个进程,那么限流就很简单,请求的计数算法都可以在内存里完成。限流算法几乎没有损耗,都是纯内存的计算。但是互联网世界的应用都是多节点的分布式的,每个节点的请求处理能力还不一定一样。我们需要考虑的是这多个节点的整体请求处理能力。

单个进程的处理能力是1w QPS 并不意味着整体的请求处理能力是 N * 1w QPS,因为整体的处理能力还会有共享资源的能力限制。这个共享资源一般是指数据库,也可以是同一台机器的多个进程共享的 CPU 和 磁盘 等资源,还有网络带宽因素也会制约整体的请求量。

这时候请求的计数算法就需要集中在一个地方(限流中间件)来完成。应用程序在处理请求之前都需要向这种集中管理器申请流量(空气、令牌桶)。 每一个请求都需要一次网络 IO,从应用程序到限流中间件之间。

比如我们可以使用 Redis + Lua 来实现这个限流功能,但是 Lua 的性能要比 C 弱很多,通常这个限流算法能达到 1w 左右的 QPS就到顶了。还可以使用 Redis-Cell 模块,其内部使用 Rust 实现,它能达到 5w 左右的 QPS 也就到极限了。这时候它们都进入了满负荷状态,但是在生产环境中我们不会希望它们一直满负荷工作。

那如何完成 10w QPS 的限流呢?

一个简单的想法就是将限流的 key 分桶,然后使用 Redis 集群来扩容,让限流的申请指令经过客户端的 hash 分桶后打散的集群的多个几点,借此分散压力。

那如何完成 百万 QPS (1M)的限流呢?

如果还使用上面的方法那需要的带宽资源和Redis实例也是惊人的。我们可能需要几十个 Redis 节点,外加上百M(1M * 20 字节 * 8) 的带宽来完成这个工作。

这时我们必须转换思路,不再使用这种集中管控的方式来工作了。就好比一个国家人太多了,就要分省、市、县来分别进行管理 —— 放权。

我们将整体的 QPS 按照权重分散多每个子节点,每个字节点在内存中进行单机限流。如果每个节点都是对等的,那么每个子节点就可以分得 1/n 的 QPS。它的优点在于分散了限流压力,将 IO 操作变成纯内存计算,这样就可以很轻松地应对超高的 QPS 限流。但是这也增加了系统的复杂度,需要有一个集中的配置中心来向每个子节点来分发 QPS 阈值,需要每个应用字节点向这个配置中心进行注册,需要有一个配置管理后台来对系统的 QPS 分配进行管理。如果没有一个完善易用成熟的开源软件的话,这样的一个控制中心服务和SDK往往需要一个小型团队来完成。这对于中小型企业来说往往是承受不起的,再想想限流的价值感如此之低,这种可能性就更加微乎其微了。

本文分享自微信公众号 - 码洞(codehole),作者:佬钱

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 天下无难试之ArrayList面试刁难大全

    ArrayList可能是Java数据结构中最简单的一种了,即使一个非Java程序员可能也知道这个数据结构,因为所有的语言中都有这样的类似的数据结构。可是在经历过...

    老钱
  • 保卫 Java 应用程序的安全沙箱机制你需要了解一下

    这明显是一个安全检查代码,检查的是你是否有访问磁盘路径的权限,为什么 Java 语言需要这样的安全检查代码呢?我们再看看客户端套接字的 connect 函数源...

    老钱
  • 《Redis深度历险》《深入理解RPC》答读者问

    老钱,你好,不知道从哪个机缘巧合关注了公众号,看老钱的文章,收获很大,最近在读redis小册,对我做业务开发的帮助挺大的。我也买了好多书,看了很多博客,开了公众...

    老钱
  • 微服务架构下的分布式限流方案思考

    随着微服务的流行,服务和服务之间的稳定性变得越来越重要。缓存、降级和限流是保护微服务系统运行稳定性的三大利器。

    IT大咖说
  • Spring Cloud 入门教程9、服务限流/API限流(Zuul+RateLimiter)

    RateLimiter是Google开源的实现了令牌桶算法的限流工具(速率限制器)。http://ifeve.com/guava-ratelimiter/

    KenTalk
  • 限流--单机限流

    前边一篇《聊一聊限流》讲述了限流的原理和应用场景,以及两种常用的限流算法,此篇将详细讲一下限流的技术实现。由于现在的系统架构大多都变成了分布式架构,而非...

    Typhoon
  • 高并发场景下如何实现系统限流?

    在分布式高可用设计中,限流应该是应用最广泛的技术手段之一,今天一起来讨论一下,为什么需要限流,以及常见的限流算法都有哪些。

    MickyInvQ
  • Sentinel 集群限流设计原理

    为了充分利用硬件的资源,诸如 Dubbo 都提供了基于权重的负载均衡机制,例如可以将8C16G的机器设置的权重是4C8G的两倍,这样充分利用硬件资源,假如现在需...

    丁威
  • 6种 分布式限流方案,我替你整理好了

    合法性验证限流为最常规的业务代码,就是普通的验证码和 IP 黑名单系统,本文就不做过多的叙述了,我们重点来看下后两种限流的实现方案:容器限流和服务端限流。

    程序员内点事
  • 限流的6大狠招,附详细代码和评测结果

    为了上班方便,去年我把自己在北郊的房子租出去了,搬到了南郊,这样离我上班的地方就近了,它为我节约了很多的时间成本,我可以用它来做很多有意义的事,最起码不会因为堵...

    Java中文社群_老王

扫码关注云+社区

领取腾讯云代金券