All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.dengchen2020.ratelimiter.local.LocalRateLimiter Maven / Gradle / Ivy

There is a newer version: 0.0.28
Show newest version
package io.github.dengchen2020.ratelimiter.local;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.Scheduler;
import io.github.dengchen2020.ratelimiter.RateLimiter;

import java.time.Duration;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 单机限流实现
 *
 * @author dengchen
 * @since 2024/4/18
 */
public class LocalRateLimiter implements RateLimiter {

    Cache cache;

    ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1, Thread.ofVirtual().name("rate-limiter").factory());

    /**
     * 限流实例化
     *
     * @param duration 多少时间内限制多少次
     */
    public LocalRateLimiter(Duration duration) {
        if (duration.getSeconds() < 1) duration = Duration.ofSeconds(1);
        cache = Caffeine.newBuilder()
                .scheduler(Scheduler.forScheduledExecutorService(scheduledExecutorService))
                .maximumSize(50000)
                .expireAfterWrite(duration.getSeconds(), TimeUnit.SECONDS)
                .build();
    }

    /**
     * 限流实例化
     * @param cache Cache实例{@link Cache}
     *
     */
    public LocalRateLimiter(Cache cache) {
        this.cache = cache;
    }

    /**
     * 是否被限制
     *
     * @param limitKey 限制标识符
     * @param limitNum 限制的次数
     * @return true:被限制 false:未被限制
     */
    @Override
    public boolean limit(String limitKey, int limitNum) {
        AtomicInteger time = cache.get(limitKey, key -> new AtomicInteger(1));
        return time.getAndIncrement() > limitNum;
    }

    /**
     * 撤销限制
     *
     * @param limitKey 限制标识符
     */
    @Override
    public void quashLimit(String limitKey) {
        AtomicInteger time = cache.getIfPresent(limitKey);
        if (time == null) return;
        time.decrementAndGet();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy