简单实现令牌桶限流

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);
        }
    }
相关推荐
dragoooon343 分钟前
[优选算法专题八.分治-归并 ——NO.46~48 归并排序 、数组中的逆序对、计算右侧小于当前元素的个数]
数据结构·算法·排序算法·分治
CoderYanger3 分钟前
优选算法-队列+宽搜(BFS):72.二叉树的最大宽度
java·开发语言·算法·leetcode·职场和发展·宽度优先·1024程序员节
招摇的一半月亮7 分钟前
P2242 公路维修问题
数据结构·c++·算法
赵大海16 分钟前
黑马《Java架构师实战训练营 (含完整资料)》
java
不带刺仙人球24 分钟前
list.stream().collect例子
java·list·dubbo
星轨初途27 分钟前
数据结构排序算法详解(5)——非比较函数:计数排序(鸽巢原理)及排序算法复杂度和稳定性分析
c语言·开发语言·数据结构·经验分享·笔记·算法·排序算法
人类发明了工具42 分钟前
【机器人-激光雷达】点云时间运动补偿
算法·机器人
Carve_the_Code1 小时前
分布式订单系统:订单号编码设计实战
java·后端
Home1 小时前
23种设计模式之代理模式(结构型模式二)
java·后端
程序员西西1 小时前
详细介绍Spring Boot中用到的JSON序列化技术?
java·后端