首页 > 其他分享 >分布式限流方案

分布式限流方案

时间:2023-07-24 17:11:45浏览次数:38  
标签:方案 令牌 maxPermits 间隔 Lua 限流 速率 分布式

https://www.cnblogs.com/jiangym/p/17473049.html

https://www.cnblogs.com/jiangym/p/17471590.html

常见限流

  • 验证码
  • 通常会设置多个维度的限流规则
  • IP每秒的访问评率小于10、连接数小于5
    • (怎么实现的?)
  • 每台机器QPS最高1000,连接数最大保持200
    • 怎么实现的?
  • 整个服务器作为一个整体,设置更高的high-level限流规则
  • Nginx限流
    • 基于ID地址的限流方案
    • 基于最大连接数的限流方案
  • 基于Redis+Lua的分布式限流
    • lua
    • lua+redis
    • 注解封装,自动以注解封装限流逻辑
  • 黑白名单限流
  • 网关层限流

 

  1. 网关层限流
    1. 网关层不像改个程序代码那么简单,和运维也相关
    2. Nginx
    3. gateway
    4. zuul
  2. 中间件限流
    1. 限流下沉到业务层,开发就可以自行控制
    2. redis
  3. 限流组件
    1. sentinel 阿里开源的

 限流算法

 常见就四种

  • 令牌桶算法
  • 漏桶算法
  • 滑动窗口
  • 计数器算法

令牌桶

token bucket

目前应用最广泛

分为

  1. 令牌
    1. 匀速发放 每秒100个请求 或者每分钟50个这种
    2. 匀速和非匀速的区别?
    1. 生成之后放到桶中,到了额定容量,新的令牌就丢弃
  2. 请求获取令牌
    1. 请求获得令牌才能执行后续逻辑。
    2. 可以用缓冲队列存多余的令牌。

 

漏桶

Leaky Bucket

 数据表放桶里。桶满了数据表将被丢弃。

 

区别

根据它们各自的特点不难看出来,这两种算法都有一个“恒定”的速率和“不定”的速率。

令牌桶是以恒定速率创建令牌,但是访问请求获取令牌的速率“不定”,反正有多少令牌发多少,令牌没了就干等。

而漏桶是以“恒定”的速率处理请求,但是这些请求流入桶的速率是“不定”的。

从这两个特点来说,漏桶的天然特性决定了它不会发生突发流量,就算每秒1000个请求到来,那么它对后台服务输出的访问速率永远恒定。

而令牌桶则不同,其特性可以“预存”一定量的令牌,因此在应对突发流量的时候可以在短时间消耗所有令牌,其突发流量处理效率会比漏桶高,但是导向后台系统的压力也会相应增多。

 

具体实现

Guava RateLimiter 当前服务器限流

非阻塞 令牌桶

 非阻塞限流

同步阻塞限流

令牌不足的时候就阻塞住。

 

适用于 对单机资源敏感  读取的资源都是本地 不会有其他的组件

比如数据库,多个机器,就不适合这种的。

 

预热模型

@Override
void doSetRate(double permitsPerSecond, double stableIntervalMicros) {
      double oldMaxPermits = maxPermits;
      
    // maxPermits表示令牌桶内最大容量,它由我们设置的预热时间除以稳定间隔获得
    // 打个比方,如果stableIntervalMicros=0.1s,而我们设置的预热时间是2s
    // 那么这时候maxPermits就是2除以0.1=20
      maxPermits = warmupPeriodMicros / stableIntervalMicros;
      
      // 这句不用解释了吧,halfPermits是最大容量的一半
      halfPermits = maxPermits / 2.0;
  
      // coldIntervalMicros就是我们前面写到的3倍间隔,通过稳定间隔*3计算得出
      // 稳定间隔是0.1,3倍间隔是0.2,那么平均间隔是0.2
      double coldIntervalMicros = stableIntervalMicros * 3.0;
      
      // slope的意思是斜率,也就是前面我们图中预热阶段中画出的斜线(速率从稳定间隔向3x间隔变化的斜线)
      // 它的计算过程就是一个简单的求斜率公式
      slope = (coldIntervalMicros - stableIntervalMicros) / halfPermits;
      
      // 计算目前令牌桶的令牌个数
      if (oldMaxPermits == Double.POSITIVE_INFINITY) {
          // 如果令牌桶最大容量是无穷大,则设置当前可用令牌数为0
          // 说实话这段逻辑没什么用
        storedPermits = 0.0;
      } else {
        storedPermits = (oldMaxPermits == 0.0)
            ? maxPermits // 初始化的状态是3x间隔
            : storedPermits * maxPermits / oldMaxPermits;
  }
}

 

基于Nginx的IP限流

  1. 修改host文件
  2. 修改nginx,把host用的域名放到路由规则里 修改nginx.conf
    1. server
      1. server_name
      2. location
      3. 这里可以添加限流规则
      4.  

Nginx连接数的限制

 

 前100M不限流:

 

基于Redis+Lua的分布式限流

redis基于内存的,并且线程安全,所以适合做限流

 这种限流不是在Java内写的,比如获取令牌场景,会涉及发放令牌、查询令牌等操作,网络开销大。

所以直接通过Lua脚本方式,更好。

Lua

很小巧精致的语言,C语言编写的,源码两万行,Lua解释器才200K。

学这个语言不用面面俱到,因为细节很繁琐。

Redis中有Lua解释器,天生的原子性操作。有脚本预编译,直接调用编译好的脚本就行。

 Lua 简单语法

 结果是reject

 Redis中执行Lua

redis中执行Lua

 

Lua脚本预导入Redis

 

检查预导入的脚本是否存在

 清空预导入脚本

限流注解: 

https://www.cnblogs.com/jiangym/p/17576108.html

 

 

 

 

 

如果限流服务挂了,怎么兜底?直接放开限流

 

标签:方案,令牌,maxPermits,间隔,Lua,限流,速率,分布式
From: https://www.cnblogs.com/jiangym/p/17574481.html

相关文章

  • 分布式开放消息系统(RocketMQ)的原理与实践
    备注:1.如果您此前未接触过RocketMQ,请先阅读附录部分,以便了解RocketMQ的整体架构和相关术语2.文中的MQServer与Broker表示同一概念分布式消息系统作为实现分布式系统可扩展、可伸缩性的关键组件,需要具有高吞吐量、高可用等特点。而谈到消息系统的设计,就回避不了两个问题:消息的顺序问......
  • 国标GB28181视频平台LntonGBS(含源码)国标视频平台播放视频时偶尔出现播放失败的问题解
    LntonGBS是基于公安部推出的安防主流协议(国标GB28181协议)的视频接入、处理及分发平台,具有视频直播监控、云端录像、云存储、检索回放、智能告警、语音对讲等功能,能够涵盖所有监控领域的视频能力需求,已经在大量的项目中落地应用,如明厨亮灶、平安乡村、雪亮工程等。有用户反馈,在某项......
  • 基于RK3568J板卡高铁高清视频监控系统解决方案-迅为电子
     随着高速铁路的建设及铁路管理的精细化,越来越多的高速铁路在建设时已经开始规划高清视频监控系统,而现在铁路建设更是桥梁多、隧道多、公跨铁多,安全隐患增加,铁路的运行安全问题以及铁路沿线的设施安全、环境安全、铁路空域安全成为迫切需要解决的问题。    针对3568开......
  • AMEYA360:大唐恩智浦的DNB1168单电芯电池管理芯片方案
    暑期来临,很多朋友会选择短途近郊游,那么AMEYA360觉得电车自驾游不失为一种更经济实惠、绿色环保的出行方式。但是很多人会担心高温天气,万一电车突发事故,甚至起火了怎么办?对此担忧,AMEYA360完全理解,毕竟近年来由于高温天引发的电车起火等事故时有发生。电车热失控风险究其原......
  • 基于C#的无边框窗体动画效果的完美解决方案 - 开源研究系列文章
          最近在整理和编写基于C#的WinForm应用程序,然后碰到一个其他读者也可能碰到的问题,就是C#的Borderless无边框窗体的动画效果问题。      在VisualStudio2022里,C#的WinForm程序提供了Borderless无边框窗体的样式效果,但是它没提供在无边框窗体下,窗体的载入、最......
  • Vitamin Shoppe EDI 解决方案
    VitaminShoppe是一家在保健品和健身领域备受认可的卖场。多年来,VitaminShoppe致力于为客户提供高品质的健康产品和专业建议,以满足他们的健康需求。VitaminShoppeEDI需求分析EDI连接的传输协议:VitaminShoppeEDI项目中使用AS2(ApplicabilityStatement2)协议。AS2......
  • 服装行业MES系统解决方案|免费使用MES系统
    背景:近年我国服装及纺织业的高速发展带动了设备改造,从而为MES系统带来契机。目前国际上先进的服装及纺机设备,大部分落户于中国企业,大大提高了生产的智能化、数字化生产水平。这样,一方面解决了长期困扰纺织行业的生产设备数据自动采集问题,为企业实现生产制造管理自动化提供了基础条......
  • abricate 升级数据库报错解决方案
    利用conda下载的abricate,其数据库版本较老abricate--listDATABASESEQUENCESDBTYPEDATEmegares6635nucl2021-Mar-27resfinder3077nucl2021-Mar-27card2631nucl2021-Mar-27argannot2223nucl2021-M......
  • 国标GB28181视频平台LntonGBS(源码版)国标云服务平台对页面过多导致加载困难的问题解决
    LntonGBS国标视频云服务平台不仅支持无缝、完整接入内网或者公网的国标设备,在输出上,实现全平台、全终端输出。平台可将GB/T28181设备/平台推送的PS流转成ES流,并提供RTSP、RTMP、FLV、HLS、WebRTC等多种格式视频流的分发服务,实现Web浏览器、手机浏览器、微信端、PC客户端等各终端无......
  • 一个nginx + vue下二级路径版本化方案
    过程说明:1、arg_appver表示读取url上appver参数2、对appver参数做变量映射得到alias_party1_test路径。具体条件:没有指定参数的话(即"")指向2.8.0版本化文件夹;默认的话(即default)则指向动态拼接的路径3、第2点里面动态拼接如果不需要版本化则先固定一个路径,如果需要则使用$arg_ap......