이 문서는 Google Cloud Translation API를 사용해 자동 번역되었습니다.
어떤 문서는 원문을 읽는게 나을 수도 있습니다.
Redis는 일반적으로 캐시, 메시지 브로커 및 데이터베이스로 사용되는 메모리 내 데이터 구조 저장소입니다. 그러나 Redis는 웹 애플리케이션을 남용으로부터 보호하기 위해 속도 제한에도 사용할 수 있습니다. 이 기사에서는 속도 제한에 Redis를 사용하는 방법과 이를 웹 애플리케이션과 통합하는 방법을 살펴봅니다.
속도 제한은 웹 응용 프로그램에 대한 요청 속도를 제어하는 데 사용되는 기술입니다. 남용을 방지하고 서비스 거부(DoS) 공격으로부터 애플리케이션을 보호하는 데 사용됩니다. 속도 제한은 다음과 같은 여러 가지 방법으로 구현할 수 있습니다.
Redis는 각 끝점, 사용자 또는 IP 주소에 대한 카운터를 저장하여 속도 제한에 사용할 수 있습니다. 웹 애플리케이션에 대한 요청이 있으면 해당 카운터가 증가합니다. 카운터가 한도를 초과하면 요청이 거부되거나 지연됩니다.
Redis는 문자열, 해시, 세트 및 정렬된 세트를 포함하여 속도 제한에 사용할 수 있는 여러 데이터 구조를 제공합니다.
속도 제한에 Redis를 사용하는 간단한 방법은 문자열을 사용하여 카운터를 저장하는 것입니다. 다음은 문자열을 사용하여 속도 제한을 구현하는 방법의 예입니다.
import redis
redis_client = redis.Redis(host='localhost', port=6379, db=0)
def rate_limit(endpoint, limit, interval):
key = f'ratelimit:{endpoint}'
count = redis_client.incr(key)
redis_client.expire(key, interval)
return count <= limit
이 예에서는 endpoint
, limit
및 interval
의 세 가지 매개변수를 사용하는 rate_limit
함수를 정의합니다. endpoint
매개변수는 속도가 제한되는 엔드포인트의 이름입니다. limit
매개변수는 interval
기간 내에 허용되는 최대 요청 수입니다.
Redis incr
명령을 사용하여 끝점에 대한 카운터를 증가시킵니다. 그런 다음 expire
명령을 사용하여 키의 만료 시간을 interval
기간으로 설정합니다. 마지막으로 카운트가 limit
보다 작거나 같으면 True
를 반환하고 그렇지 않으면 False
를 반환합니다.
경우에 따라 속도가 제한된 요청에 대한 추가 정보를 저장해야 할 수 있습니다. 예를 들어 마지막 요청의 타임스탬프 또는 요청과 관련된 사용자 ID를 저장하고자 할 수 있습니다. 이러한 경우 해시를 사용하여 카운터 및 추가 정보를 저장할 수 있습니다.
다음은 해시를 사용하여 속도 제한을 구현하는 방법의 예입니다.
import redis
import time
redis_client = redis.Redis(host='localhost', port=6379, db=0)
def rate_limit(endpoint, limit, interval, user_id=None):
key = f'ratelimit:{endpoint}'
if user_id:
key = f'{key}:{user_id}'
now = time.time()
p = redis_client.pipeline()
p.hincrby(key, 'count', 1)
p.hsetnx(key, 'timestamp', now)
p.expire(key, interval)
count, timestamp = p.execute()
if count > limit:
return False
if now - float(timestamp) < interval:
return True
redis_client.hset(key, 'timestamp', now)
return True
이 예에서는 endpoint
, limit
, interval
및 user_id
의 네 가지 매개변수를 사용하는 rate_limit
함수를 정의합니다. user_id
매개변수는 선택사항이며 다른 사용자의 요청을 구분하는 데 사용됩니다.
Redis pipeline
명령을 사용하여 단일 요청으로 Redis에 여러 명령을 보냅니다. hincrby
명령을 사용하여 해시의 count
필드를 1씩 증가시킵니다. hsetnx
명령을 사용하여 해시의 timestamp
필드가 존재하지 않는 경우 현재 시간으로 설정합니다. 그런 다음 'expire' 명령을 사용하여 키의 만료 시간을 'interval' 기간으로 설정합니다.
count
가 limit
를 초과하는지 확인합니다. 그렇다면 'False'를 반환합니다. 또한 마지막 요청 이후 시간이 간격
보다 짧은지 확인합니다. 그렇다면 카운터를 증가시키지 않고 'True'를 반환합니다. 그렇지 않으면 해시의 timestamp
필드를 현재 시간으로 업데이트하고 True
를 반환합니다.
IP 기반 속도 제한은 DoS 공격을 방지하는 데 사용되는 일반적인 기술입니다. 이 경우 특정 기간 내에 각 IP 주소에서 요청하는 횟수를 제한하려고 합니다. Redis 세트를 사용하여 요청의 IP 주소와 타임스탬프를 저장할 수 있습니다.
다음은 집합을 사용하여 IP 기반 속도 제한을 구현하는 방법의 예입니다.
import redis
import time
redis_client = redis.Redis(host='localhost', port=6379, db=0)
def rate_limit(endpoint, limit, interval, ip_address):
key = f'ratelimit:{endpoint}'
now = time.time()
p = redis_client.pipeline()
p.zadd(key, {ip_address: now})
p.zremrangebyscore(key, 0, now - interval)
p.expire(key, interval)
count = p.zcard(key)
if count > limit:
return False
return True
이 예에서는 endpoint
, limit
, interval
및 ip_address
의 네 가지 매개변수를 사용하는 rate_limit
함수를 정의합니다. Redis 세트를 사용하여 요청의 IP 주소와 타임스탬프를 저장합니다.
Redis zadd
명령을 사용하여 IP 주소와 현재 타임스탬프를 세트에 추가합니다. zremrangebyscore
명령을 사용하여 interval
기간보다 오래된 항목을 제거합니다. expire
명령을 사용하여 키의 만료 시간을 interval
기간으로 설정합니다.
세트의 항목 수가 '제한'을 초과하는지 확인합니다. 그렇다면 'False'를 반환합니다. 그렇지 않으면 'True'를 반환합니다.
토큰 기반 속도 제한은 특정 기간 내에 각 사용자 계정이 생성한 요청 수를 제한하는 데 사용되는 일반적인 기술입니다. Redis 정렬 세트를 사용하여 사용자 ID와 요청의 타임스탬프를 저장할 수 있습니다.
다음은 정렬된 세트를 사용하여 토큰 기반 속도 제한을 구현하는 방법의 예입니다.
import redis
import time
redis_client = redis.Redis(host='localhost', port=6379, db=0)
def rate_limit(endpoint, limit, interval, user_id):
key = f'ratelimit:{endpoint}'
now = time.time()
p = redis_client.pipeline()
p.zadd(key, {user_id: now})
p.zremrangebyscore(key, 0, now - interval)
p.expire(key, interval)
count = p.zcard(key)
if count > limit:
return False
return True
이 예에서는 endpoint
, limit
, interval
및 user_id
의 네 가지 매개변수를 사용하는 rate_limit
함수를 정의합니다. Redis 정렬 집합을 사용하여 사용자 ID와 요청의 타임스탬프를 저장합니다.
Redis zad
명령을 사용하여 사용자 ID와 현재 타임스탬프를 정렬된 집합에 추가합니다. zremrangebyscore
명령을 사용하여 interval
기간보다 오래된 항목을 제거합니다. expire
명령을 사용하여 키의 만료 시간을 interval
기간으로 설정합니다.
정렬된 집합의 항목 수가 '제한'을 초과하는지 확인합니다. 그렇다면 'False'를 반환합니다. 그렇지 않으면 'True'를 반환합니다.
Redis를 웹 애플리케이션과 통합하려면 요청을 가로채서 속도 제한을 초과하는지 확인해야 합니다. 미들웨어나 데코레이터를 사용하여 이를 수행할 수 있습니다.
미들웨어는 웹 애플리케이션에서 요청과 응답을 가로채는 데 사용되는 기술입니다. Python에서는 django.middleware
모듈을 사용하여 미들웨어를 구현할 수 있습니다.
다음은 Django에서 미들웨어를 사용하여 속도 제한을 구현하는 방법의 예입니다.
import redis
from django.conf import settings
from django.http import HttpResponseForbidden
redis_client = redis.Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=0)
class RateLimitMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
endpoint = request.path
limit = settings.RATE_LIMIT
interval = settings.RATE_LIMIT_INTERVAL
ip_address = request.META['REMOTE_ADDR']
if not rate_limit(endpoint, limit, interval, ip_address):
return HttpResponseForbidden('Rate limit exceeded')
response = self.get_response(request)
return response
이 예에서는 미들웨어를 구현하는 RateLimitMiddleware
클래스를 정의합니다. 우리는 settings
모듈을 사용하여 Django 설정에서 Redis 호스트, 포트, 속도 제한 및 간격을 가져옵니다.
우리는 request.path
속성을 사용하여 액세스되는 엔드포인트를 얻습니다. settings.RATE_LIMIT
및 settings.RATE_LIMIT_INTERVAL
설정을 사용하여 속도 제한과 간격을 각각 가져옵니다. request.META['REMOTE_ADDR']
속성을 사용하여 클라이언트의 IP 주소를 가져옵니다.
요청이 속도 제한을 초과하는지 확인하기 위해 rate_limit
함수를 호출합니다. 그렇다면 HTTP 403 Forbidden 응답을 반환합니다. 그렇지 않으면 get_response
메서드를 호출하여 요청을 처리합니다.
미들웨어를 사용하려면 settings.py
의 MIDDLEWARE
설정에 추가합니다.
MIDDLEWARE = [
# ...
'path.to.RateLimitMiddleware',
# ...
]
데코레이터는 함수나 클래스의 동작을 수정하는 데 사용되는 기술입니다. Python에서는 데코레이터를 사용하여 웹 애플리케이션에서 속도 제한을 구현할 수 있습니다.
다음은 데코레이터를 사용하여 속도 제한을 구현하는 방법의 예입니다.
import redis
from django.conf import settings
from django.http import HttpResponseForbidden
redis_client = redis.Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=0)
def rate_limit_decorator(endpoint):
def decorator(view_func):
def wrapper(request, *args, **kwargs):
limit = settings.RATE_LIMIT
interval = settings.RATE_LIMIT_INTERVAL
ip_address = request.META['REMOTE_ADDR']
if not rate_limit(endpoint, limit, interval, ip_address):
return HttpResponseForbidden('Rate limit exceeded')
return view_func(request, *args, **kwargs)
return wrapper
return decorator
이 예에서는 endpoint
매개변수를 사용하고 데코레이터 함수를 반환하는 rate_limit_decorator
함수를 정의합니다. 데코레이터 함수는 view_func
매개변수를 사용하고 래퍼 함수를 반환합니다.
우리는 settings
모듈을 사용하여 Django 설정에서 Redis 호스트, 포트, 속도 제한 및 간격을 가져옵니다.
요청이 속도 제한을 초과하는지 확인하기 위해 rate_limit
함수를 호출하는 wrapper
함수를 정의합니다. 그렇다면 HTTP 403 Forbidden 응답을 반환합니다. 그렇지 않으면 view_func
함수를 호출하여 요청을 처리합니다.
데코레이터를 사용하려면 뷰 함수나 클래스에 적용합니다.
@rate_limit_decorator('/my-endpoint/')
def my_view(request):
# ...
Redis는 남용 및 DoS 공격으로부터 웹 애플리케이션을 보호하기 위해 속도 제한에 사용할 수 있습니다. Redis는 문자열, 해시, 세트 및 정렬된 세트를 포함하여 속도 제한에 사용할 수 있는 여러 데이터 구조를 제공합니다.
미들웨어 또는 데코레이터를 사용하여 Redis를 웹 애플리케이션과 통합할 수 있습니다. 미들웨어는 웹 애플리케이션에서 요청과 응답을 가로채는 데 사용되는 기술인 반면 데코레이터는 함수 또는 클래스의 동작을 수정하는 데 사용되는 기술입니다.
Redis로 속도 제한을 구현함으로써 웹 애플리케이션의 안정성과 보안을 보장할 수 있습니다.