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^]。

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

目录
相关文章
|
1月前
|
IDE Java 开发工具
Java系统中的错误码设计问题之为Java项目中的错误消息提供国际化支持如何解决
Java系统中的错误码设计问题之为Java项目中的错误消息提供国际化支持如何解决
34 0
|
2天前
|
Java
使用IDEA创建项目运行我的第一个JAVA文件输出Helloword
本文介绍了如何使用IDEA(IntelliJ IDEA)创建一个新的Java项目,并运行一个简单的Java程序输出"Hello Word"。文章详细展示了创建项目的步骤,包括选择JDK版本、设置项目名称和路径、创建包和类,以及编写和运行代码。最后,还展示了如何通过IDEA的运行功能来执行程序并查看输出结果。
20 4
使用IDEA创建项目运行我的第一个JAVA文件输出Helloword
|
3天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
339 5
|
7天前
|
Kubernetes Java Android开发
用 Quarkus 框架优化 Java 微服务架构的设计与实现
Quarkus 是专为 GraalVM 和 OpenJDK HotSpot 设计的 Kubernetes Native Java 框架,提供快速启动、低内存占用及高效开发体验,显著优化了 Java 在微服务架构中的表现。它采用提前编译和懒加载技术实现毫秒级启动,通过优化类加载机制降低内存消耗,并支持多种技术和框架集成,如 Kubernetes、Docker 及 Eclipse MicroProfile,助力开发者轻松构建强大微服务应用。例如,在电商场景中,可利用 Quarkus 快速搭建商品管理和订单管理等微服务,提升系统响应速度与稳定性。
27 5
|
8天前
|
机器学习/深度学习 数据采集 JavaScript
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
ADR药品不良反应监测系统是一款智能化工具,用于监测和分析药品不良反应。该系统通过收集和分析病历、处方及实验室数据,快速识别潜在不良反应,提升用药安全性。系统采用Java开发,基于SpringBoot框架,前端使用Vue,具备数据采集、清洗、分析等功能模块,并能生成监测报告辅助医务人员决策。通过集成多种数据源并运用机器学习算法,系统可自动预警药品不良反应,有效减少药害事故,保障公众健康。
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
|
25天前
|
Java 数据库连接 Apache
Java进阶-主流框架总结与详解
这些仅仅是 Java 众多框架中的一部分。每个框架都有其特定的用途和优势,了解并熟练运用这些框架,对于每一位 Java 开发者来说都至关重要。同时,选择合适框架的关键在于理解框架的设计哲学、核心功能及其在项目中的应用场景。随着技术的不断进步,这些框架也在不断更新和迭代以适应新的开发者需求。
36 1
|
28天前
|
存储 Java 程序员
Java中的集合框架:从入门到精通
【8月更文挑战第30天】在Java的世界里,集合框架是一块基石,它不仅承载着数据的存储和操作,还体现了面向对象编程的精髓。本篇文章将带你遨游Java集合框架的海洋,从基础概念到高级应用,一步步揭示它的奥秘。你将学会如何选择合适的集合类型,掌握集合的遍历技巧,以及理解集合框架背后的设计哲学。让我们一起探索这个强大工具,解锁数据结构的新视角。
|
29天前
|
存储 算法 Java
Java中的集合框架深度解析云上守护:云计算与网络安全的协同进化
【8月更文挑战第29天】在Java的世界中,集合框架是数据结构的代言人。它不仅让数据存储变得优雅而高效,还为程序员提供了一套丰富的工具箱。本文将带你深入理解集合框架的设计哲学,探索其背后的原理,并分享一些实用的使用技巧。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇通往高效编程的大门。
|
27天前
|
存储 算法 Java
Java中的集合框架深度解析与实践
【8月更文挑战第31天】在Java编程的海洋中,集合框架扮演着不可或缺的角色。本文将带你领略Java集合框架的魅力,从理论到实践,深入浅出地探索List、Set和Map等核心接口的使用技巧。我们将通过具体代码示例,展示如何在日常开发中高效运用这些工具,让你的代码更加优雅和高效。无论你是初学者还是有经验的开发者,这篇文章都将为你打开一扇通往Java集合世界的大门。
|
29天前
|
jenkins Java Shell
jenkins学习笔记之十三:配置SonarScanner扫描Java项目
jenkins学习笔记之十三:配置SonarScanner扫描Java项目