惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threat Research - Cisco Blogs
博客园 - 聂微东
小众软件
小众软件
P
Proofpoint News Feed
Security Archives - TechRepublic
Security Archives - TechRepublic
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
TaoSecurity Blog
TaoSecurity Blog
博客园 - 司徒正美
罗磊的独立博客
N
News and Events Feed by Topic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security Affairs
S
Security @ Cisco Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
月光博客
月光博客
S
Secure Thoughts
P
Proofpoint News Feed
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Forbes - Security
Forbes - Security
H
Heimdal Security Blog
W
WeLiveSecurity
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
L
LangChain Blog
T
The Blog of Author Tim Ferriss
NISL@THU
NISL@THU
Google DeepMind News
Google DeepMind News
Cloudbric
Cloudbric
H
Hacker News: Front Page
The Last Watchdog
The Last Watchdog
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cisco Blogs
博客园 - 三生石上(FineUI控件)
博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Schneier on Security
Project Zero
Project Zero
SecWiki News
SecWiki News
爱范儿
爱范儿
The Register - Security
The Register - Security
AI
AI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Y
Y Combinator Blog
L
Lohrmann on Cybersecurity
Application and Cybersecurity Blog
Application and Cybersecurity Blog
P
Privacy International News Feed
J
Java Code Geeks
S
Securelist
C
Cyber Attacks, Cyber Crime and Cyber Security
V
Visual Studio Blog

咸糖 - 自律者自由

2025 年终总结:降噪、重构与长期主义 在新加坡和新山吃过最好的食物(持续更新) 写给还在迷茫的你:我的三本大学回忆 2024 年终总结 Neovim: No Crash Incremental Selection 2022 年终总结 使用 neovim 作为 PDE(个性化开发环境) shell 是一个不错的生产力工具 使用二八法则省力地学习 awk 肉身翻墙新加坡安顿指南 使用 Docker Compose 建立你自己的开发环境 关于编写可维护的代码的一些实践与想法 我为什么使用双向链接做笔记? 关于焦虑和拖延症 Golang: 如何处理日渐膨胀的 interface 使用番茄工作法来更好的利用你的时间 Unix 如何杀死一个进程和它的子孙进程? Golang: 让你的零值更有用 使用 Mock 和 Interface 进行 Golang 单测 关于 Golang Slice 的一些细节 总结一些计算机常用的原则 重新学习英语语法 上班族近期小半年入门投资基金组合的学习与实践经历 疫情期间的肉身翻墙新加坡指南 About me 软技能:大厂底层员工打工指南 软技能:我是如何获取知识与信息的? 分布式的令牌桶算法的实现 实现一个AtomicInteger GC root 在哪里? 什么是 Minor GC/Major GC 剑指offer 单例模式 TCP 针对面试学习 Actor 如何处理阻塞消息 Akka 源码解析 How to learn scala AES 需要限制 SEED 长度 Java 如何区分==与.equals()方法 2018年年度总结 Java 集合扩容
漏桶算法的设计与实现
xiantang · 2020-04-05 · via 咸糖 - 自律者自由

文章目录

【注意】最后更新于 April 5, 2020,文中内容可能已过时,请谨慎使用。

什么是漏斗算法?

漏斗算法顾名思义采用一个漏斗来对流量进行限制。

因为漏斗下面有孔,所以会定时的漏水下去,然后我们可以将流量想象为从上边落入漏斗的水。

这样就会有两种情况,如果流量的注入漏斗的速度比漏斗的漏水的速度慢,漏斗就会处于一个空漏斗的状态,也就是没有超出负荷的状态。

第二种情况就是,如果流量注入漏斗的速度比漏斗快,那么漏斗就会渐渐的超出最大的容量,对于溢出的流量,漏斗会采用拒绝的方式,防止流量继续进入。

image-20200405231856133

使用 Java 实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package info.xiantang.limiter;

class FunnelRateLimiter {

    // 容量
    private final int capacity;
    // 每毫秒漏水的速度
    private final double leakingRate;
    // 漏斗没有被占满的体积
    private int emptyCapacity;
    // 上次漏水的时间
    private long lastLeakingTime = System.currentTimeMillis();


    FunnelRateLimiter(int capacity, double leakingRate) {
        this.capacity = capacity;
        this.leakingRate = leakingRate;
        // 初始化为一个空的漏斗
        this.emptyCapacity = capacity;
    }

    private void makeSpace() {
        long currentTimeMillis = System.currentTimeMillis();
       // 计算离上次漏斗的时间
        long gap = currentTimeMillis - lastLeakingTime;
       // 计算离上次漏斗的时间到现在漏掉的水
        double deltaQuota = (int) gap * leakingRate;
        // 更新上次漏的水
        lastLeakingTime = currentTimeMillis;
        // 间隔时间太长,整数数字过大溢出 
       if (deltaQuota < 0) {
            emptyCapacity = capacity;
        }
        // 更新腾出的空间
        emptyCapacity += deltaQuota;
        // 超出最大限制 复原
        if (emptyCapacity > capacity) {
            emptyCapacity = capacity;
        }

    }

    boolean isActionAllowed(int quota) {
        makeSpace();
       // 如果腾出的空间大于需要的空间
        if (emptyCapacity >= quota) {
           // 给腾出空间注入流量
            emptyCapacity -= quota;
            return true;
        }
        return false;
    }
}

image-20200405232439711

我们这边定义了一个 empty capacity 的容量 表示腾出的空间。也可以通过以剩余的水来计算水占用的空间,这是两个角度来计算。但是我们使用的是empty capacity。

对于新来的流量,我们要判断是否Empty Capacity 能够容纳这些流量,如果能够容纳,就减少Empty Capacity的大小,不能的话就拒绝。

与令牌桶的区别

  • 令牌桶是定时放入令牌,漏桶是定时流数据

  • 朴素的令牌桶实现是对于溢出的请求计算出能够处理的时间进行阻塞,而漏桶则是会将溢出的流量拒绝。

文章作者 xiantang

上次更新 2020-04-05

赞赏支持

微信打赏 支付宝打赏