カウンタ実装ストリーム制限-Java実装

1023 ワード

実装時には、カウントに使用される変数は、自己増加動作が原子動作であるべきであることに注意しなければならない.
import java.util.concurrent.atomic.AtomicLong;

public class RateLimiter {

    private final static AtomicLong ZERO = new AtomicLong(0);
    private AtomicLong counter = ZERO;
    private static long timestamp = System.currentTimeMillis();
    private long permitsPerSecond;

    public RateLimiter(long permitsPerSecond) {
        this.permitsPerSecond = permitsPerSecond;
    }

    public boolean tryAcquire() {
        long now = System.currentTimeMillis();
        if (now - timestamp < 1000) {
            if (counter.get() < permitsPerSecond) {
                counter.incrementAndGet();
                return true;
            } else {
                return false;
            }
        } else {
            counter = ZERO;
            timestamp = now;
            return false;
        }
    }

}

カウンタでストリーム制限を行い、簡単に分散シーンに拡張しやすく、カウント値をredisで保存し、自動期限を設定します.欠点は、カウンタセット0前後の極短時間で、2*permitsPerSecondのバースト流量がある可能性があることです.