栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > Java

java基于内存实现的令牌桶限流工具类

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java基于内存实现的令牌桶限流工具类

基于内存实现的限流工具类,适用于可以容忍单节点限流的场景。
由于redis实现令牌桶需要每次都访问redis,所以做了一个内存的工具类,实现逻辑和redis的一样。

优点:1 不依赖其他中间件。2 数据都存放在本机内存,没有外部交互性能更高
缺点:1 没有任何持久化,重启后信息全部丢失。2 多节点流量不可控或者说不精准

首先考虑缓存实现,需要满足每个令牌桶不同的过期时间。hutool工具包中有相关的工具,所以不用造轮子了。
mvn依赖:

			
				cn.hutool
				hutool-all
				5.7.3
			
import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;



public class InMemoryRateLimit{

    private TimedCache cache;

    public InMemoryRateLimit(){
        cache = CacheUtil.newTimedCache(0);
        cache.schedulePrune(60*1000);
        // 销毁时调用cache.cancelPruneSchedule();
    }


    
    public boolean tryAllowed(String id, int rate, int capacity, int requested) {
        String intern = id.intern();
        int ttl = BigDecimal.valueOf(capacity).divide(BigDecimal.valueOf(rate), 0, RoundingMode.CEILING).multiply(BigDecimal.valueOf(2)).intValue();
        long now = Instant.now().getEpochSecond();
        Long lastToken;
        Long timestamp;
        boolean allowed = false;
        synchronized (intern){
            Node node = cache.get(id);
            if(node!=null){
                lastToken = node.getLastTokens();
                timestamp = node.getTimestamp();
            }else{
                node = new Node();
                lastToken = new Long(capacity);
                timestamp = 0L;
            }
            long timeDiff = now-timestamp;
            long filledTokens = Math.min(capacity, lastToken + (timeDiff * rate));
            if(filledTokens>=requested){
                filledTokens = filledTokens-requested;
                allowed = true;

            }
            node.setLastTokens(filledTokens);
            node.setTimestamp(now);
            cache.put(intern, node, ttl*1000);
        }
        return allowed;
    }




    @Data
    @NoArgsConstructor
    private static class Node{
        
        private volatile Long timestamp;
        
        private volatile Long lastTokens;
    }

}
转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1040869.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号