简单实现令牌桶限流

java 复制代码
package com.trpc.protection;

import lombok.extern.slf4j.Slf4j;

/**
 * 令牌桶限流器
 */
@Slf4j
public class TokenBucketRateLimiter implements RateLimiter{
    //令牌桶 >0有令牌
    private int tokenBucket;

    //令牌桶最大容量
    private final int max;

    //加入令牌的速率
    private final int rate;

    //上次放入令牌时间
    private long lastPutTokenTime;

    public TokenBucketRateLimiter( int max, int rate) {
        this.tokenBucket = max;
        this.max = max;
        this.rate = rate;
        this.lastPutTokenTime = System.currentTimeMillis();
    }
    /**
     * 判断是否放行请求
     * 多服务调用限流-->加锁
     * @return
     */
    public synchronized boolean allowRequest(){

        //1 添加令牌
        long currentTime = System.currentTimeMillis();  //拿到当前时间

        long needAddTokenTime = currentTime - lastPutTokenTime; //拿到时间差

        //2 设置间隔一秒放一次令牌
        if (needAddTokenTime >= 1000 ){
            int addTokenNums= (int) (needAddTokenTime * rate / 1000);// 乘上速率拿到需要添加的令牌书

            tokenBucket = Math.min(max, tokenBucket + addTokenNums);//给令牌桶添加令牌,到达最大值就用最大值,否则就用桶内余量+新增余量

            this.lastPutTokenTime=System.currentTimeMillis();//重置
        }

        //2自增令牌
        if (tokenBucket > 0){
            tokenBucket--;
            if (log.isDebugEnabled()){
                log.debug("------还有【{}】令牌存在,放行--------",tokenBucket);
            }
            return true;
        }else {
            if (log.isDebugEnabled()){
                log.debug("限流中请等待");
            }
            return false;
        }
    }
}

测试

java 复制代码
public static void main(String[] args) {
        TokenBucketRateLimiter tokenBucketRateLimiter = new TokenBucketRateLimiter(20,20);
        for (int i = 0; i < 21; i++) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            boolean b = tokenBucketRateLimiter.allowRequest();
            System.out.println("是否放行 = " + b);
        }
    }
相关推荐
小π军4 分钟前
最大重叠区间数量
数据结构·算法
镜像视界(浙江)科技有限公司13 分钟前
《视频孪生之上:二维展示终结,三维空间计算重构城市逻辑》——跨摄像连续表达 × 三角测量厘米级定位 × 动态轨迹建模,构建新一代城市空间
大数据·人工智能·算法·矩阵·音视频·空间计算
SL_staff28 分钟前
3天上线OKR系统:一名HR与1名工程师如何用JVS完成全栈交付
java·低代码·开源
a1879272183144 分钟前
【算法】双指针与滑动窗口(二):滑动窗口——吃进、判定、吐出
算法·leetcode·双指针·滑动窗口·原理·模板·算法讲解
铭哥的编程日记1 小时前
从一道 LeetCode Hard 到吃透一类题:加权区间调度「排序 + 二分 + DP」
算法·leetcode·职场和发展
Navigator_Z1 小时前
LeetCode //C - 1248. Count Number of Nice Subarrays
c语言·算法·leetcode
wzdark2 小时前
基于链表的内存池设计与内存复用机制4
java·数据结构·链表
wzdark2 小时前
多维数组在算法设计中的存储映射问题4
算法
cnkeysky2 小时前
idea 中的 maven 项目重新加载子模块
java·idea
Escalating_xu2 小时前
【System V 信号量】从 P/V 原语到 Builder 封装:写出可控、可清理的进程互斥组件
java·linux·开发语言·jvm