首页 > 其他分享 >网关限流功能性能优化

网关限流功能性能优化

时间:2024-06-04 19:23:41浏览次数:23  
标签:方案 网关 权重 redis 令牌 访问 限流 优化

本文主要从设计与原理方面分享优化过程中的思考,不涉及具体的代码实现。在分析过程中我会写一些当时思考的问题,在看后续答案时可以自己也先思考一下

老的限流方案

首先讲解一下原本网关限流功能的实现方案,省略其中的白名单,黑名单,令牌桶算法实现等一些细节
  • 限流策略中包含多种策略,比如根据用户维度限流,ip维度限流,接口维度限流等,每种限流策略各自维护自己的计数。任意一个策略触发限流拒绝都会拒绝请求
  • 每种限流策略都会设置好总允许的权重值,每次访问通过redis的lua脚本进行权重的扣除和增加,直到为0,扣除不了的则触发拒绝
  • 简单讲一下限流使用的令牌桶,网关会在redis中记录剩余令牌数和上次补充令牌的时间点,redis的key是限流维度生成的唯一id,比如用户维度则是特殊前缀+用户id。假设我们有一个令牌桶,初始令牌数为10,每5秒钟补充5个令牌,桶的最大容量也是10个令牌。那么令牌使用情况如下图:
  • 老限流的流程图:

限流存在的问题

总体来看,这个限流的方案还是比较简单的,当流量不大的时候也可以正常运行。
但是流量大的时候存在一些问题,大家可以先想一下有哪些问题?

  1. 一次请求由于需要从多个维度进行限流,所以会串行的多次访问redis,每次io都需要消耗时间
  2. lua脚本在redis中执行,redis的性能成为瓶颈,一方面是cpu高,另一方面redis的命令也是串行的,后面的命令需要等待前面的命令
  3. 即使权重已经扣除到0了,当请求过来时,仍然需要访问redis去判断是否可以通过

分析和优化思路

针对这3个问题,我们分析一下,都有哪些处理方案,以及这些方案的优缺点

第一个问题:多次串行IO
  1. 多线程并行访问

    • 并行可以同时进行网络请求,虽然总次数没有少,但是总时间可以减少到最慢的那次请求的耗时。比如,每次1秒,串行访问3次,总耗时3秒,改为并行则只需要1秒。
    • 串行改并行一般来说改动起来会小一些,比较好实现。可以节省时间。但是本质上没有减少资源消耗
    • 同时由于本次请求的是redis,redis仍然需要进行串行执行
    • 所以这个方案并不好
  2. 合并请求批量访问

    • 在这个场景中,时间消耗分为,io耗时+redis执行耗时。
    • 批量访问可以减少io耗时的部分,但是不会减少redis执行耗时。
    • 总体来看这个方案可以减少总耗时,但是由于需要聚合请求,分发响应,因此代码改动会稍微大一些。
    • 目前看是一个可行的方案
  3. 减少redis的访问

    • 首先我们要分析redis的作用是什么,为什么我们需要访问redis?
      • 由于网关是无状态的,限流是全局维度的,所以针对这个场景我们利用redis作为一个中心化的数据保存,也就是每个策略的权重数据。其次由于请求是并发的,所以我们利用了redis来保证权重加减的原子性。在这2个原因中的3个关键点是:数据保存,中心化和原子性。
    • 数据保存通常来讲我们遵循(内存>redis>数据库)。那我们是否可以用内存代替redis实现数据保存?
      • 如果网关只有一台机器,那么是可行的,但是现在由于多台机器,所以中心化这个关键点限制了我们把数据从redis改为内存。
    • 那我们改进一下这个思路,能不能把部分数据改为内存?
      • 数据是权重数据,本质上就是一个计数器。那我们将计数器的一部分值放到内存中,扣除完了之后再来redis扣除一次(这个思路其实就是java中的TLAB机制的启发)。
    • 数据保存和中心化都没问题了,那原子性是否可以保证?
      • 不同机器从redis中扣除这部分逻辑与之前是一致的,所以原子性没问题,保存在内存中的值,只会被单机操作一定可以保证原子性(最差就是加锁)。
    • 那么最终分析之后这个方案也是可行的
第二个问题: redis执行lua脚本成为瓶颈
  1. 优化lua脚本
    • lua脚本实现的是令牌桶算法,在当前场景下没有发现优化空间,因此不考虑
  2. redis分片处理
    • 不同的key路由到不同的redis中,可以解决瓶颈问题,方案可行,但是本质上没有减少资源消耗
  3. 减少redis访问
    • 同上一个问题的解决方案,方案可行
第三个问题:权重扣除为0,仍然访问redis
  1. 还是先分析原因,为什么权重为0时我们需要访问redis?
    • 因为内存中并不知道权重是否已经为0,这个数据只在redis中存在。
  2. 那我们有什么办法可以提前知道redis中权重是否为0?
    • 好像没有办法
  3. 但是如果上一次请求返回了权重为0,那么这一次请求是否可以判断出redis中权重是否为0?
    • 答案是部分可以。
    • 利用令牌桶算法的特点,令牌桶每隔一定时间会增加令牌。如果当前权重已经是0,且在到需要增加令牌的时间之前,权重一定一直为0。
    • 所以当上一次请求返回为0时,同时记录上一次补充令牌的时间点,那么就可以推算出在哪个时间点前,权重一直为0,那么此时就不需要再次访问redis。
    • 通过这种方式可以极大的减少权重为0时的redis访问。不管总请求数是多少,在一个令牌补充周期内,每台机器只会在权重为0时访问一次redis。
    • 这个问题的解决方案与上2个问题的解决方案同时兼容,因此也是可行的

优化后的方案

现在我们总结上面的问题解决方案:

  • 可以看到减少redis访问这个方案可以同时解决第一个和第二个问题,并且真实的减少了资源消耗
  • 第三个问题的解决方案也不冲突,因此优化后的限流方案改为如下流程:
新方案的优点
  • 从原本一次请求多次redis访问变成了,多次请求一次redis操作
  • 大部分扣除权重不经过网络,纯内存操作
  • redis访问极大的减少,redis的消耗变小
  • 权重扣完后不会再请求redis,避免恶意流量打垮redis
新方案有什么缺点?
  • 限流的精确度变差,限流的边界值被模糊了
    • 比如原本限流1w次,现在变成不到1w次就已经触发了限流
    • 已经触发限流后,在补充令牌前,后面的请求可能又可以成功
  • 这个缺点我认为是可以接受的,毕竟我们的限流没有必要那么的精确,可以容忍
  • 提一个问题,假设一个令牌周期内限流1w次,新方案的限流最早从第多少次会触发第一次限流?和哪些因素有关?

优化后的效果

redis的cpu使用率从85% -> 5%

机器的cpu使用率从70% -> 50%

优化后的总结

  • 优化的首要关键因素是能发现问题,也就是优化点
    • 一般最直接的方式就是通过监控发现,所以监控很重要
    • 业务的理解程度也很大程度上会影响你是否能发现问题
  • 其次是问题的解决方案
    • 解决方案跟个人经验有关系,但是大部分的问题的解决方案都是类似的,通过其他人的问题解决方案来积累经验我认为是最值的
    • 一般来讲很难一下子就想到最优方案。想出一种方案后最好再思考一下,有哪些缺点,还有没有其他方案。比较多个方案选一个相对最优的方案
  • 优化时常用的一些思路
    • 通用方案不一定是最好的,可以利用一些功能的特点去针对性的优化
    • 优化到一定程度后,一般很难做到十全十美,通过放弃一部分东西可以换取一些你更需要的东西,比如空间换时间

如果觉得本文的内容有不足之处,欢迎指出
总觉得自己写的文章语言都好生硬,不知道怎么改善

标签:方案,网关,权重,redis,令牌,访问,限流,优化
From: https://www.cnblogs.com/wsss/p/18231400

相关文章

  • 1500PLC通过232自由口转profinet网关接ABB扫码枪通讯方案
    一、现状:在实际的生产环境中,越来越多的自动化设备采用扫码枪录入代替手动录入信息的方式进行操作。二、了解现场现场要求在不动其他设备和程序的情况下让ABB扫码枪与1500PLC通讯,在拿到现场的需求时兴达易控的专项技术为其制定了方案。 三、制定方案:在不动其他设备和程序的......
  • redis限流
    前提redis+lua 滑动窗口--滑动窗口localkey=KEYS[1]localmaxSize=ARGV[1]localcurrentTime=ARGV[2]localstartTime=ARGV[3]localuuid=ARGV[4]localcurrentCount=redis.call('zcount',key,startTime,currentTime)if(currentCountandtonumber......
  • 数据类岗位简历优化指南
    描述数据类项目:描述数据源在描述数据源时,将数据具体化。量化结果时,对于模型项目,可以将最后的准确率与随机准确率相比,对于分析项目,可以将最终的提升幅度与项目预期或同期的其他项目相比。|描述|改进后||---|---||从大量/海量数据中...|从300万元的店铺销售额数据......
  • 淘宝商品搜索API返回值解析:关键字搜索如何优化商品推荐
    淘宝商品搜索API的返回值通常包含了大量的商品信息,这些信息对于优化商品推荐至关重要。以下是一些建议,帮助你基于关键字搜索优化商品推荐:理解API返回值:首先,确保你完全理解API返回的数据结构。通常,这包括商品ID、标题、价格、图片URL、销售数量、评分等。分析这些字段,确定哪......
  • 梵几 x TapData:如何高效落地实时数据中台,助力家居企业优化数字营销
    使用TapData,化繁为简,摆脱手动搭建、维护数据管道的诸多烦扰,轻量代替OGG、DSG等同步工具,「CDC+流处理+数据集成」组合拳,加速数据流转,帮助企业将真正具有业务价值的数据作用到实处,将“实时数仓”等实时的中央化数据存储方法论落进现实。TapData持续迭代产品能力,优化用户体......
  • 网站优化的七大优化方式
    随着网站的普及与发展,网站优化成为了许多企业和个人关注的焦点。那么,网站优化到底包括哪些优化方式呢?下面将为大家一一介绍。一、网站内容优化网站内容是用户访问网站的核心,良好的内容可以吸引用户的注意力,提高用户体验,并且对搜索引擎也有很大的影响。优化网站内容包括以下几个......
  • C++的vector使用优化
    我们在上一章说了如何使用这个vector动态数组,这章我们说说如何更好的使用它以及它是如何工作的。当你创建一个vector,然后使用push_back添加元素,当当前的vector的内存不够时,会从内存中的旧位置复制到内存中的新位置,然后删除删除旧位置的内存,也就是说当我push_back,vector容量不够......
  • 北京Profinet转Modbus网关配置调试详解
    一、背景:在工业自动化系统中,PLC(可编程逻辑控制器)与流量计之间的通信是非常重要的,以确保数据准确传输并实现控制功能。然而,由于PLC和流量计可能采用不同的通信协议(如Profinet和Modbus),因此需要一种转换机制来实现它们之间的通信。在这种情况下,Profinet转Modbus网关成为了一个理想的......
  • 数据治理--企业数据服务 数据连接注册成API并且通过网关去限流 数据同步
      不直接开发hive的API访问速度慢,开放内存Presto的API去hive库查这样快 第一种不安全, 第二种公司内部用比较安全,结构文件落到对方ftp服务器 第三种一般跨网络同步 数据同步任务创建和执行监控          证券案例 ......
  • Oracle优化神技之临时表
    Oracle临时表在处理临时数据、会话数据隔离和复杂查询优化方面非常有用。其底层逻辑是通过Oracle特殊的临时表来减少I/O操作和日志开销,提高了数据库性能和查询效率。开发者可以根据具体需求和场景,合理使用临时表来简化数据处理逻辑和提高系统性能。早期开发人员在使用Oracle数据......