当前位置:   article > 正文

【限流算法】java实现滑动时间窗口算法_滚动算法统计热key怎么算java

滚动算法统计热key怎么算java

本文实现了一种基于java的滑动时间窗口计数器算法

滑动时间窗口计数器算法思想:针对固定时间算法会在临界点存在瞬间大流量冲击的场景,滑动时间窗口计数器算法应运而生。它将时间窗口划分为更小的时间片段,每过一个时间片段,我们的时间窗口就会往右滑动一格,每个时间片段都有独立的计数器。我们在计算整个时间窗口内的请求总数时会累加所有的时间片段内的计数器。时间窗口划分的越细,那么滑动窗口的滚动就越平滑,限流的统计就会越精确。

本文代码逻辑:新建一个本地缓存,每5s为一个时间窗口,每1s为一个时间片段,时间片段作为缓存的key,原子类计数器作为缓存的value。每秒发送随机数量的请求,计算每个时间片段的前5秒内的累加请求数量,超出阈值则限流。

  1. @Slf4j
  2. public class WindowLimiter {
  3. private LoadingCache<Long, AtomicLong> counter =
  4. CacheBuilder.newBuilder()
  5. .expireAfterWrite(10, TimeUnit.SECONDS)
  6. .build(new CacheLoader<Long, AtomicLong>() {
  7. @Override
  8. public AtomicLong load(Long seconds) throws Exception {
  9. return new AtomicLong(0);
  10. }
  11. });
  12. private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
  13. //限流阈值
  14. private long limit = 15;
  15. /**
  16. * 滑动时间窗口
  17. * 每隔1s累加前5s内每1s的请求数量,判断是否超出限流阈值
  18. */
  19. public void slideWindow() {
  20. scheduledExecutorService.scheduleWithFixedDelay(() -> {
  21. try {
  22. long time = System.currentTimeMillis() / 1000;
  23. //每秒发送随机数量的请求
  24. int reqs = (int) (Math.random() * 5) + 1;
  25. counter.get(time).addAndGet(reqs);
  26. long nums = 0;
  27. // time windows 5 s
  28. for (int i = 0; i < 5; i++) {
  29. nums += counter.get(time - i).get();
  30. }
  31. log.info("time=" + time + ",nums=" + nums);
  32. if (nums > limit) {
  33. log.info("限流了,nums=" + nums);
  34. }
  35. } catch (Exception e) {
  36. log.error("slideWindow error", e);
  37. } finally {
  38. }
  39. }, 5000, 1000, TimeUnit.MILLISECONDS);
  40. }
  41. }

输出结果:

20:14:50.083 [pool-1-thread-3] INFO com.example.demo.limit.WindowLimiter - time=1574079290,nums=15
20:14:51.114 [pool-1-thread-3] INFO com.example.demo.limit.WindowLimiter - time=1574079291,nums=13
20:14:52.119 [pool-1-thread-3] INFO com.example.demo.limit.WindowLimiter - time=1574079292,nums=14
20:14:53.121 [pool-1-thread-3] INFO com.example.demo.limit.WindowLimiter - time=1574079293,nums=15
20:14:54.126 [pool-1-thread-3] INFO com.example.demo.limit.WindowLimiter - time=1574079294,nums=17
20:14:54.127 [pool-1-thread-3] INFO com.example.demo.limit.WindowLimiter - 限流了,nums=17
20:14:55.128 [pool-1-thread-3] INFO com.example.demo.limit.WindowLimiter - time=1574079295,nums=14
20:14:56.131 [pool-1-thread-3] INFO com.example.demo.limit.WindowLimiter - time=1574079296,nums=17
20:14:56.132 [pool-1-thread-3] INFO com.example.demo.limit.WindowLimiter - 限流了,nums=17

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/274638
推荐阅读
相关标签
  

闽ICP备14008679号