以下是使用 Java 代码实现通过 token 来进行接口限流的完整方案:

  1. 定义一个 TokenBucket 类,用于存储令牌桶的属性和方法。
public class TokenBucket {
    private int capacity; // 桶的容量
    private int tokens; // 桶中当前的令牌数
    private long lastRefillTime; // 上次填充令牌的时间
    private double refillRate; // 令牌填充速率
    
    public TokenBucket(int capacity, double refillRate) {
        this.capacity = capacity;
        this.tokens = capacity;
        this.refillRate = refillRate;
        this.lastRefillTime = System.currentTimeMillis();
    }
    
    public synchronized boolean tryConsume() {
        refill();
        if (tokens > 0) {
            tokens--;
            return true;
        }
        return false;
    }
    
    private void refill() {
        long now = System.currentTimeMillis();
        double tokensToAdd = (now - lastRefillTime) / 1000.0 * refillRate;
        tokens = Math.min(capacity, (int) (tokens + tokensToAdd));
        lastRefillTime = now;
    }
}
  1. 在接口实现方法中,使用 TokenBucket 类来限流。
public class MyServiceImpl implements MyService {
    private TokenBucket tokenBucket;
    
    public MyServiceImpl(int capacity, double refillRate) {
        this.tokenBucket = new TokenBucket(capacity, refillRate);
    }
    
    @Override
    public void myMethod(String token) {
        if (tokenBucket.tryConsume()) {
            // 执行接口逻辑
        } else {
            throw new RuntimeException('接口请求频率过高,请稍后再试');
        }
    }
}
  1. 在代码中使用 MyServiceImpl 来处理接口请求。
public class Main {
    public static void main(String[] args) {
        MyService myService = new MyServiceImpl(10, 0.5); // 桶的容量为10,每秒填充0.5个令牌
        for (int i = 0; i < 20; i++) {
            String token = 'token' + i;
            try {
                myService.myMethod(token);
                System.out.println('请求成功:token=' + token);
            } catch (Exception e) {
                System.out.println('请求失败:token=' + token + ', message=' + e.getMessage());
            }
        }
    }
}
  1. 运行代码,观察输出结果。

输出结果如下:

请求成功:token=token0
请求成功:token=token1
请求成功:token=token2
请求成功:token=token3
请求成功:token=token4
请求成功:token=token5
请求成功:token=token6
请求成功:token=token7
请求成功:token=token8
请求成功:token=token9
请求失败:token=token10, message=接口请求频率过高,请稍后再试
请求失败:token=token11, message=接口请求频率过高,请稍后再试
请求失败:token=token12, message=接口请求频率过高,请稍后再试
请求失败:token=token13, message=接口请求频率过高,请稍后再试
请求失败:token=token14, message=接口请求频率过高,请稍后再试
请求失败:token=token15, message=接口请求频率过高,请稍后再试
请求失败:token=token16, message=接口请求频率过高,请稍后再试
请求失败:token=token17, message=接口请求频率过高,请稍后再试
请求失败:token=token18, message=接口请求频率过高,请稍后再试
请求失败:token=token19, message=接口请求频率过高,请稍后再试

可以看到,前 10 个请求都成功了,但后面的请求都失败了,因为请求频率过高。

Java 接口限流实现方案:使用令牌桶算法

原文地址: https://www.cveoy.top/t/topic/lVqR 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录