속도 제한
번역일: 2026년 6월 20일
속도 제한
소개
Laravel은 간단하게 사용할 수 있는 속도 제한(Rate Limiting) 추상화를 제공합니다. 애플리케이션의 캐시와 함께 사용하면, 특정 시간 범위 내에서 임의의 동작을 손쉽게 제한할 수 있습니다.
NOTE
HTTP 요청 자체에 속도 제한을 적용하고 싶다면, 라우트 속도 제한 미들웨어 문서를 참고하세요.
캐시 설정
속도 제한기는 기본적으로 cache 설정 파일의 default 키에 지정된 캐시 드라이버를 사용합니다. 속도 제한기가 사용할 캐시 드라이버를 별도로 지정하고 싶다면, cache 설정 파일에 limiter 키를 추가하면 됩니다. 예를 들어 Redis를 사용하려면 다음과 같이 설정합니다:
'default' => env('CACHE_STORE', 'database'),
'limiter' => 'redis',기본 사용법
속도 제한기와 상호작용할 때는 Illuminate\Support\Facades\RateLimiter 파사드를 사용합니다. 가장 간단한 방법은 attempt 메서드로, 지정한 콜백을 일정 시간 동안 제한된 횟수만 실행할 수 있도록 합니다.
attempt 메서드는 허용된 시도 횟수를 모두 소진한 경우 false를 반환하고, 그렇지 않으면 콜백의 반환값 또는 true를 반환합니다. 첫 번째 인수는 속도 제한기의 "키"로, 제한할 동작을 나타내는 임의의 문자열을 사용하면 됩니다:
use Illuminate\Support\Facades\RateLimiter;
$executed = RateLimiter::attempt(
'send-message:'.$user->id,
$perMinute = 5,
function() {
// 메시지 전송...
}
);
if (! $executed) {
return '메시지를 너무 많이 전송했습니다!';
}필요하다면 네 번째 인수로 "감소율(decay rate)"을 지정할 수 있습니다. 이 값은 시도 횟수가 초기화될 때까지 걸리는 시간(초)입니다. 예를 들어 2분마다 최대 5회 시도를 허용하려면 다음과 같이 작성합니다:
$executed = RateLimiter::attempt(
'send-message:'.$user->id,
$perTwoMinutes = 5,
function() {
// 메시지 전송...
},
$decayRate = 120,
);시도 횟수 직접 증가시키기
속도 제한기를 보다 세밀하게 제어하고 싶다면 다양한 메서드를 직접 활용할 수 있습니다.
tooManyAttempts 메서드를 사용하면 특정 키의 시도 횟수가 허용된 최대치를 초과했는지 확인할 수 있습니다:
use Illuminate\Support\Facades\RateLimiter;
if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
return '시도 횟수를 초과했습니다!';
}
RateLimiter::increment('send-message:'.$user->id);
// 메시지 전송...또는 remaining 메서드로 특정 키의 남은 시도 횟수를 확인하고, 남은 횟수가 있을 때만 increment 메서드로 횟수를 증가시킬 수도 있습니다:
use Illuminate\Support\Facades\RateLimiter;
if (RateLimiter::remaining('send-message:'.$user->id, $perMinute = 5)) {
RateLimiter::increment('send-message:'.$user->id);
// 메시지 전송...
}한 번에 1 이상의 값으로 시도 횟수를 증가시키려면, increment 메서드에 원하는 값을 전달하면 됩니다:
RateLimiter::increment('send-message:'.$user->id, amount: 5);다음 시도까지 남은 시간 확인
특정 키의 시도 횟수가 모두 소진된 경우, availableIn 메서드를 사용해 다음 시도가 가능해지기까지 남은 시간(초)을 확인할 수 있습니다:
use Illuminate\Support\Facades\RateLimiter;
if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
$seconds = RateLimiter::availableIn('send-message:'.$user->id);
return $seconds.'초 후에 다시 시도해 주세요.';
}
RateLimiter::increment('send-message:'.$user->id);
// 메시지 전송...시도 횟수 초기화
clear 메서드를 사용하면 특정 키의 시도 횟수를 즉시 초기화할 수 있습니다. 예를 들어, 수신자가 메시지를 읽었을 때 발신자의 시도 횟수를 초기화하는 상황을 생각해 볼 수 있습니다:
use App\Models\Message;
use Illuminate\Support\Facades\RateLimiter;
/**
* 메시지를 읽음으로 표시합니다.
*/
public function read(Message $message): Message
{
$message->markAsRead();
RateLimiter::clear('send-message:'.$message->user_id);
return $message;
}