当前位置: 首页> 科技> IT业 > 微商城app官方下载_网络运营商远端无响应怎么解决_青岛seo网站排名优化_海外推广方法有哪些

微商城app官方下载_网络运营商远端无响应怎么解决_青岛seo网站排名优化_海外推广方法有哪些

时间:2025/7/11 20:16:31来源:https://blog.csdn.net/xiewenfeng520/article/details/147121049 浏览次数:0次
微商城app官方下载_网络运营商远端无响应怎么解决_青岛seo网站排名优化_海外推广方法有哪些

分布式限流器框架 eval-rate-limiter

文章目录

    • 分布式限流器框架 eval-rate-limiter
    • 前言
    • 设计
      • 流程图
    • 核心方法
      • tryAcquire 获取通信证
      • 增加访问次数 incrementRequestCount
      • 生成分布式 key generateRateLimiterKey
    • 测试
      • 测试代码
      • 结果
      • Redis 客户端

前言

基于 redis 实现的分布式限流器,实现如下效果

  • 对每个应用节点进行限流
    • 有需要的可以根据实际业务定制 rateLimiterKey 的生成规则,目前是针对 ip+port 进行限流
  • 控制限流的速率->次数/分钟

源码已上传 github

  • https://github.com/huajiexiewenfeng/eval-rate-limiter

设计

流程图

请添加图片描述

  • 时间窗口&最大条数可以配置

  • 采用 redis 的过期时间+increment 来实现时间窗口和计数功能

  • synchronized 防止多线程获取 count 产生一致性问题

  • key 采用实例的 host+port 来实现各个实例控制自己的发送速率

核心方法

tryAcquire 获取通信证

  • 获取当前的请求次数 currentCount
  • 比较 currentCount 和 MaxCount 的大小
    • 小于,那么 count++,返回 true,表示获取通行证成功
    • 否则,返回 false,表示获取通信证失败
    /*** 尝试获取限流通行证** @return true表示允许通过,false表示被限流*/public synchronized boolean tryAcquire() {if (!properties.getEnable()) {return true;}try {int currentCount = getCurrentRequestCount();if (currentCount >= properties.getMaxCount()) {logger.warn("Rate limit exceeded - window: {} minutes, max: {}, current: {}",properties.getWindowMinutes(),properties.getMaxCount(),currentCount);return false;}incrementRequestCount();return true;} catch (Exception e) {logger.error("Failed to acquire rate limit token for key: {}", rateLimiterKey, e);// 在限流器异常时默认放行,保证系统可用性return true;}}

增加访问次数 incrementRequestCount

  • 使用 redis increment 计数+1
  • 第一次设置过期时间为时间窗口
    private void incrementRequestCount() {Long count = valueOperations.increment(rateLimiterKey, 1);if (count != null && count == 1) {// 首次设置时初始化过期时间redisTemplate.expire(rateLimiterKey, properties.getWindowMinutes(), TimeUnit.MINUTES);}}

生成分布式 key generateRateLimiterKey

    private String generateRateLimiterKey() {String port = environment.getProperty("server.port", "unknown");String host = getLocalHostAddress();return String.format("%s:%s:%s", RATE_LIMITER_KEY_PREFIX, host, port);}

测试

测试代码

@SpringBootApplication
@EnableEvalRateLimiter
@RestController
@RequestMapping("/demo1")
public class Demo1Application {@Autowiredprivate RateLimiter rateLimiter;public static void main(String[] args) {SpringApplication.run(Demo1Application.class, args);}@GetMapping("/test")public String test(@RequestParam(value = "count", defaultValue = "105") int count) {for (int i = 0; i < count; i++) {doTest(i);}return "hello";}private void doTest(int count) {System.out.println("当前请求次数:" + count + ",节点限流剩余次数:" + rateLimiter.getRemainingRequests());if (!rateLimiter.tryAcquire()) {// 5秒后再发送try {Thread.sleep(5000L);} catch (InterruptedException e) {e.printStackTrace();}doTest(count);}}}

application.properties 配置

spring.application.name=${APPLICATION_NAME:demo1}
server.port=${SERVER_PORT:8091}#redis
eval.rate.limiter.redis.database=${REDIS_DB_INDEX:2}
eval.rate.limiter.redis.host=${REDIS_HOST:127.0.0.1}
eval.rate.limiter.redis.port=${REDIS_PORT:6379}
eval.rate.limiter.redis.password=${REDIS_INFRA_PASSWORD:1234567a}
#1分钟
eval.rate.limiter.redis.windowMinutes=${EVAL_RATE_LIMITER_WINDOW_MINUTES:1}
#100次
eval.rate.limiter.redis.maxCount=${EVAL_RATE_LIMITER_MAX_COUNT:100}

结果

请添加图片描述

到 1 分钟时间之后,又重新计数

请添加图片描述

Redis 客户端

  • key:host+ip,限制每个机器+端口
  • value:每访问一次,value+1,value 到达100(配置)后,不在增加

请添加图片描述

关键字:微商城app官方下载_网络运营商远端无响应怎么解决_青岛seo网站排名优化_海外推广方法有哪些

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: