APIのレート制限の実装方法

APIゲートウェイにおいて、特定のエンドポイントに対するアクセス頻度を制御する仕組みを構築する。各APIごとに1分間の最大リクエスト数(例:1000回)を設定し、上限を超えた場合はエラーレスポンスを返す。次の1分では再び正常な処理が可能となる。

public class RateLimit {
    private long resetTime;
    private int requestCount;

    public long getResetTime() {
        return resetTime;
    }

    public void setResetTime(long resetTime) {
        this.resetTime = resetTime;
    }

    public int getRequestCount() {
        return requestCount;
    }

    public void setRequestCount(int requestCount) {
        this.requestCount = requestCount;
    }

    public boolean checkAndIncrement() {
        long currentTime = System.currentTimeMillis() / 1000;
        if (currentTime < resetTime) {
            if (requestCount < 10) { // テスト用に値を調整
                requestCount++;
                System.out.println("成功");
                return true;
            } else {
                System.out.println("制限 exceeded");
                return false;
            }
        } else {
            resetTime = currentTime + 1;
            requestCount = 1;
            System.out.println("リセット完了");
            return true;
        }
    }
}
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ApiGateway {
    private final ConcurrentHashMap rateLimitMap = new ConcurrentHashMap<>();

    public boolean handleRequest(String endpoint) {
        if (endpoint == null || endpoint.isEmpty()) {
            return false;
        }

        RateLimit limit = rateLimitMap.computeIfAbsent(endpoint, k -> {
            RateLimit newLimit = new RateLimit();
            newLimit.setResetTime(System.currentTimeMillis() / 1000 + 1);
            newLimit.setRequestCount(1);
            return newLimit;
        });

        return limit.checkAndIncrement();
    }

    public static Runnable createTestTask(String endpoint) {
        return () -> {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                ApiGateway gateway = new ApiGateway();
                System.out.println(gateway.handleRequest(endpoint));
            }
        };
    }

    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10; i++) {
            executor.submit(createTestTask("test-endpoint"));
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        executor.shutdown();
    }
}

タグ: Java ratelimiting ConcurrencyControl

9月8日 11:16 投稿