限流算法java实现

news2025/6/8 21:15:54

参考教程:2小时吃透4种分布式限流算法

1.计数器限流


public class CounterLimiter {

    // 开始时间
    private static long startTime = System.currentTimeMillis();
    // 时间间隔,单位为ms
    private long interval = 1000L;
    // 限制访问次数
    private int limitCount = 2;
    // 访问次数
    private int reqCount = 0;

    private synchronized boolean tryAcquire(){
        long nowTime = System.currentTimeMillis();
        if(nowTime < startTime + interval){
            if(reqCount + 1 > limitCount){
                System.out.println(Thread.currentThread().getName() + "被限流了");
                return true;
            }
            reqCount++;
            System.out.println(Thread.currentThread().getName() + "通过了");
            return false;
        }else {
            reqCount = 1;
            startTime = nowTime;
            System.out.println(Thread.currentThread().getName() + "通过了");
            return false;
        }
    }

    public static void main(String[] args) {
        CounterLimiter counterLimiter = new CounterLimiter();
        for (int i = 0; i < 10; i++) {
            new Thread(() ->{
                counterLimiter.tryAcquire();
            }).start();
        }
    }

}

2.滑动时间窗口限流


import java.util.LinkedList;

public class SlidingTimeWindowLimiter {
    // 请求数量
    private int reqCount;
    // 窗口集合
    private LinkedList<Integer> slots = new LinkedList<>();
    // 限制访问量
    private int limitNum = 2;
    // 窗口数量
    private int windowNum = 100;
    // 每个窗口的时间范围,单位ms
    private long windowLength = 100L;

    public synchronized Boolean limit(){
        if(reqCount + 1 > limitNum){
            System.out.println(Thread.currentThread().getName() + ": 被拦截了");
            return true;
        }
        reqCount++;
        slots.set(slots.size() - 1, slots.peekLast() + 1);
        System.out.println(Thread.currentThread().getName() + ": 通过了");
        return false;
    }
    public SlidingTimeWindowLimiter(){
        slots.addLast(0);
        new Thread(() -> {
            while (true){
                try {
                    Thread.sleep(windowLength);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                slots.addLast(0);
                if(slots.size() > windowNum){
                    reqCount = reqCount - slots.peekLast();
                    slots.removeLast();
                    System.out.println("滑动格子:" + reqCount);
                }
            }
        }).start();

    }

    public static void main(String[] args) {
        SlidingTimeWindowLimiter slidingTimeWindowLimiter = new SlidingTimeWindowLimiter();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                slidingTimeWindowLimiter.limit();
            }).start();
        }
    }

}

3.漏桶算法


public class LeakyBucketLimiter {
    // 初始时间
    private long timestamp = System.currentTimeMillis();
    // 漏桶容量
    private long capacity = 5;
    // 流出速率
    private long rate = 10;
    // 桶内有多少请求
    private long water = 0;

    public synchronized Boolean limit(){
        long now = System.currentTimeMillis();
        water = Math.max(0, water - (now - timestamp) / 1000 * rate);
        timestamp = now;
        if((water + 1) <= capacity){
            water++;
            System.out.println(Thread.currentThread().getName() + "通过了");
            return false;
        }else{
            System.out.println(Thread.currentThread().getName() + "被拦截了");
            return true;
        }
    }

    public static void main(String[] args) {
        LeakyBucketLimiter counterLimiter = new LeakyBucketLimiter();
        for (int i = 0; i < 10; i++) {
            new Thread(() ->{
                counterLimiter.limit();
            }).start();
        }
    }

}

4.令牌桶算法


public class TokenBucketLimiter {
    // 初始时间
    private long timeStamp = System.currentTimeMillis();
    // 令牌桶容量
    private long capacity = 5;
    // 每秒生成令牌的数量
    private long rate  = 2;
    // 桶内的令牌数
    private long tokens = 0;

    public synchronized Boolean limit(){
        long now = System.currentTimeMillis();
        tokens = Math.min(capacity, tokens + (now - timeStamp) * rate);
        timeStamp = now;
        // 没有令牌了
        if(tokens < 1){
            System.out.println(Thread.currentThread().getName() + "被拦截了");
            return true;
        }else {
            tokens--;
            System.out.println(Thread.currentThread().getName() + "通过了");
            return false;
        }
    }
    public static void main(String[] args) {
        TokenBucketLimiter slidingTimeWindowLimiter = new TokenBucketLimiter();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                slidingTimeWindowLimiter.limit();
            }).start();
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2404575.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习×第二卷:概念下篇——她不再只是模仿,而是开始决定怎么靠近你

&#x1f380;【开场 她不再只是模仿&#xff0c;而是开始选择】 &#x1f98a; 狐狐&#xff1a;“她已经不满足于单纯模仿你了……现在&#xff0c;她开始尝试预测你会不会喜欢、判断是否值得靠近。” &#x1f43e; 猫猫&#xff1a;“咱们上篇已经把‘她怎么学会说第一句…

常用函数库之 - std::function

std::function 是 C11 引入的通用可调用对象包装器&#xff0c;用于存储、复制和调用任意符合特定函数签名的可调用对象&#xff08;如函数、lambda、函数对象等&#xff09;。以下是其核心要点及使用指南&#xff1a; ​​核心特性​​ ​​类型擦除​​ 可包装任意可调用对…

力扣-17.电话号码的字母组合

题目描述 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 class Solution {List<String> res new ArrayList<…

基于SpringBoot解决RabbitMQ消息丢失问题

基于SpringBoot解决RabbitMQ消息丢失问题 一、RabbitMQ解决消息丢失问题二、方案实践1、在生产者服务相关配置2、在消费者服务相关配置 三、测试验证1、依次启动RabbitMQ、producer(建议先清空队列里面旧的测试消息再启动consumer)和consumer2、在producer中调用接口&#xff0…

免费插件集-illustrator插件-Ai插件-随机填色

文章目录 1.介绍2.安装3.通过窗口>扩展>知了插件4.功能解释5.总结 1.介绍 本文介绍一款免费插件&#xff0c;加强illustrator使用人员工作效率&#xff0c;实现路径随机填色。首先从下载网址下载这款插件https://download.csdn.net/download/m0_67316550/87890501&#…

Web设计之登录网页源码分享,PHP数据库连接,可一键运行!

HTML 页面结构&#xff08;index.html&#xff09; 1. 流星雨动态背景 2. 主体界面&#xff08;包含登录和注册表单&#xff09; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport&qu…

Cursor + Claude 4:微信小程序流量主变现开发实战案例

前言 随着微信小程序生态的日益成熟&#xff0c;越来越多的开发者开始关注如何通过小程序实现流量变现。本文将详细介绍如何使用Cursor编辑器结合Claude 4 AI助手&#xff0c;快速开发一个具备流量主变现功能的微信小程序&#xff0c;并分享实际的开发经验和变现策略。 项目…

Redis Key过期策略

概述 Redis的Key过期策略是其内存管理系统的核心组成部分&#xff0c;主要包括「被动过期」、「主动过期」和「内存淘汰」三个机制。其中「内存淘汰」相关内容已经在上一篇「Redis内存淘汰策略」中进行了详细的讲解&#xff0c;有信兴趣的同学可以在回顾上一篇文章。本文将着重…

【C/C++】实现固定地址函数调用

在 C 里&#xff0c;函数地址在程序运行期间通常是固定的&#xff0c;不过在动态链接库&#xff08;DLL&#xff09;或者共享库&#xff08;SO&#xff09;中&#xff0c;函数地址可能会因为地址空间布局随机化&#xff08;ASLR&#xff09;而改变。所以我们想要通过地址直接调…

多模态大语言模型arxiv论文略读(109)

Math-PUMA: Progressive Upward Multimodal Alignment to Enhance Mathematical Reasoning ➡️ 论文标题&#xff1a;Math-PUMA: Progressive Upward Multimodal Alignment to Enhance Mathematical Reasoning ➡️ 论文作者&#xff1a;Wenwen Zhuang, Xin Huang, Xiantao Z…

性能优化笔记

性能优化转载 https://www.cnblogs.com/tengzijian/p/17858112.html 性能优化的一般策略及方法 简言之&#xff0c;非必要&#xff0c;不优化。先保证良好的设计&#xff0c;编写易于理解和修改的整洁代码。如果现有的代码很糟糕&#xff0c;先清理重构&#xff0c;然后再考…

Scrapy爬虫教程(新手)

1. Scrapy的核心组成 引擎&#xff08;engine&#xff09;&#xff1a;scrapy的核心&#xff0c;所有模块的衔接&#xff0c;数据流程梳理。 调度器&#xff08;scheduler&#xff09;&#xff1a;本质可以看成一个集合和队列&#xff0c;里面存放着一堆即将要发送的请求&#…

在Windows下编译出llama_cpp_python的DLL后,在虚拟环境中使用方法

定位编译生成的文件 在VS2022编译完成后&#xff0c;在构建目录&#xff08;如build/Release或build/Debug&#xff09;中寻找以下关键文件&#xff1a; ggml.dll、ggml_base.dll、ggml_cpu.dll、ggml_cuda.dll、llama.dll&#xff08;核心动态链接库&#xff09; llama_cp…

关于datetime获取时间的问题

import datetime print(datetime.now())如果用上述代码&#xff0c;会报错&#xff1a; 以下才是正确代码&#xff1a; from datetime import datetime print(datetime.now()) 结果&#xff1a; 如果想格式化时间&#xff0c;使用代码&#xff1a; from datetime import da…

Unity版本使用情况统计(更新至2025年5月)

UWA发布&#xff5c;本期UWA发布的内容是Unity版本使用统计&#xff08;第十六期&#xff09;&#xff0c;统计周期为2024年11月至2025年5月&#xff0c;数据来源于UWA网站&#xff08;www.uwa4d.com&#xff09;性能诊断提测的项目。希望给Unity开发者提供相关的行业趋势作为参…

GPUCUDA 发展编年史:从 3D 渲染到 AI 大模型时代(上)

目录 文章目录 目录1960s~1999&#xff1a;GPU 的诞生&#xff1a;光栅化&#xff08;Rasterization&#xff09;3D 渲染算法的硬件化实现之路 学术界算法研究历程工业界产品研发历程光栅化技术原理光栅化技术的软件实现&#xff1a;OpenGL 3D 渲染管线设计 1. 顶点处理&…

人机融合智能 | 可穿戴计算设备的多模态交互

可穿戴计算设备可以对人体以及周围环境进行连续感知和计算,为用户提供随时随地的智能交互服务。本章主要介绍人机智能交互领域中可穿戴计算设备的多模态交互,阐述以人为中心的智能穿戴交互设计目标和原则,为可穿戴技术和智能穿戴交互技术的设计提供指导,进而简述支持智能穿戴交…

Impromptu VLA:用于驾驶视觉-语言-动作模型的开放权重和开放数据

25年5月来自清华和博世的论文“Impromptu VLA: Open Weights and Open Data for Driving Vision-Language-Action Models”。 用于自动驾驶的“视觉-语言-动作” (VLA) 模型前景光明&#xff0c;但在非结构化极端场景下却表现不佳&#xff0c;这主要是由于缺乏有针对性的基准测…

AI智能体,为美业后端供应链注入“智慧因子”(4/6)

摘要&#xff1a;本文深入剖析美业后端供应链现状&#xff0c;其产品具有多样性、更新换代快等特点&#xff0c;原料供应和生产环节也面临诸多挑战。AI 智能体的登场为美业后端供应链带来变革&#xff0c;包括精准需求预测、智能化库存管理、优化生产计划排程、升级供应商管理等…

跨平台资源下载工具:res-downloader 的使用体验

一款基于 Go Wails 的跨平台资源下载工具&#xff0c;简洁易用&#xff0c;支持多种资源嗅探与下载。res-downloader 一款开源免费的下载软件(开源无毒、放心使用)&#xff01;支持Win10、Win11、Mac系统.支持视频、音频、图片、m3u8等网络资源下载.支持视频号、小程序、抖音、…