java实现 限流算法 漏斗模型

本文详细探讨了如何使用Java实现漏斗模型进行流量限制。通过该算法,可以有效地控制系统的并发请求,保障服务稳定性和性能。文中将阐述漏斗模型的工作原理,并提供具体的Java代码示例,帮助读者理解并应用该限流策略。
package com.example.redis.漏斗限流;

/**
 * @Auther: liuyujie
 * @Date: 2019/3/4 12:48
 * @Description:
 */
public class Funnel {
    int capacity;//漏斗容量
    double leakingRate;//漏水速度
    int leftQuota;//漏斗剩余的量
    long leakingTs;//上次漏斗漏水的 时间

    public Funnel(int capacity, double leakingRate, int leftQuota, long leakingTs) {
        this.capacity = capacity;
        this.leakingRate = leakingRate;
        this.leftQuota = leftQuota;
        this.leakingTs = leakingTs;
    }


    private void makeSpace(){
        long nowTs = System.currentTimeMillis();
        long deltaTs = nowTs - this.leakingTs;//这个是间隔的时间
        int deltaQuota = (int)(deltaTs*leakingRate);//漏掉的水
        if (deltaQuota<0){//间隔时间太长,溢出
            this.leftQuota=capacity;
            this.leakingTs = nowTs;
            return;
        }
        if (deltaQuota<1){//说明漏的时间不够
            return;
        }
        this.leakingTs = nowTs;
        this.leftQuota = this.leftQ
### Java 中的限流算法 #### 令牌桶算法Java开发过程中,经常使用的限流算法之一是令牌桶算法。该算法通过设定一个固定速率向桶中添加令牌,请求只有消耗掉一个令牌才能被处理。如果桶为空,则拒绝新的请求或者让其等待直到有可用的令牌[^1]。 ```java public class TokenBucketLimiter implements Limiter { private final int capacity; // 桶容量 private final double refillRate; // 补充频率(每秒) private long lastRefillTimestamp; private int tokens; public TokenBucketLimiter(int capacity, double refillRate) { this.capacity = capacity; this.refillRate = refillRate; this.tokens = capacity; this.lastRefillTimestamp = System.currentTimeMillis(); } @Override public synchronized boolean tryAcquire() { refillTokens(); if (tokens >= 1) { --tokens; return true; } return false; } private void refillTokens() { long now = System.currentTimeMillis(); double newTokens = ((now - lastRefillTimestamp) / 1000.0) * refillRate; lastRefillTimestamp = now; tokens = Math.min(capacity, (int)(tokens + newTokens)); } } ``` #### 漏斗桶算法 另一种常见的限流出策略为漏斗桶算法。此方法模拟了一个具有恒定排水速度的水桶模型;当接收到新流入的数据包时会立即加入到桶里去,只要不超过最大存储量即可正常工作。一旦超出界限则丢弃多余部分而不影响现有流程继续运行。 ```java public class LeakyBucketLimiter implements Limiter { private static final int BUCKET_CAPACITY = 100; // 容器大小 private static final int DRAIN_RATE = 10; // 排放率(单位/ms) private volatile int currentLevel = 0; // 当前水平面高度 private Timer timer = new Timer(true); public LeakyBucketLimiter(){ startDrainingProcess(); } @Override public synchronized boolean tryAcquire() { if(currentLevel < BUCKET_CAPACITY){ ++currentLevel; return true; }else{ return false; } } private void startDrainingProcess(){ timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { drainWater(DRAIN_RATE); } }, 0 , 1); // 每隔一毫秒执行一次排放操作 } private void drainWater(int amount){ if(amount <= getCurrentLevel()){ setCurrentLevel(getCurrentLevel()-amount); } } protected int getCurrentLevel(){return currentLevel;} protected void setCurrentLevel(int level){this.currentLevel=level;} } ``` 这两种算法实现了`Limiter`接口中的`tryAcquire()`方法用于尝试获取访问权限[^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值