【限流算法】

news/2024/9/19 14:09:45 标签: 算法, java, 开发语言

文章目录

介绍

令牌桶算法是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。

算法原理

在这里插入图片描述
令牌桶算法基于以下核心概念:
令牌桶:一个虚拟的容器,用来存放固定数量的令牌。
令牌填充速率:系统以固定的速率向桶中添加令牌。
令牌消耗:每当一个数据包发送时,就从桶中移除一个k如果桶中没有令牌,数据包将被延迟发送或丢弃,直到桶中有足够的令牌。

适用场景

网络带宽管理:控制用户的网络流量,防止滥用。
API速率限制:限制API调用频率,保护后端服务。
云服务提供商:为不同级别的用户提供不同速率的服务。
任务调度:限制任务执行的速率,避免资源争用。

令牌通算法实现

java">package com.schdule.util;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class TokenBucket {
    /**
     * 桶的最大容量
     */
    private  int  capacity;
    /**
     * 当前桶的令牌数
     */
    private  AtomicInteger tokens;
    /**
     * 令牌通的生成速率
     */
    private  int refillRate;
    /**
     * 上次填充令牌的时间
     */
    private  long lastRefillTimestamp;

    public TokenBucket(int capacity, int refillRate) {
        this.capacity = capacity;
        this.tokens = new AtomicInteger(capacity);
        this.refillRate = refillRate;
        this.lastRefillTimestamp = System.nanoTime();
    }

    public synchronized boolean tryConsuse(){
        refill();
        if(tokens.get()>0){
            tokens.decrementAndGet();
            return true;
        }
        return false;
    }

    /**
     * 填充令牌,根据时间间隔计算应该添加多少令牌
     */
    public void refill(){
        long now=System.nanoTime();
        long timeSinceLastRefill = now - lastRefillTimestamp;
        long tokensToAdd = timeSinceLastRefill * refillRate / TimeUnit.SECONDS.toNanos(1);
        if(tokensToAdd>0){
            int newTokenCount=Math.min(capacity,tokens.get()+(int)tokensToAdd);
            tokens.set(newTokenCount);
            lastRefillTimestamp=now;
        }
    }
    public static void main(String[] args) throws InterruptedException {
        // 创建一个容量为10,速率为每秒2个令牌的令牌桶
        TokenBucket tokenBucket = new TokenBucket(10, 2);

        // 模拟多个请求,每隔500毫秒尝试一次
        for (int i = 0; i < 20; i++) {
            boolean allowed = tokenBucket.tryConsuse();
            System.out.println("Request " + (i + 1) + (allowed ? " allowed" : " denied"));
            Thread.sleep(500);
        }
    }

}

限流算法

1‌.计数器算法‌是最简单也是最容易实现的限流算法。它通过维护一个计数器,每当有请求到达时,计数器加一,如果计数器的值超过了预设的阈值,则拒绝新的请求。这种算法实现简单,但容易受到突发流量的影响,因为请求可能会在同一时间窗口内集中到达,导致计数器迅速达到上限。

2‌.滑动窗口算法‌是对计数器算法的改进,通过将时间划分为多个小窗口,每个小窗口内限制请求的数量。与计数器算法相比,滑动窗口算法能够更好地处理突发流量,因为它允许在每个小窗口内有一定的请求量,而不会因为一个时间点的请求过多而导致整个时间窗口的请求被拒绝。

‌3.令牌桶算法‌通过控制令牌的生成速度来限制请求的处理速度。所有请求在处理前都需要获取一个可用的令牌。令牌以一定的速率生成,当桶满时,新生成的令牌会被丢弃或拒绝。这种算法能够有效地限制请求的处理速率,即使面对突发流量也能保持一定的服务能力。

‌4.漏桶算法‌可以看作是一个具有固定容量的请求队列,请求以一定的速率流入和流出。当请求流入的速度超过流出速度时,多余的请求会被丢弃。漏桶算法能够平滑地处理请求,防止突发流量对系统造成过大压力。


http://www.niftyadmin.cn/n/5665668.html

相关文章

人工智能 | 基于ChatGPT开发人工智能服务平台

简介 ChatGPT 在刚问世的时候&#xff0c;其产品形态就是一个问答机器人。而基于ChatGPT的能力还可以对其做一些二次开发和拓展。比如模拟面试功能、或者智能机器人功能。 模拟面试功能包括个性化问题生成、实时反馈、多轮面试模拟、面试报告。 智能机器人功能提供24/7客服支…

828华为云征文|华为云Flexus X实例docker部署Rocket.Chat构建属于自己的团队通讯协作平台

828华为云征文&#xff5c;华为云Flexus X实例docker部署Rocket.Chat构建属于自己的团队通讯协作平台 华为云最近正在举办828 B2B企业节&#xff0c;Flexus X实例的促销力度非常大&#xff0c;特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Nginx等服务…

如何切换淘宝最新镜像源(npm)【2024版】

在使用 Node.js 和 npm 进行开发时&#xff0c;大家通常会遇到 npm 源速度较慢的问题。特别是当你需要安装大量依赖时&#xff0c;npm 官方源的速度可能不尽如人意。幸运的是&#xff0c;淘宝提供了一个更快速的 npm 镜像源&#xff0c;可以让你更快地下载和安装包。本文将介绍…

Spring考点总结

01.Spring框架的基本理解 关键字:核心思想IOC\AOP\作用(解耦、简化)&#xff0c;简单描述框架组成 Spring框架是一款轻量级的开发框架&#xff0c;核心思想是IOC&#xff08;控制反转&#xff09;和AOP&#xff08;面向切面编程&#xff09;&#xff0c; 为Java应用程序开发…

【Delphi】知道控件名称(字符串),访问控件

在 Delphi 中&#xff0c;可以使用 RTTI&#xff08;运行时类型信息&#xff09; 或其他方法通过对象的名称字符串来访问对象。比如&#xff0c;如果你有一个控件的名称字符串&#xff0c;你希望通过该名称找到并访问实际的控件。 以下是通过 RTTI 以及其他技术&#xff08;如…

网络编程的应用

目录 1.单机程序和网络程序 2.客户端与服务端 3.网络编程三要素 3.1 IP地址 3.2 port端口 4.TCP编程 5.UDP编程 1.单机程序和网络程序 之前编写的程序都是单机程序&#xff0c;所有的业务功能实现及数据存储都在一个主机上完成&#xff0c;我们称为单机程序 我们在生活…

【Vue】- 路由及传参

文章目录 知识回顾前言源码分析1. 声明式导航2. 路由传参3. 可选符4. 重定向5. 4046. 跳转及传参7. 路由懒加载拓展知识总结router-link静态传参和动态路由的对比知识回顾 前言 什么是单页面应用程序? ● 所有功能在一个html页面上实现 单页面应用优缺点? ● 优点:按需更新…

普罗米修斯监控

概念 prometheus是开源的系统监控和告警。在k8s分布式的容器化管理系统当中&#xff0c;一般都是搭配prometheus来进行监控。它是服务监控系统&#xff0c;也可以监控主机&#xff0c;它自带时序数据库&#xff0c;这个时序数据库提供了数据模型和采集的指标项、存储、查询接口…