Java项目不使用框架如何实现限流?

简介: Java项目不使用框架如何实现限流?

在Java项目中,如果不使用任何框架来实现限流,可以通过手动编写代码来控制请求的速率。以下是一个简单的示例,展示了如何使用令牌桶算法实现限流:

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class RateLimiter {
   
    private final long maxTokens; // 最大令牌数
    private final long refillTokens; // 每次补充的令牌数
    private final long refillPeriod; // 补充令牌的时间间隔(毫秒)
    private long lastRefillTimestamp; // 上次补充令牌的时间戳
    private long currentTokens; // 当前令牌数
    private final LinkedBlockingQueue<Long> tokenBucket; // 存放令牌的队列

    public RateLimiter(long maxTokens, long refillTokens, long refillPeriod) {
   
        this.maxTokens = maxTokens;
        this.refillTokens = refillTokens;
        this.refillPeriod = refillPeriod;
        this.lastRefillTimestamp = System.currentTimeMillis();
        this.currentTokens = maxTokens;
        this.tokenBucket = new LinkedBlockingQueue<>(maxTokens);

        // 初始化令牌桶
        for (int i = 0; i < maxTokens; i++) {
   
            tokenBucket.offer(System.currentTimeMillis());
        }

        // 启动一个定时任务,定期补充令牌
        new Thread(() -> {
   
            while (!Thread.interrupted()) {
   
                try {
   
                    TimeUnit.MILLISECONDS.sleep(refillPeriod);
                    refill();
                } catch (InterruptedException e) {
   
                    Thread.currentThread().interrupt();
                }
            }
        }).start();
    }

    public boolean tryAcquire() {
   
        long now = System.currentTimeMillis();
        if (now - lastRefillTimestamp >= refillPeriod) {
   
            refill();
        }

        if (tokenBucket.isEmpty()) {
   
            return false; // 没有可用的令牌
        } else {
   
            Long token = tokenBucket.poll();
            if (token != null && token <= now) {
   
                return true; // 令牌有效
            } else {
   
                tokenBucket.offer(token); // 放回无效的令牌
                return false; // 没有可用的令牌
            }
        }
    }

    private void refill() {
   
        long now = System.currentTimeMillis();
        long tokensToAdd = (now - lastRefillTimestamp + refillPeriod - 1) / refillPeriod * refillTokens;
        lastRefillTimestamp = now;
        currentTokens = Math.min(maxTokens, currentTokens + tokensToAdd);

        for (int i = 0; i < tokensToAdd; i++) {
   
            tokenBucket.offer(now);
        }
    }
}

使用这个RateLimiter类,可以在需要限流的地方调用tryAcquire()方法,如果返回true,则表示有可用的令牌,可以继续处理请求;如果返回false,则表示没有可用的令牌,可以选择拒绝请求或者排队等待。
Java限流算法主要包括以下几种:

  1. 固定窗口算法:这种算法通过一个支持原子操作的计数器来累计一定时间窗口内的请求次数。当请求次数达到设定的阈值时,触发拒绝策略。每过一个时间窗口,计数器重置为0重新开始计数[^2^]。

  2. 滑动窗口算法:这是对固定窗口算法的改进。在滑动窗口算法中,窗口的大小是固定的,但起止时间是动态的。它将一个大的时间窗口分割成多个小的子窗口,每个子窗口单独计数,所有子窗口的计数之和不超过整体阈值。当新请求的时间点超过时间窗口的右边界时,窗口向右移动一个小窗口的距离,最左边的小窗口的计数值被舍弃[^3^][^4^]。

  3. 漏桶算法:漏桶算法将请求看作是流入的水,水桶容量有限,水以恒定的速率流出。如果水桶满了,新的请求(水)就会被丢弃。这种方法可以平滑突发流量,保证流量以相对稳定的速率处理[^5^]。

  4. 令牌桶算法:令牌桶算法通过一个令牌桶来控制请求的速率。系统以一定的速率向桶中添加令牌,当有请求到达时,需要从桶中取出一个令牌才能继续处理。如果桶中没有令牌,请求要么排队等待,要么被直接拒绝。这种方法既可以控制请求的突发流量,又可以允许一定程度的突发请求处理[^5^]。

总的来说,这些算法各有优缺点,适用于不同的场景。选择合适的限流算法取决于具体的应用需求、系统性能要求以及预期的流量模式。

目录
相关文章
|
11月前
|
安全 前端开发 Java
《深入理解Spring》:现代Java开发的核心框架
Spring自2003年诞生以来,已成为Java企业级开发的基石,凭借IoC、AOP、声明式编程等核心特性,极大简化了开发复杂度。本系列将深入解析Spring框架核心原理及Spring Boot、Cloud、Security等生态组件,助力开发者构建高效、可扩展的应用体系。(238字)
|
11月前
|
存储 安全 Java
《数据之美》:Java集合框架全景解析
Java集合框架是数据管理的核心工具,涵盖List、Set、Map等体系,提供丰富接口与实现类,支持高效的数据操作与算法处理。
|
11月前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
913 8
|
11月前
|
存储 算法 安全
Java集合框架:理解类型多样性与限制
总之,在 Java 题材中正确地应对多样化与约束条件要求开发人员深入理解面向对象原则、范式编程思想以及JVM工作机理等核心知识点。通过精心设计与周密规划能够有效地利用 Java 高级特征打造出既健壮又灵活易维护系统软件产品。
275 7
|
12月前
|
IDE 安全 Java
Lombok 在企业级 Java 项目中的隐性成本:便利背后的取舍之道
Lombok虽能简化Java代码,但其“魔法”特性易破坏封装、影响可维护性,隐藏调试难题,且与JPA等框架存在兼容风险。企业级项目应优先考虑IDE生成、Java Records或MapStruct等更透明、稳健的替代方案,平衡开发效率与系统长期稳定性。
720 115
|
存储 小程序 Java
热门小程序源码合集:微信抖音小程序源码支持PHP/Java/uni-app完整项目实践指南
小程序已成为企业获客与开发者创业的重要载体。本文详解PHP、Java、uni-app三大技术栈在电商、工具、服务类小程序中的源码应用,提供从开发到部署的全流程指南,并分享选型避坑与商业化落地策略,助力开发者高效构建稳定可扩展项目。
|
安全 Java API
Java Web 在线商城项目最新技术实操指南帮助开发者高效完成商城项目开发
本项目基于Spring Boot 3.2与Vue 3构建现代化在线商城,涵盖技术选型、核心功能实现、安全控制与容器化部署,助开发者掌握最新Java Web全栈开发实践。
909 1
|
人工智能 Java 开发者
阿里出手!Java 开发者狂喜!开源 AI Agent 框架 JManus 来了,初次见面就心动~
JManus是阿里开源的Java版OpenManus,基于Spring AI Alibaba框架,助力Java开发者便捷应用AI技术。支持多Agent框架、网页配置、MCP协议及PLAN-ACT模式,可集成多模型,适配阿里云百炼平台与本地ollama。提供Docker与源码部署方式,具备无限上下文处理能力,适用于复杂AI场景。当前仍在完善模型配置等功能,欢迎参与开源共建。
3628 58
阿里出手!Java 开发者狂喜!开源 AI Agent 框架 JManus 来了,初次见面就心动~
|
SQL Java 数据库连接
区分iBatis与MyBatis:两个Java数据库框架的比较
总结起来:虽然从技术角度看,iBATIS已经停止更新但仍然可用;然而考虑到长期项目健康度及未来可能需求变化情况下MYBATISS无疑会是一个更佳选择因其具备良好生命周期管理机制同时也因为社区力量背书确保问题修复新特征添加速度快捷有效.
949 12
|
存储 缓存 安全
Java集合框架(三):Map体系与ConcurrentHashMap
本文深入解析Java中Map接口体系及其实现类,包括HashMap、ConcurrentHashMap等的工作原理与线程安全机制。内容涵盖哈希冲突解决、扩容策略、并发优化,以及不同Map实现的适用场景,助你掌握高并发编程核心技巧。