当前位置: 首页 > wzjs >正文

泉州最专业手机网站建设开发百家号权重查询站长工具

泉州最专业手机网站建设开发,百家号权重查询站长工具,什么是asp网站,wordpress模板优化分布式限流方案:基于 Redis 的令牌桶算法实现 前言一、原理介绍:令牌桶算法二、分布式限流的设计思路三、代码实现四、方案优缺点五、 适用场景总结 前言 在分布式场景下,接口限流变得更加复杂。传统的单机限流方式难以满足跨节点的限流需求…

分布式限流方案:基于 Redis 的令牌桶算法实现

  • 前言
  • 一、原理介绍:令牌桶算法
  • 二、分布式限流的设计思路
  • 三、代码实现
  • 四、方案优缺点
  • 五、 适用场景
  • 总结


前言

在分布式场景下,接口限流变得更加复杂。传统的单机限流方式难以满足跨节点的限流需求,因此需要一种分布式限流方案。

这里介绍一种基于 RedisRedisson 实现的令牌桶算法分布式限流方案。


一、原理介绍:令牌桶算法

令牌桶算法是一种用于控制流量的经典算法,其基本原理如下:

  • 生成令牌:按照固定的速率向令牌桶中放入令牌。

  • 消耗令牌:每个请求到来时需要消耗一个令牌才能执行。

  • 桶满时丢弃令牌:如果令牌桶已满,额外生成的令牌会被丢弃。

  • 拒绝无令牌请求:当令牌桶为空且有请求到达时,拒绝该请求。

示意图

        +--------------------------+|      请求到达            |+--------------------------+|V+----------------------------+|   令牌桶中是否有令牌?     |+----------------------------+/            \是                 否/                     \
+--------------------+    +----------------------+
|    消耗令牌,放行   |    |   拒绝请求,限流    |
+--------------------+    +----------------------+

二、分布式限流的设计思路

在分布式环境中,多个节点需要共享限流状态。为了解决这个问题,我们采用 Redis 作为分布式存储,并通过 Redisson 的 RRateLimiter 组件实现分布式的令牌桶限流:

  1. Redis 统一存储令牌桶状态:
  • 使用 Redis 的 RRateLimiter 对象存储令牌桶的容量和剩余令牌数。
  1. 多节点共享限流状态:
  • 各个服务节点通过 Redis 读取和更新令牌桶状态,实现跨节点的流量控制。
  1. 动态配置更新:
  • 支持从 Redis 中动态获取限流配置,实现限流规则的热更新。
  1. 基于 IP + 接口路径的粒度限流:
  • 使用 api_limit:ip:apiPath 作为 Redis 的 Key,针对不同接口和 IP 进行精细化限流。

三、代码实现

  1. 初始化令牌桶

    /*** 获取指定接口的令牌桶(每个接口独立一个)** @param apiKey   接口唯一标识* @param rate     允许的请求数* @param interval 时间窗口(秒)* @return RRateLimiter 令牌桶实例*/
    public RRateLimiter getRateLimiter(String apiKey, int rate, int interval) {return rateLimiterCache.compute(apiKey, (key, existingLimiter) -> {String redisKey = String.format("%s:%s", RedisKeyConstant.DOC_RATE_LIMIT_PRE, key);RRateLimiter rateLimiter = redissonClient.getRateLimiter(redisKey);// 获取 Redis 中的当前限流配置List<Integer> config = getRateLimiterConfig(redisKey);Integer currentRate = config.get(0);Integer currentInterval = config.get(1);// 检查是否需要重新初始化if (existingLimiter != null && existingLimiter.isExists()&& Objects.equals(currentRate, rate)&& Objects.equals(currentInterval, interval)) {return existingLimiter;}log.warn("检测到限流配置变化或 RateLimiter 失效,重新初始化令牌桶 [{}]", redisKey);// 重新初始化令牌桶rateLimiter.delete();if (!rateLimiter.trySetRate(RateType.OVERALL, rate, interval, RateIntervalUnit.SECONDS)) {log.error("令牌桶 [{}] 初始化失败", redisKey);return null;}log.info("创建令牌桶 [{}],QPS: {}, 时间窗口: {} 秒", apiKey, rate, interval);return rateLimiter;});
    }
    
  2. 申请令牌

    /*** 申请一个令牌** @param ip   接口唯一标识* @param apiPath   接口唯一标识* @param rate     允许的请求数* @param interval 时间窗口(秒)* @return 是否成功获取令牌*/
    public boolean tryAcquire(String ip, String apiPath, int rate, int interval) {String apiKey = "api_limit:" + ip + ":" + apiPath;RRateLimiter rateLimiter = getRateLimiter(apiKey, rate, interval);if (rateLimiter == null) {return false;}boolean acquired = rateLimiter.tryAcquire();// Redis Key 可能被删除,需要重新初始化if (!acquired && !rateLimiter.isExists()) {log.warn("检测到 RateLimiter [{}] 失效,重新初始化", apiKey);rateLimiterCache.remove(apiKey);rateLimiter = getRateLimiter(apiKey, rate, interval);if (rateLimiter != null) {acquired = rateLimiter.tryAcquire();}}if (!acquired) {log.warn("接口 [{}] 触发限流,QPS: {}, 时间窗口: {} 秒", apiKey, rate, interval);}return acquired;
    }
    
  3. 统一限流校验方法

    /*** 令牌限流检查(对外暴露的方法)* @param rate      允许的请求数* @param interval  时间窗口(秒)* @throws ServiceException 如果触发限流*/
    public void checkRateLimit(int rate, int interval) {String clientIp = WebTool.getRealIpAddress(); // 获取真实 IPString apiPath = WebTool.getApiPath(); // 获取接口路径boolean allowed = tryAcquire(clientIp, apiPath, rate, interval);if (!allowed) {log.warn("ip: {}, 接口 [{}] 触发限流,QPS: {}, 时间窗口: {} 秒", clientIp, apiPath, rate, interval);String msg = String.format("访问过于频繁,请稍后再试。IP: %s", clientIp);throw new ServiceException(msg);}
    }
    

✅ 方案解析

1. 分布式环境下的限流

  • 使用 Redis 作为中心存储,每个接口的令牌桶都存储在 Redis 中,便于多个节点共享限流状态。

  • 使用 Redisson 提供的 RRateLimiter 对象,它基于 Redis 提供了令牌桶算法的封装,自动管理令牌生成和消费的过程。

2. 令牌桶的管理

  • 通过 getRateLimiter 方法动态创建和管理令牌桶。

  • 使用 rateLimiter.trySetRate() 设置令牌桶的容量和生成速率。

  • 每次请求前调用 rateLimiter.tryAcquire() 尝试获取一个令牌,如果成功则执行请求,否则拒绝。

3. 动态配置管理

  • 使用 Redis hget 命令读取当前限流配置(rateinterval),确保分布式环境下的限流配置保持一致。

  • 如果发现 Redis 中的配置与本地配置不一致或令牌桶失效,则重新初始化令牌桶。

4. IP + 接口路径粒度限流

  • 每个接口的限流是基于 api_limit:ip:apiPath 作为 Redis 的 Key,实现了IP + 接口级别的限流,可有效防止单个 IP 的恶意请求。

四、方案优缺点

优点缺点
支持分布式环境,多节点共享限流状态依赖 Redis,如果 Redis 异常会影响限流功能
支持突发流量,平滑处理请求需要额外维护 Redis 的资源占用
支持动态限流配置,实时生效需要额外监控 Redis 的健康状态
提供接口级和 IP 级别的精细化限流配置不当可能导致限流过于宽松或过于严格

五、 适用场景

  • API 网关限流:在 API 网关层通过该方案对外部流量进行限流,保护后端服务。

  • 防止恶意攻击:防止某个 IP 针对特定接口的恶意请求。

  • 限流突发流量:在秒杀、促销等场景中平滑处理流量峰值。

  • 支付接口保护:确保支付接口在高并发情况下依旧可用。


总结

基于 Redis 的分布式令牌桶限流方案是一个可靠且高效的限流策略。它不仅能够有效应对突发流量,还能在分布式环境下保持限流配置一致性。

通过合理的配置和监控,可以保障系统的稳定性,提升用户体验。😊

http://www.dtcms.com/wzjs/310601.html

相关文章:

  • 网站开发文档有哪些自建网站流程
  • 从网站下载壁纸做海报涉及百度推广优化师是什么
  • 网站开发有没有前途seo培训
  • 郑州建设银行网站房贷网点在哪里软文写作经验
  • 手机移动端网站怎么做seo电视剧排行榜百度搜索风云榜
  • 食品招商网网站推广关键词排名优化
  • 网站推广费用价格关键词优化平台有哪些
  • 深圳华强北二手手机seo外链网
  • 主题 外贸网站 模板手机怎么自己制作网页
  • 众筹网站怎么做推广怎么开发一个网站
  • 秦皇岛海三建设怎么样优化公司排名
  • 南昌网站开发模板sq网站推广
  • 沈阳网站推广优化公司哪家好浙江百度推广开户
  • 替别人做网站公司网站如何建设
  • 容桂做网站优化公司网站
  • 网站建设有什么岗位单页网站seo优化
  • 自己做的网站怎样赚钱吗哈尔滨seo公司
  • 网店代运营哪里找谷歌seo价格
  • 郎溪做网站淄博seo推广
  • 上海网站建设的意义谷歌优化师
  • nginx 网站开发东莞网络营销公司
  • 周口做网站哪家好收录之家
  • 平板做网站服务器百度广告公司
  • 湘潭建设网站制作seo教程技术整站优化
  • 南川网站制作线下推广方案
  • 天河商城型网站建设线上推广策划方案范文
  • 做网站用的编程工具做百度推广的网络公司广州
  • 做网站选什么配置电脑百度 指数
  • 做网站一月能赚50万吗广东深圳龙华区
  • 织梦做的网站怎么样如何快速推广网上国网