OPE最近现在的平台维护是不是有点网站频繁维护?

2019 年 1 月 12 日由又拍云、OpenResty 中国社区主辦的 OpenResty × Open Talk 全国巡回沙龙·深圳站圆满结束,又拍云首席架构师张聪在活动上做了《 OpenResty 动态流控的几种姿势 》的分享。
OpenResty x Open Talk 全国巡回沙龙是由 OpenResty 社区、叒拍云发起的为促进 OpenResty 在技术圈的发展,增进 OpenResty 使用者的交流与学习的系列活动活动将会陆续在深圳、北京、上海、广州、杭州、成都、武汉等地举办,欢迎大家关注
张聪,又拍云首席架构师多年 CDN 行业产品设计、技术开发和团队管理相关经验,个人技术方向集中在 Nginx、OpenResty 等高性能 Web 服务器方面国内 OpenResty 技术早期推广者之一;目前担任又拍云内容加速部技术负责人,主导又拍云 CDN 技术平台的建设和发展

大家下午好,今天我主要和大家分享“在 OpenResty 上如何做动态的流量控制”将会从以下几个方面来介绍:

  • Nginx 如何做流控,介绍几种经典的速率和流量控制的指令和方法;
  • OpenResty 动态流控在又拍云的业务应用

我目前在又拍云负责 CDN 的架构设计和开发工作,又拍云早在 2012 年就开始接触 OpenResty 当时我们做调研选型,部分项目考虑用 Lua 来实现在此之前是基于 Nginx C 模块来做业务开发,一个防盗链模块就好几千行代码改成 Lua 之后大量减少了代码,并且整个開发的效率、维护的复杂度都降低了此外我们通过测试和性能对比,几乎没有多的损耗因为在这一层主要是字符串的处理,甚至在 LuaJIT 加速的情况下有很多的调用比我们原先用 C 写的函数还高效得多。

目前又拍云整个 CDN 代理层系统、对外开放的 API 系统、数据中心的网关系统、分咘式云存储代理层、逻辑层全部用 ngx_lua 进行了深度的改造又拍云内部几个不同业务的团队都在 OpenResty 技术栈上有多年的实践和经验积累。

又拍云开放了一个 upyun-resty 的仓库()我们内部孵化的开源项目以及对社区的补丁修复等都会发布在这个仓库。大家如果对又拍云这块的工作感兴趣可以關注这个仓库我们今年还会陆续把内部使用非常成熟的一些库放出来,包括今天讲的两个与限速有关的 Lua 库也已经开源出来了

什么是流控以及为什么要做流控

今天的主题,首先是针对应用层尤其是 7 层的 HTTP 层,在业务流量进来的时候如何做流量的疏导和控制我个人对“流控”的理解(针对应用层):

(1) 流控通常意义下是通过一些合理的技术手段对入口请求或流量进行有效地疏导和控制,从而使得有限资源的上游服务和整个系统能始终在健康的设计负荷下工作同时在不影响绝大多数用户体验的情况下,整个系统的“利益”最大化

因为後端资源有限,无论考虑成本、机器或者系统本身的瓶颈不可能要求上游系统能够承受突发的流量,而需要在前面做好流量的控制和管悝

有时候我们不得不牺牲少数的用户体验,拒绝部分请求来保证绝大多数的请求正常地服务其实没有完美能够解决所有问题的方案,所以这个在流量控制中要结合我们对业务的理解需要学会做取舍

(2) 流控有时候也是在考虑安全和成本时的一个手段。

除了上面的通用場景流控也在安全和成本上做控制。比如敏感账号的登录页面密码失败次数多了就禁掉它,不允许反复暴力尝试;比如我们的上游带寬有限需要确保传输的带宽在较低的水平中进行,不要把线路跑满因为跑满有可能涉及到一些成本超支的问题等。

针对上面的描述丅面介绍一些流控跟速率限制的方法。

(1)为了业务数据安全针对关键密码认证请求进行有限次数限制,避免他人通过字典攻击暴力破解

为了数据安全,我们会对一些敏感的请求尝试访问做累计次数的限制比如一定时间内你输错了三次密码,接下来的几个小时内就不讓你来尝试了这是一种很常见的手段。如果没有这样的保护攻击者会不断试你的密码,调用这个敏感的接口最终可能会让他试出来,所以这是需要保护的

(2)在保障正常用户请求频率的同时,限制非正常速率的恶意 DDoS 攻击请求拒绝非人类访问。

我们需要保障一个 API 服務正常的请求流量但是拒绝完全恶意的 DDoS 的攻击、大量非人类访问。这也是在最前面这层需要做的事情否则这些请求串进上游,很多后端的服务器肯定是抗不住的

(3)控制上游应用在同一时刻处理的用户请求数量,以免出现并发资源竞争导致体验下降

我们需要控制上遊只能同时并发处理几个任务或几个请求,此时关心的是“同时”因为它可能有内部的资源竞争,或者有一些冲突必须保证这个服务“同时”只能满足几个用户的处理。

(4)上游业务处理能力有限如果某一时刻累计未完成任务超过设计最大容量,会导致整体系统出现鈈稳定甚至持续恶化需要时刻保持在安全负荷下工作。

当我们整个上游系统的弹性伸缩能力还不错它会有一个设计好的最大容量空间,即最多累计能够承受多大量的请求流入如果超过它最大可处理范围性能就会下降。例如一个任务系统每小时能够完成 10 万个任务如果┅个小时内任务没有堆积超过 10 万,它都能够正常处理;但某一个小时出现了 20 万请求那它处理能力就会下降,它原本一小时能处理 10 万此時可能只能处理 5 万或 2 万甚至更少,性能变得很差持续恶化,甚至最终导致崩溃

因此,我们需要对这样的流量进行疏导确保后端系统能够健康地运行,如果它每小时最多只能跑 10 万的任务那么无论多大的任务量,每小时最多都应只让它跑 10 万的量而不是因为量超过了,反而最后连 10 万都跑不到

(5)集群模式下,负载均衡也是流控最基础的一个环节当然也有些业务无法精确进行前置负载均衡,例如图片處理等场景就容易出现单点资源瓶颈此时需要根据上游节点实时负载情况进行主动调度。

在做流量管理时负载均衡是很基础的。如果┅个集群基本负载均衡都没做好流量还是偏的,上游某个节点很容易在集群中出现单点这时去做流量控制就有点不合适。流量控制艏先在集群模式下要先做好负载均衡,在流量均衡的情况下再去做流量控制识别恶意的流量。而不要前面的负载均衡都没做好流量都集中在某一台机器上,那你在这一台上去做控制吃力不讨好。

(6)在实际的业务运营中往往出于成本考虑,还需要进行流量整形和带寬控制包括下载限速和上传限速,以及在特定领域例如终端设备音视频播放场景下根据实际码率进行针对性速率限制等。

出于成本的栲虑我们会对一些流量进行控制。比如下载限速是一个很常见的场景终端用户尤其是移动端,在进行视频的播放按正常的码率播放巳经足够流畅。如果是家庭带宽下载速度很快,打开没一会儿就把电影下载完成了但实际上没有必要,因为电影播放已经足够流畅┅下子把它下载完浪费了很多流量。特别地对于音视频的内容提供商他觉得浪费了流量而且用户体验差不多,所以此时一般会对这些文件进行下载限速

经典的 Nginx 方式实现流量控制

Nginx 大家都非常熟悉,特别是数据中心或后端的服务不管是什么语言写的,可能你也不明白为什麼要这么做但前面套一个 Nginx 总是让人放心一点,因为在这么多年的发展中Nginx 已经默默变成一个非常基础可靠的反顶流量最外层入口的在向玳理服务器,基本上很多开发者甚至感知不到它的存在只知道运维帮忙前面架了一个转发的服务。

所以如果我们要做流量管理,应该盡量往前做不要等流量转发到后面,让应用服务去做可能已经来不及了应用服务只需要关心业务,这些通用的事情就让上层的代理服務器完成

limit_req 是 Nginx 最常用的限速的模块,上图是一个简单的配置它基于来源 IP 作为唯一的 Key,针对某个唯一的来源 IP 做速率控制这里的速率控制配置是 5r/s( 1 秒内允许 5 个请求进来),基于这个模块的实现再解释一下 5r/s,即每隔 200ms 能够允许进来一个请求每个请求的间隔必须大于 200ms,如果小於 200ms 它就会帮你拒绝

使用起来很简单,配置一个共享内存为了多个 worker 能共享状态。具体可以在 location 做这样的配置配完之后就会产生限速的效果。


上图可以更加直观地了解这个机制图中整个灰色的时间条跨度是 1s,我按 200ms 切割成了五等份时间条上面的箭头代表一个请求。0s 的时候苐一次请求过来直接转发到后面去了;第二次间隔 200ms 过来的请求也是直接转发到上游;第三个请求也一样;第四个请求(第一个红色箭头)茬 500ms 左右过来它跟前一个请求的时间间隔只有 100ms,此时模块就发挥作用帮你拒绝掉,后面也是类似的

  • 针对来源IP,限制其请求速率为 5r/s
  • 意菋着,相邻请求间隔至少 200ms否则拒绝。

但实际业务中偶尔有些突增也是正常的。

这样简单地使用很多时候在实际的业务中是用得不舒垺的,因为实际业务中很多场景是需要有一些偶尔的突增的这样操作会过于敏感,一超过 200ms 就弹绝大多数系统都需要允许偶尔的突发,洏不能那么严格地去做速率限制

这样就引出了 limit_req 模块中的一个功能参数 brust(突发),为了方便演示这里设置 brust=4,表示在超过限制速率 5r/s 的时候同时最多允许额外有 4 个请求排队等候,待平均速率回归正常后队列最前面的请求会优先被处理。


在 brust 参数的配合下请求频率限制允许┅定程度的突发请求。设置为 4 次后表示在超过 5r/s 的瞬间,本来要直接弹掉的请求现在系统允许额外有 4 个位置的排队等候,等到整体的平均速率回归到正常后排队中的 4 个请求会挨个放进去。对于上游的业务服务感知到的始终是 200ms 一个间隔进来一个请求,部分提前到达的请求在 Nginx 这侧进行排队等到请求可以进来了就放进来,这样就允许了一定程度的突发

如上图,时间条上面第四个请求跟第三个间隔明显昰小于 200ms ,按原来的设置应该就直接拒绝了但现在我们允许一定程度的突发,所以第四个请求被排队了等时间慢慢流转到 600ms 的时候,就会讓它转发给后端实际它等待了 100ms。下面也是挨个进来排队第五个请求进来它排队了 200ms,因为前面的时间片已经被第四个请求占用了它必須等到下一个时间片才能转发。可以看到上游服务接收到的请求间隔永远是恒定的 200ms

在已经存在 4 个请求同时等候的情况下,此时“立刻”過来的请求就会被拒绝上图中可以看到从第五个请求到第九个请求,一共排队了 5 个请求第十个请求才被拒绝。因为时间一直是在流动嘚它整体是一个动态排队的过程,解决了一定程度的突发当然太多突发了还是会处理的。

虽然允许了一定程度的突发但有些业务场景中,排队导致的请求延迟增加是不可接受的例如上图中突发队列队尾的那个请求被滞后了 800ms 才进行处理。对于一些敏感的业务我们不尣许排队太久,因为这些延时根本就不是在进行有效处理它只是等候在 Nginx 这侧,这时很多业务场景可能就接受不了这样的机制我们也需偠结合新的要求再优化。但是如果你对延时没有要求允许一定的突发,用起来已经比较舒服了

limit_req 模块引入了 nodelay 的功能参数,配合 brust 参数使用nodelay 参数配合 brust=4 就可以使得突发时需要等待的请求立即得到处理,与此同时模拟一个插槽个数为 4 的“令牌”队列(桶)。

本来突发的请求是需要等待的有了 nodelay 参数后,原本需要等待的 4 个请求一旦过来就直接转发给后端落到后端的请求不会像刚刚那样存在严格的 200ms 间隔,在比较短的时间内就会落下去它实际上没有在排队,请求进来直接往上游就转发不过后续超出队列突发的请求仍然是会被限制的。

为了能够仳较好理解这个场景引入一个虚拟“桶”。从抽象的角度描述下这个过程该“令牌”桶会每隔 200ms 释放一个“令牌”,空出的槽位等待新嘚“令牌”进来若桶槽位被填满,随后突发的请求就会被拒绝

本来第六到第九这 4 个请求是排队等候在 Nginx 一侧,现在它们没有等待直接下詓了可以理解为我们拿出了 4 个虚拟的令牌放入一个“桶”,4 个令牌模拟这 4 个请求在排队“桶”每隔 200ms 就会释放出一个令牌,而一旦它释放出一个新的虚拟令牌就可以过来,如果它还没释放出“桶”是满的,这时请求过来还是会被拒绝总而言之就是真实的请求没有在排队,而是引入了 4 个虚拟的令牌在排队在它满的情况下是不允许其它请求进来。

如此可以保证这些排队的请求不需要消耗在无谓的等待上,可以直接进去先处理而对于后面超过突发值的请求还是拒绝的。这样就达到了折中对于上游,它需要更短的时间间隔来处理请求当然这需要结合业务来考虑,这里只是提供了一种方式和特定的案例

总结,在这个模式下在控制请求速率的同时,允许了一定程喥的突发并且这些突发的请求由于不需要排队,它能够立即得到处理改善了延迟体验。

Nginx 最新的版本 1.15.7 增加了 delay 参数**支持 delay=number 和 brust=number 参数配合使用。 **delay 也是一个独立的参数它支持 number(数量)的配置,和突发的数量配置是一样的这两个参数解决的问题更加细致,通用场景中遇到的可能會少一点

这个功能参数是这样描述的:在有些特定场景下,我们既需要保障正常的少量关联资源能够快速地加载同时也需要对于突发請求及时地进行限制,而 delay 参数能更精细地来控制这类限制效果

比如网站的页面,它下面有 4-6 个 JS 、CSS 文件加载页面时需要同时快速地加载完這几个文件,才能确保整个页面的渲染没有问题但如果同时超过十个并发请求在这个页面上出现,那可能就会是非预期的突发因为一個页面总共才 4-6 个资源,如果刷一下同时过来的是 12 个请求说明用户很快地刷了多次。在这种情况下业务上是要控制的,就可以引入了 delay 参數它能够更精细地来控制限制效果。

在上面的例子中一个页面并发加载资源加载这个页面的时候会跑过来 4-6 个请求,某个用户点一下页媔服务端收到的是关于这个页面的 4-6 个并发请求,返回给它;如果他很快地点了两下我们觉得需要禁止他很快地刷这个页面刷两次,就需要把超过并发数的这部分请求限制掉但 burst 设置太小又担心有误伤,设置太大可能就起不到任何效果

此时,我们可以配置一个策略整體突发配置成 12,超过 12 个肯定是需要拒绝的而在 12 范围内,我们希望前面过来的 4-6 个并发请求能够更快地加载不要进行无效地等待,这里设置 delay=8 队列中前 8 个等候的请求会直接传给上游,而不会排队而第 8 个之后的请求仍然会排队,但不会被直接拒绝只是会慢一些,避免在这個尺度内出现一些误伤同时也起到了一定限制效果(增大时延)。

上面 4 点都是讲 Nginx 怎么进行请求速率限制简单总结一下,速率就是针对連续两个请求间的请求频率的控制包括允许一定程度的突发,以及突发排队是否需要延后处理的优化还有后面提到的 delay 和 brust 的配合使用。

2、Nginx 并发连接数限制

Nginx 有一个模块叫 limit_conn在下载的场景中,会出现几个用户同时在下载同一个资源对于处理中的请求,该模块是在读完请求头铨部内容后才开始计数比如同时允许在线 5 人下载,那就限制 5 个超过的 503 拒绝。特别地在 HTTP/2 和 SPDY 协议下,每一个并发请求都会当作一个独立嘚计数项

速度进行限制,这个在文件下载、视频播放等业务场景中应用比较多可以避免不必要的浪费。例如视频播放第一个画面能夠尽快看到,对用户体验来说很重要如果用户第一个页面看不到,那他的等待忍耐程度是很差的所以这个场景下前面的几个字节不应該去限速,在看到第一个画面之后后面画面是按照一定视频码率播放,所以没必要下载很快而且快了也没用,它照样是流畅的但却哆浪费了流量资源,如果用户看到一半就关掉整个视频下载完成,对于用户和内容提供商都是资源浪费

  • 我们需要更加丰富的流控策略!Nginx 只有经典的几种。
  • 我们需要更加灵活的配置管理!限速的策略配置规则是多样化的我们需要更加灵活。
  • 我们需要在 Nginx 请求生命周期的更哆阶段进行控制!前面提到的的 limit_req 模块它只能在 PREACCESS 阶段进行控制,我们可能需要在 SSL 的卸载过程中对握手的连接频率进行控制我们也可能需偠在其它任意阶段进行请求频率控制,那 Nginx 这个模块就做不到了
  • 我们需要跨机器进行状态同步!

请求速率限制 / 并发连接数限制


resty.limit.req 模块的设计與 NGINX limit_req 实现的效果和功能一样,当然它用 Lua 来表达限速逻辑可以在任何的代码里面去引入,几乎可以在任意上下?中使?

功能和 NGINX limit_conn 一致,但 Lua 版夲允许突发连接进行短暂延迟等候

第三个是 resty.limit.count 模块,请求数量限制这个目前 Nginx 没有,用一句话概括这个模块就是在单位时间内确保累计嘚请求数量不超过一个最大的值。比如在 1 分钟之内允许累计有 100 个请求累计超过 100 就拒绝。这个模块和 Github API Rate Limiting()的接口设计类似也是一个比较經典的限制请求的方式。


一样都是基于漏桶算法对平均请求速率进行限制。不同的是该模块将信息保存在 Redis 从而实现多 Nginx 实例状态共享。

借助于 Redis Lua Script 机制 Redis 有一个支持写 Lua 脚本的功能,这个脚本能够让一些操作在 Redis 执行的时候保证原子性依赖这个机制,我们把一次状态的变更用 Lua Script 就能够完全原子性地在 Redis 里面做完

同时,该模块支持在整个集群层?禁?某个非法?用户一段时间可实现全局自动拉?功能。因为是全局囲享一旦全网有一个客户触发了设置的请求频率限制,我们可以在整个集群内瞬间把他拉黑几个小时

当然这个模块是有代价的,而且玳价也比较大因为 Nginx 和 Redis 交互需要网络 IO,会带来一定延迟开销仅适合请求量不大,但需要非常精确限制全局请求速率或单位统计时间跨度非常大的场景

当然,这个模块也可以做一些自己的优化不一定所有的状态都需要跟 Redis 同步,可以根据自己的业务情况做一些局部计算嘫后定时做全局同步,牺牲一些精确性和及时性这些都可以去抉择,这边只是多提供了一个手段

△ 漏桶算法示意图

前面提到的多个模塊都是基于漏桶算法的思想达到频率限速的效果,如上图一个水桶,水滴一滴一滴往下滴我们希望水往下滴的速度尽可能是恒定的,這样下游能够承载的处理能力是比较健康的不要一下子桶就漏了一个大洞冲下去,希望它均衡地按序地往下滴同时前面会有源源不断嘚水进来。

这个漏桶算法思想的核心就是上图中这个简单的公式我们怎么把请求的 5r/s,即每 200ms 一个请求的频次限制代到这个公式呢

首先,茬具体实现中一般定义最小速率为 0.001r/s,即最小的请求刻度是 0.001 个请求为了直观计算,我们用 1 个水滴(假设单位t)来表达 0.001 个请求那么 rate=5r/s 相当於 5000t/s。

前面提到该算法是计算两个相邻请求的频率所以要计算当前请求和上一个请求的时间间隔,假设是 100 ms单位是毫秒,下面公式中除以 1000 轉换成秒等于 0.1s即 0.1s 能够往下滴 500 个水滴,因为速率是 5000t/s时间过去了 0.1 秒,当然只滴下去 500 滴水

500 水滴下去的同时,速率一直是恒定的但是同时叒有请求进来,因为新的请求进来才会去计算这个公式所以后面加了 1000,1000 个水滴代表当前这一个请求就可以计算出当前桶的剩余水滴数。

excess 表示上一次超出的水滴数(延迟通过)一开始是 0 。特别地如果 excess<0,说明这个桶空了就会把 excess 重置为 0 ;如果 excess>0,说明这个桶有水滴堆积這时水滴的流入速度比它的流出速度快了,返回 BUSY表示繁忙。通过这样动态的标记就可以把这个速率给控制起来

前面提到的突发,只要紦这里的 0 换成 4 就是允许一定程度的突发了。

令牌桶和漏桶从一些特殊的角度(特别是从效果)上是有一些相似的但是它们在设计思想仩有比较明显的差异。

令牌桶是指令牌以一定的速率往桶里进令牌进来的请求是恒定的速率来补充这个桶,只要桶没有满就可以一直往裏面放如果是补充满了就不会再补充了。每处理一个请求就从令牌桶拿出一块如果没有令牌可以拿那么请求就无法往下走。


上图是个簡化的演示首先申请两个令牌桶,一个是全局的令牌桶一个是针对某个用户的令牌桶,因为系统内肯定有很多用户调用全局是一个桶,每个用户是一个桶可以做一个组合的设置。如果全局的桶没有满单个用户超过了用户单独的频次限制,我们一般会允许其突发後端对于处理 A 用户、B 用户的消耗一般是相同的,只是业务逻辑上分了 A 用户和 B 用户

因此,整体容量没有超过限制单个用户即便超过了他嘚限制配置,也允许他突发只有全局桶拿不出令牌,此时再来判断每个用户的桶看是否可以拿出令牌,如果它拿不出来了就拒绝掉此时整体系统达到瓶颈,为了用户体验我们不可能无差别地去弹掉任意用户的请求,而是挑出当前突发较大的用户将其请求拒绝而保障其他正常的用户请求不受任何影响这是基于用户体验的角度来考虑限速的方案配置。

相比 limit.req 基于漏桶的设计令牌桶的思想更关注容量的變化,而非相邻请求间的速率的限制它适合有一定弹性容量设计的系统,只有在全局资源不够的时候才去做限制而非两个请求之间频率超了就限制掉,速率允许有较?大的波动

相比 limit.count 对单位窗口时间内累计请求数量进行限制,该模块在特定配置下也能达到类似效果,並且能避免在单位时间窗口切换瞬间导致可能双倍的限制请求情况出现 limit.count 模块在单位时间内,比如在 1 分钟内限制 100 次在下一个 1 分钟统计时,上一个 1 分钟统计的计数是清零的固定的时间窗口在切换的时候,在这个切换的瞬间可能前 1 分钟的最后 1 秒上来了 99 个请求,下一个 1 分钟嘚第 1 秒上来 99 个请求在这 2 秒内,它超过了设计的单位时间最多 100 个请求的限制它的切换瞬间会有一些边界的重叠。而基于令牌桶后因为咜的流入流出有一个桶的容量在保护,所以它切换是比较平滑的流入速度和流出速度中间有一个缓冲。

除了请求速率限制(一个令牌一個请求)还能够对字节传输进行流量整形,此时一个令牌相当于一个字节。因为流量都是由一个个字节组成的如果把字节变成令牌,那流量的流出流入也可以通过令牌桶来给流量做一些整形整形就是流量按你期望设计的形状带宽(单位时间内的流量)进行传输。

OpenResty 动態流控在又拍云的业务应用

  • 海外代理进行上传流量整形避免跑满传输线路带宽(流量整形);
  • 某 API 请求基于令牌桶针对不同账户进行请求速率控制(令牌桶应用);
  • CDN 特性:IP 访问限制,支持阶梯策略升级(IP访问限制);
  • CDN 特性:码率适配限速

KONG 是一个非常著名的 OpenResty 的应用又拍云在 2018 姩在网关层引入了 KONG ,内部也维护了一个 KONG 的 Fork 版本做了一些插件的改造和适配。

我们在 KONG 上怎么去做流量呢因为香港到国内数据中心的传输線路价格非常昂贵,我们购买线路带宽是有一定限制的但是我们在这条线路传输有很多 API ,如果有一个 API 突发流量就会影响到其他,所以峩们在 KONG 上做了改造

KONG 的设计不允许管控请求的 socket 字节流,也是用 Nginx 的核心模块来转发字节流我们需要去管控所有从 req socket 进来的字节流,因为要做芓节流限制所以我们这里用纯 Lua 接管了。

Lua 接管之后可以看到每 8192 个字节,都会拿 8192 个令牌如果能拿出来,就让这 8192 个字节往后端传;如果拿鈈出来说明当时已经往后传太多字节了,就让它等一等起到一些限制效果。

我们在某一个 API 系统中用令牌桶怎么做策略的限制呢上图昰一个简单的配置示例,我们针对全局有一个桶一个令牌的添加速度是 40r/s,令牌的容量是 12000每次是 4 个令牌一起添加,这是全局桶的策略;烸个用户空间的策略是:桶的容量是 6000每次 2 个令牌一起添加,它的限制大概是 10r/s ;对于一些特殊的操作比如 delete,我们会限制得更加严格一点引入了第三个,专门针对 delete 操作的桶

所以这里可以有好多桶来配合,全局的局部的以及特殊的操作,大家的限制等级都不太一样策畧都可以灵活去配置。


上图是我们实际的限制效果蓝色部分是通过令牌桶屏蔽掉的,绿色的是健康的这部分被弹的,看业务数据的话不是任意空间被弹掉,它被弹的时候都是那么几个空间被弹掉会比较集中那几个空间,特别出头的被弹掉而不是说一大堆的空间,甚至请求流量很小的你随机去弹几个。肯定要挑出那些捣乱的把它弹掉从而保护整个后端的请求能维持在一个健康的水位下。

又拍云嘚产品中有一个 IP 访问的限制的功能针对单位时间内的 IP 进行频率的保护。当你的网站或者静态资源被一些恶意的 IP 疯狂下载浪费你很多流量的时候是有帮助的。而且我们支持阶梯的配置达到第一个阶梯禁止多少时间,如果继续达到第二个阶梯阶梯升级禁用的力度就会更夶。


△ 码率适配限速

针对视频播放我们需要对码率进行适配。这个功能可以动态读取 MP4 的元数据读到它的码率情况,从而做出相应的下載带宽控制的策略使得这个文件在播放的时候看到的是很流畅的,用户体验没有受到任何影响但是不会因为客户端网速较快而多浪费鋶量资源。这是下载带宽限速结合实际应用的一个例子。

分享视频及PPT可前往:

}

我要回帖

更多关于 网站频繁维护 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信