본문 바로가기

Spring Boot

Bucket4j

개요

현대의 웹 서비스와 API는 대규모 트래픽을 처리해야 하며, 이러한 상황에서 안정성과 성능을 유지하는 것이 중요합니다. 특히, API를 사용할 때 과도한 요청이 서버에 들어오면 시스템 성능 저하 및 다운타임이 발생할 수 있습니다.

 

이를 방지하기 위해 API 속도 제한(rate limiting) 기법이 자주 사용됩니다.

 

이 글에서는 자바 기반의 API 속도 제한을 구현하는 데 유용한 라이브러리인 Bucket4j에 대해 다루고, 이를 사용하는 방법과 기본 설정 방법을 설명합니다.


 

API 속도 제한 하는 이유

앞서 설명한것과 더불어 다음과 같은 이유가 있습니다.

 

  • 서버 보호: 과도한 요청으로 인해 서버 자원이 고갈되거나, 서버가 다운되는 것을 방지할 수 있습니다.
  • 공정한 사용 보장: 모든 사용자에게 공정한 API 사용 기회를 제공하며, 특정 사용자가 서버 리소스를 독점하는 것을 막습니다.
  • 비용 관리: 클라우드 기반 서비스의 경우 트래픽에 따라 비용이 발생할 수 있으므로, 속도 제한을 통해 예기치 않은 비용 증가를 예방할 수 있습니다.
  • 보안: 악의적인 봇이나 DDoS 공격으로부터 시스템을 보호하는 데도 효과적입니다.

 


 

 

Bucket4j 라이브러리 소개

 

Bucket4j는 자바 기반의 API 속도 제한을 구현하는 오픈 소스 라이브러리입니다. 이 라이브러리는 버킷 알고리즘을 사용하여 효율적이고 유연한 속도 제한 기능을 제공합니다. 사용자는 특정 기간 동안 허용되는 요청 수를 정의하고, 그 범위를 초과하는 요청을 제한할 수 있습니다.

 

Bucket4j 특징

  • 유연성: 로컬 메모리에서 작동하거나 Redis와 같은 분산 캐시 시스템과 함께 사용가능
  • 손쉬운 통합: 자바 애플리케이션에 쉽게 통합할 수 있으며, 다양한 환경에서 사용 가능

등이 있습니다.

 

 


 

사용 알고리즘 

Bucket4j토큰 버킷(Token Bucket) 알고리즘을 사용합니다.

이 알고리즘은 일정 간격으로 버킷에 토큰을 추가하고, 요청이 들어올 때마다 버킷에서 토큰을 소비하는 방식으로 동작합니다. 요청을 처리하기 위해서는 버킷에 최소한 하나의 토큰이 있어야 하며, 그렇지 않으면 요청이 거부되거나 지연됩니다.

 


사용예시

의존성 추가

 

Gradle:

implementation 'com.github.vladimir-bukhtoyarov:bucket4j-core:7.0.0'

 

Maven:

<dependency>
    <groupId>com.github.vladimir-bukhtoyarov</groupId>
    <artifactId>bucket4j-core</artifactId>
    <version>7.0.0</version>
</dependency>

 

import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.Refill;

import java.time.Duration;

public class RateLimiterExample {
    public static void main(String[] args) {
        // 1분에 최대 100개의 요청 허용
        Bandwidth limit = Bandwidth.classic(100, Refill.greedy(100, Duration.ofMinutes(1)));
        Bucket bucket = Bucket.builder().addLimit(limit).build();

        for (int i = 0; i < 110; i++) {
            if (bucket.tryConsume(1)) {
                System.out.println("요청 처리됨: " + i);
            } else {
                System.out.println("요청 제한됨: " + i);
            }
        }
    }
}

 

 

주요 클래스 

Bucket 속도 제한을 적용하는 주체입니다. 요청이 들어올 때마다 토큰을 소비하며, 토큰이 없으면 요청을 제한합니다.
Bandwidth 버킷에 대한 제한 규칙을 정의합니다. 여기서 제한할 최대 요청 수와 리필 주기를 설정할 수 있습니다.
Refill 버킷에 토큰을 채우는 방식과 주기를 정의합니다.

주로 greedy(즉시 리필)와 intervally(간격 리필) 방식이 있습니다.