searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

分布式限流详解

2024-12-12 09:10:58
4
0

限流介绍

限流 (Ratelimiting) :指对应用服务的请求进行限制,例如某一接口的请求限制为 100 个每秒, 对超过限制的请求则进行快速失败或丢弃。
限流可以应对:
•热点业务带来的突发请求;
•调用方 bug 导致的突发请求;
•恶意攻击请求。
因此,对于公开的接口最好采取限流措施。
 

单点限流

缺陷:
1.线上业务多是分布式系统,单节点的限流仅能保护自身节点,但无法保护应用依赖的各种服务,并且在进行节点扩容、缩容时也无法准确控制整个服务的请求限制
2.业务定制级别限流如果应用为分布式部署则很难通过单点限流达到目的
 

分布式限流

如果实现了分布式限流,那么就可以方便地控制整个服务集群的请求限制,且由于整个集群的请求数量得到了限制,因此服务依赖的各种资源也得到了限流的保护
 

常用限流方法介绍

计数器限流

主要用来限制总并发数,比如数据库连接池、线程池、秒杀的并发数;只要全局总请求数或者一定时间段的总请求数设定的阀值则进行限流,是简单粗暴的总数量限流,而不是平均速率限流
1.将时间划分为多个窗口;
2.在每个窗口内每有一次请求就将计数器加一;
3.如果计数器超过了限制数量,则本窗口内所有的请求都被丢弃,当时间到达下一个窗口时,计数器重置;
缺点:
致命问题:临界问题
原因:精度太低
 

滑动窗口限流

滑动窗口其实就是 细分之后的计数器。
滑动窗口计数器是通过将窗口再细分,并且按照时间滑动,这种算法避免了固定窗口计数器带来的双倍突发请求
但时间区间的精度越高,算法所需的空间容量就越大。
1.将时间划分为多个区间;
2.在每个区间内每有一次请求就将计数器加一,维持一个时间窗口占据多个区间;
3.每经过一个区间的时间,则抛弃最老的一个区间,并纳入最新的一个区间;
4.如果当前窗口内区间的请求计数总和超过了限制数量,则本窗口内所有的请求都被丢弃。
 

漏桶限流

水(请求)先进入到漏桶里,漏桶以一定的速度出水(接口有响应速率),当水流入速度过大会直接溢出(请求拒绝)
漏桶算法(Leaky Bucket)是网络世界中流量整形(Traffic Shaping)或速率限制(Rate Limiting)时经常使用的一种算法,主要目的是控制数据注入到网络的速率,平滑网络上的突发流量。漏桶算法提供了一种机制,通过它,突发流量可以被整形以便为网络提供一个稳定的流量
特点:a.速度恒定 b.不允许突发
 

令牌桶限流

和漏洞漏水相反, 令牌桶是系统以恒定速率往桶中加令牌(桶满了则溢出),新请求到达直接从桶中拿走需要的令牌数,如果桶中剩余令牌数不够则拒绝请求
概述:通过向固定大小的令牌桶中以恒定速率放置令牌来实现去网络流量和速率进行控制。
特点:a. 速率恒定 b.允许突发
 

多漏桶限流

漏桶改进版:同一漏桶但具有不同权重优先级的一组请求(报文)进行限速的时候, 将总漏桶按照权重优先级的个数及比例参数分割为多个子漏桶(报文权重优先级与子漏桶权重优先级相对应),各个子漏桶突发度总和等于大漏桶的突发度且各个子漏桶水流流出速率总和等于大漏桶流出速率。
抢票举例: 资源总并发量固定,非VIP, VIP,VVIP不同等级,子桶大小不同,可容纳请求量不同(非VIP抢了1次, VIP可能同样时间内可以抢多次)
 

限流算法对比

  令牌桶 漏桶
机制 按照固定速率往桶中添加令牌(限制流入速度),请求是否被处理需要看桶中令牌是否足够,当令牌数减为零时则拒绝新的请求; 按照常量固定速率流出请求(限制流出速度),流入请求速率任意,当流入的请求数累积到漏桶容量时,则新流入的请求被拒绝;
目的 容忍一定程度的突发 平滑流入速率
  两个算法实现可以一样,但是方向是相反的,对于相同的参数得到的限流效果一样
 

限流方案介绍

应用级限流
限流总(并发/连接/请求/资源)数 系统TPS/QPS限制,Web容器总的连接数、连接池、线程池等资源限制例如:Tomcat Connector配置: acceptCount、maxConnections、maxThreads等参数配置
限流某个接口的总并发/请求数或时间窗内的请求数 1.AtomicLong(原子操作): atomicLong.incrementAndGet(); //增
atomicLong.decrementAndGet(); //减2. Guava Cache 缓存计数器
平滑限流某个接口的请求数(限速率) Guava RateLimiter (平滑突发限流(SmoothBursty)和平滑预热限流(SmoothWarmingUp)) 基于令牌桶,单机版
分布式限流
问题 应用被部署到多台机器,应用级限流方式只是单应用内的请求限流,不能进行全局限流,怎样保证多系统之间限流操作一致性?
解决方式 将限流服务独立第三方管理并做成原子化
目前流程方案 基于缓存 + lua 或者 Nginx + lua 实现 (利用lua脚本执行的原子性特征)
接入层限流(流量入口限流)
目的 负载均衡、非法请求过滤、请求聚合、缓存、降级、限流、A/B测试、服务质量监控等等
目前流程方案 基于Nginx实现: ngx_http_limit_conn_module:限制总的连接数 ngx_http_limit_req_module: 限制请求速率(漏桶算法) lua-resty-limit-traffic : 灵活实现限流算法 (基于OpenResty提供lua限流模块)
0条评论
0 / 1000
Nicole
2文章数
0粉丝数
Nicole
2 文章 | 0 粉丝
Nicole
2文章数
0粉丝数
Nicole
2 文章 | 0 粉丝
原创

分布式限流详解

2024-12-12 09:10:58
4
0

限流介绍

限流 (Ratelimiting) :指对应用服务的请求进行限制,例如某一接口的请求限制为 100 个每秒, 对超过限制的请求则进行快速失败或丢弃。
限流可以应对:
•热点业务带来的突发请求;
•调用方 bug 导致的突发请求;
•恶意攻击请求。
因此,对于公开的接口最好采取限流措施。
 

单点限流

缺陷:
1.线上业务多是分布式系统,单节点的限流仅能保护自身节点,但无法保护应用依赖的各种服务,并且在进行节点扩容、缩容时也无法准确控制整个服务的请求限制
2.业务定制级别限流如果应用为分布式部署则很难通过单点限流达到目的
 

分布式限流

如果实现了分布式限流,那么就可以方便地控制整个服务集群的请求限制,且由于整个集群的请求数量得到了限制,因此服务依赖的各种资源也得到了限流的保护
 

常用限流方法介绍

计数器限流

主要用来限制总并发数,比如数据库连接池、线程池、秒杀的并发数;只要全局总请求数或者一定时间段的总请求数设定的阀值则进行限流,是简单粗暴的总数量限流,而不是平均速率限流
1.将时间划分为多个窗口;
2.在每个窗口内每有一次请求就将计数器加一;
3.如果计数器超过了限制数量,则本窗口内所有的请求都被丢弃,当时间到达下一个窗口时,计数器重置;
缺点:
致命问题:临界问题
原因:精度太低
 

滑动窗口限流

滑动窗口其实就是 细分之后的计数器。
滑动窗口计数器是通过将窗口再细分,并且按照时间滑动,这种算法避免了固定窗口计数器带来的双倍突发请求
但时间区间的精度越高,算法所需的空间容量就越大。
1.将时间划分为多个区间;
2.在每个区间内每有一次请求就将计数器加一,维持一个时间窗口占据多个区间;
3.每经过一个区间的时间,则抛弃最老的一个区间,并纳入最新的一个区间;
4.如果当前窗口内区间的请求计数总和超过了限制数量,则本窗口内所有的请求都被丢弃。
 

漏桶限流

水(请求)先进入到漏桶里,漏桶以一定的速度出水(接口有响应速率),当水流入速度过大会直接溢出(请求拒绝)
漏桶算法(Leaky Bucket)是网络世界中流量整形(Traffic Shaping)或速率限制(Rate Limiting)时经常使用的一种算法,主要目的是控制数据注入到网络的速率,平滑网络上的突发流量。漏桶算法提供了一种机制,通过它,突发流量可以被整形以便为网络提供一个稳定的流量
特点:a.速度恒定 b.不允许突发
 

令牌桶限流

和漏洞漏水相反, 令牌桶是系统以恒定速率往桶中加令牌(桶满了则溢出),新请求到达直接从桶中拿走需要的令牌数,如果桶中剩余令牌数不够则拒绝请求
概述:通过向固定大小的令牌桶中以恒定速率放置令牌来实现去网络流量和速率进行控制。
特点:a. 速率恒定 b.允许突发
 

多漏桶限流

漏桶改进版:同一漏桶但具有不同权重优先级的一组请求(报文)进行限速的时候, 将总漏桶按照权重优先级的个数及比例参数分割为多个子漏桶(报文权重优先级与子漏桶权重优先级相对应),各个子漏桶突发度总和等于大漏桶的突发度且各个子漏桶水流流出速率总和等于大漏桶流出速率。
抢票举例: 资源总并发量固定,非VIP, VIP,VVIP不同等级,子桶大小不同,可容纳请求量不同(非VIP抢了1次, VIP可能同样时间内可以抢多次)
 

限流算法对比

  令牌桶 漏桶
机制 按照固定速率往桶中添加令牌(限制流入速度),请求是否被处理需要看桶中令牌是否足够,当令牌数减为零时则拒绝新的请求; 按照常量固定速率流出请求(限制流出速度),流入请求速率任意,当流入的请求数累积到漏桶容量时,则新流入的请求被拒绝;
目的 容忍一定程度的突发 平滑流入速率
  两个算法实现可以一样,但是方向是相反的,对于相同的参数得到的限流效果一样
 

限流方案介绍

应用级限流
限流总(并发/连接/请求/资源)数 系统TPS/QPS限制,Web容器总的连接数、连接池、线程池等资源限制例如:Tomcat Connector配置: acceptCount、maxConnections、maxThreads等参数配置
限流某个接口的总并发/请求数或时间窗内的请求数 1.AtomicLong(原子操作): atomicLong.incrementAndGet(); //增
atomicLong.decrementAndGet(); //减2. Guava Cache 缓存计数器
平滑限流某个接口的请求数(限速率) Guava RateLimiter (平滑突发限流(SmoothBursty)和平滑预热限流(SmoothWarmingUp)) 基于令牌桶,单机版
分布式限流
问题 应用被部署到多台机器,应用级限流方式只是单应用内的请求限流,不能进行全局限流,怎样保证多系统之间限流操作一致性?
解决方式 将限流服务独立第三方管理并做成原子化
目前流程方案 基于缓存 + lua 或者 Nginx + lua 实现 (利用lua脚本执行的原子性特征)
接入层限流(流量入口限流)
目的 负载均衡、非法请求过滤、请求聚合、缓存、降级、限流、A/B测试、服务质量监控等等
目前流程方案 基于Nginx实现: ngx_http_limit_conn_module:限制总的连接数 ngx_http_limit_req_module: 限制请求速率(漏桶算法) lua-resty-limit-traffic : 灵活实现限流算法 (基于OpenResty提供lua限流模块)
文章来自个人专栏
技术积累1
2 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0