简单实现令牌桶限流

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);
        }
    }
相关推荐
道可到2 小时前
Java 反射现代实践速查表(JDK 11+/17+)
java
Fanxt_Ja2 小时前
【LeetCode】算法详解#15 ---环形链表II
数据结构·算法·leetcode·链表
侃侃_天下2 小时前
最终的信号类
开发语言·c++·算法
道可到2 小时前
Java 反射现代实践指南(JDK 11+ / 17+ 适用)
java
茉莉玫瑰花茶2 小时前
算法 --- 字符串
算法
玉衡子2 小时前
九、MySQL配置参数优化总结
java·mysql
叽哥2 小时前
Kotlin学习第 8 课:Kotlin 进阶特性:简化代码与提升效率
android·java·kotlin
麦兜*2 小时前
MongoDB Atlas 云数据库实战:从零搭建全球多节点集群
java·数据库·spring boot·mongodb·spring·spring cloud
带刺的坐椅2 小时前
DamiBus v1.1.0 发布(给单体多模块解耦)
java·事件总线·damibus
葡萄城技术团队2 小时前
用 Java 构建健壮 REST API 的 4 个关键技巧
java