【AICon】探索RAG 技术在实际应用中遇到的挑战及应对策略!AICon精华内容已上线73%>>> 了解详情
写点什么

预案三板斧的限流大法

  • 2019-10-21
  • 本文字数:2794 字

    阅读完需:约 9 分钟

预案三板斧的限流大法

限流策略:多维防御+纵深防御

限流能力

限流是针对请求的各种特征,多维防御+纵深防御,从而限制流量,实现对服务端资源的合理使用。这里的特征是指一个请求所包含的各种信息,包括但不限于 IP、Header、URI、Cookie 等。常见的限流策略有以下三种(以 Nginx 为例进行说明):


  • 限制请求数,意思是请求的次数不能太多


Nginx:http://nginx.org/en/docs/http/ngx_http_limit_req_module.html


  • 限制并发连接数,意思是请求的频率不能太快


Nginx:http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html


  • 限制传输速度,意思是请求的体积不能太大


Nginx:http://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate


Nginx 还提供 work_connections 和 worker_processes 这类针对程序的全局设置,但是这些配置并非是客户端的请求的特征,不能直接作用于特定请求特征的流量,因此不属于本文限流的讨论范畴。

多维防御

所谓的多维防御,不仅仅针对 IP 进行限制,还可以从 URI、Cookie、状态码等多个维度进行限制,同时还可以组合起来进行精细化的限制,举例说明:


  • 状态码+IP,如果恶意扫描整个网站,必然会出现较多的 404 状态码,这时候结合其他维度,就可以进行一定的防御和限制

  • URI+Cookie,可以避免公司 IP 出口导致的请求被误伤,同时也解决了 IP 模式下阈值设置太大的问题

纵深防御

所谓的纵深防御,则是指针对单一维度,进行多层级的防御,实现精细化的限制。以 IP 维度为例进行说明:


  • 每秒钟,单个 IP 最多可以访问 100 次

  • 每十秒钟,单个 IP 最多可以访问 500 次

  • 每分钟,单个 IP 最多可以访问 1000 次

阈值设置

上述的阈值只是简单举例,并没有太大的参考价值,在实际部署的过程中,一般需要至少 30 天的访问日志以及多个节假日的访问日志进行离线分析,从而得出业务特定的合理阈值,然后在通过灰度逐步全量。初期的阈值,建议设置的比预估阈值至少高一倍,先具备限流功能,然后再慢慢打磨阈值,避免因为阈值设置不合理,导致限流功能上线受阻,那就得不偿失了。

限流的算法

那各种限流策略背后的实现机制是怎样的呢?常见的限流算法有固定窗口计数器,滑动窗口计数器,漏洞和令牌桶四种,在各类软件的具体实现上却不尽相同,详细内容可以参考这篇文章《分布式系统关注点——限流该怎么做?》,本文仅介绍较为常用的两种算法。

固定窗口计数器

将时间划分为固定时间窗口(例如每秒一个单位),在每个固定的时间窗口内对请求进行计数,如果请求的次数超过了限制,则本时间窗口内所有的后续请求都被丢弃,直到下一个固定时间窗口时,重置计数器。



该算法常被吐槽流量突增,举例来说 100r/m(每分钟 100 次请求),可能在第一秒钟就请求完毕,更有甚者,在两个时间窗口交界处可能会产生 2 倍的请求,这样就会导致短时的流量突增。但是,只要把时间粒度控制在秒级,效果还是可以的。因此,滑动窗口就没有太大的必要进行介绍了,大家看相关文章即可。


漏桶

漏桶算法,有一个固定大小的队列,进入的请求全部放入该队列中,如果队列满,则丢弃进入的请求。同时,以固定的速率从队列中消费请求。好处就是,不管流量进来多少,出去的速率始终固定。


该算法的主要不足就是消费速率设置会偏保守一些,因为不同请求的资源消耗和处理耗时不同,为了能够适配各类场景,必然会导致消费速率设置较为保守。缓解的方法,对不同的请求类型进行集群拆分,从而能够更加精细化的设置消费速率。


各层级限流

全局统一接入:GFE/BFE/JFE

全局统一接入的产品,Goolge 叫做 GFE,Baidu 叫做 BFE,JD 叫做 JFE。这类产品会将公司所有对外流量进行统一的接入和调度,同时具备较强的通用防护能力,如抗 D、WAF 等。


对于一些业务定制化的复杂限流规则,一般会下放到各个业务线自己的接入端来实现。


Webserver:Nginx/OpenResty

上面介绍各种 XFE 的时候提到,一些业务定制化的复杂限流规则,会下放到各个业务线的接入端来实现,在这个阶段,因为 Webserver 的选择较多,所以实现方式也较多,没有统一的标准,一般是直接利用 webserver 提供的限流能力,或者是通过插件方式来实现,前者多以 Nginx 为主,后者则是 Nginx+lua/Nginx+lua+redis 的形式。


本文以 Nginx 为例来进行说明,业务侧的整体思路应该是多维防御+纵深防御,从而实现较好的限流效果。


多维防御,以 Nginx 的 limit_req 为例进行说明,不仅仅对来源 IP 进行流控,还可以对请求的 uri,cookie 进行流控,还可以对 ip+uri+cookie 的组合进行流控,从多个维度下手,进而实现更好的效果。


limit_req_zone $ip zone=1:10m rate=100r/s;


limit_req_zone ip zone=2:10m rate=100r/s;


limit_req_zone ip$cookie zone=3:10m rate=100r/s;


limit_req zone=1 burst=30 nodelay;


limit_req zone=2 burst=10 nodelay;


limit_req zone=3 burst=30 nodelay;


纵深防御,以 Nginx 的 limit_req 为例进行说明,主要是通过漏斗思路,设置三级防御体系,第一级是粗滤,因此阈值可以设置的较大,仅拦截明显的恶意行为即可,第二级过滤,可以拦截一些异常请求,第三级过滤,则可以将大部分异常请求进行拦截。


limit_req_zone $ip zone=11:10m rate=100r/s;


limit_req_zone $ip zone=12:10m rate=500r/10s;


limit_req_zone $ip zone=13:10m rate=1200r/1m;


limit_req zone=1 burst=50 nodelay;


limit_req zone=2 burst=100 nodelay;


limit_req zone=3 burst=200 nodelay;


备注:Nginx 本身并不支持 500r/10s 这种模式,同时,60r/m 的效果等同于 1r/s,因此上述的配置只能起到一个演示的作用。实际上是需要大家通过插件的方式来实现上述的效果。Nginx 官方对于 r/m 的解释如下:The rate is specified in requests per second (r/s). If a rate of less than one request per second is desired, it is specified in request per minute (r/m). For example, half-request per second is 30r/m.

应用程序和中间件:Istio

对于大部分自研的程序来讲,限流功能如有必要,就得自行实现了,算法前面已经介绍过了,当然,也可以参考 Google 的 RateLimiter。


对于进入了 Docker 的程序,则可以考虑引入 Istio,改造成本可控,收益上,限流,熔断,鉴权等等功能均可具备,但是目前大规模应用的公司还不多,大家都是在慢慢探索中。


对于短期内还无法实现虚拟化的业务,则可以考虑类似 Istio 的模式,在每个程序前,在关键程序前,在和多个下游交互的程序前,适度放置 Proxy 来实现流控的效果。在 AWS 的 Proxy-ELB,就是挂在了每组服务之前。这种模式的缺点就在于会略为增加延时,但如果是同 Regin 部署,那么只要增加的 Proxy 层级数量可控,整体延时影响也可控。


极少数情况下,也有业务直接通过 Iptable 的方式进行限流,对于物理机的部署模式,笔者只能建议要谨慎使用。


参考文章


分布式服务限流实战,已经为你排好坑了


分布式系统关注点——限流该怎么做?


华为交换机设置配置说明


BFE开源版本


2019-10-21 11:5612427

评论

发布
暂无评论
发现更多内容

实用机器学习笔记二十五:超参数优化

打工人!

学习笔记 超参数调优 机器学习算法 3月月更

被冰封的 Bug:Fishhook Crash 修复纪实

声网

Dev for Dev fishhook

基于深度学习的时间序列预测

云智慧AIOps社区

如何使用OKR管理团队?

优秀

hexo+github搭建个人博客前期部署工作

静Yu

Hexo

OceanBase 社区版 运维管控平台 OCP 功能解读

OceanBase 数据库

OCP oceanbase OceanBase 开源 OceanBase 社区版

企业内PAAS建设的经验与教训

Crazy

中间件 PaaS 经验 云原生应用

基于WEB快速开发平台的轻量ERP

雯雯写代码

ERP 快速开发平台

杜绝不良信息侵害未成年,皮皮APP发起语音社交行业自律书

联营汇聚

手把手教程|构建无服务器通用文本识别功能

亚马逊云科技 (Amazon Web Services)

架构

打造优质的车联网体验,仍需注意数据安全保护

FinClip

喜讯!openGauss社区入选2021年 “科创中国”榜单

openGauss

云计算及国内主流云厂商概述

穿过生命散发芬芳

3月月更

基于微信小程序的大学社团平台的可研方案

CC同学

安全app之PHP代码审计

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 代码审计

移动域全链路可观测架构和关键技术

阿里巴巴终端技术

架构 App 移动端 体验优化

向工程腐化开炮 | Java代码治理

阿里巴巴终端技术

Java android JVM 代码治理

如何从头到脚彻底解决一个MySQL Bug?华为云数据库高级专家带你看

华为云数据库小助手

bug GaussDB 华为云数据库 GaussDB(for MySQL)

如何从头到脚彻底解决一个MySQL Bug

华为云开发者联盟

MySQL 数据库 华为云 bug GaussDB(for MySQL)

企业知识管理的目标是什么?

小炮

Gitlab-ci 替代 webhook 触发Jenkins job

网易云信

gitlab

租房小程序

源字节1号

前端开发 后端开发 租房小程序

WebRTC 简单入门

ZEGO即构

WebRTC 动手实践 音视频开发 即构科技

盲盒风潮过后,中国收藏玩具市场该何去何从?

易观分析

盲盒 潮玩

租房小程序

源字节1号

前端开发 后端开发 租房小程序

VuePress 博客之 SEO 优化(一) sitemap 与搜索引擎收录

冴羽

Vue vuepress SEO 博客搭建 sitemap

关于知识库:你需要知道的一切

小炮

什么是以特性为核心的持续交付|阿里巴巴DevOps实践指南

阿里云云效

云计算 阿里云 研发效能 研发 DevOps实践指南

APICloud平台使用融云模块实现音视频通话实践经验总结分享

YonBuilder低代码开发平台

前端开发 APP开发 APICloud 融云 跨端开发

openGauss社区成立ReleaseManagement SIG

openGauss

聊聊 kerberos 的 kinit 命令和 ccache 机制

明哥的IT随笔

数据安全 kerberos

预案三板斧的限流大法_软件工程_焦振清_InfoQ精选文章