DRF内蔵限流ユニットのカスタム限流機構
5955 ワード
DRFは周波数セットThrottlingを内蔵しています.
サーバの圧力を軽減するために、インターフェースへのアクセス頻度を制限することができます.
一般的には有料購入回数、投票などの場面で使われます.
オプションの制限レベル
1)は、すべての匿名未認証ユーザを制限し、IPを使用してユーザを区別する. は、 を設定する.
2)は認証ユーザを制限し、User idを用いて区別する. は、 を設定する.
グローバル設定
全体構成は、構成ファイルにおいて
具体的なビューにおいて、
settings.pyプロファイルには以下のように構成されています.
フロー制限コンポーネントは周波数コンポーネントとも呼ばれ、クライアントを制御するためにAPIの要求周波数、例えば1分間に3回アクセスし、1分間に3回以上の場合はクライアントを制限する.
現在APIへのアクセスが30 s以内で3回を超えてはいけないとしたら、どうやって実現すればいいですか?
カスタムストリーム制限コンポーネント
rest frame ewarkフレームでは、クラスのリストとして定義されています.グローバル構成またはローカル構成だけが必要です.上記のフロー制限の原理は、クライアントの一意の表示をキーとして、アクセスの瞬間に形成されるリストを値として形成した辞書であり、辞書を介して動作する.
上記ではグローバル変数を使って記録することもできます.もちろんキャッシュを使って記録することもできます.djangoのキャッシュAPI、from django.com re.cache import cacheを使用して、このAPIを導入したらsetとget方法を使用して、cacheに格納されているオブジェクトを設定して取得して、グローバル変数を操作して置換するだけでいいです.
上記のwait方法では、このAPIにどれぐらいの時間がかかりますか?
サーバの圧力を軽減するために、インターフェースへのアクセス頻度を制限することができます.
一般的には有料購入回数、投票などの場面で使われます.
オプションの制限レベル
1)
AnonRateThrottle
DEFAULT_THROTTLE_RATES['anon']
を使用して、周波数帯域2)
UserRateThrottle
DEFAULT_THROTTLE_RATES['user']
を使用して、周波数帯域グローバル設定
全体構成は、構成ファイルにおいて
DEFAULT_THROTTLE_CLASSES
およびDEFAULT_THROTTLE_RATES
を使用して行うことができる.REST_FRAMEWORK = {
#
'DEFAULT_THROTTLE_CLASSES': (
# , IP
'rest_framework.throttling.AnonRateThrottle',
# , User_id
'rest_framework.throttling.UserRateThrottle'
),
#
'DEFAULT_THROTTLE_RATES': {
# 3
'anon': '3/m',
# 10
'user': '10/m'
}
}
DEFAULT_THROTTLE_RATES
は、second
、minute
、hour
、またはday
を使用して周期を指定しても良い. :
{'s': 1, 'm': 60, 'h': 3600, 'd': 86400} m , m, minute
ローカル設定具体的なビューにおいて、
throttle_classess
属性によって構成されてもよい.from rest_framework.views import APIView
from rest_framework.throttling import AnonRateThrottle
from rest_framework.throttling import UserRateThrottle
class ExampleView1(APIView):
# 3
# 10
throttle_classes = (AnonRateThrottle, UserRateThrottle)
...
# settings.py
REST_FRAMEWORK = {
#
'DEFAULT_THROTTLE_RATES': {
# 3
'anon': '3/m',
# 10
'user': '10/m'
}
}
ScopedRateThrottle
DRFはまた、異なるインターフェースに対して異なるアクセス頻度をカスタマイズすることができる制限ストリームレベルを提供する.settings.pyプロファイルには以下のように構成されています.
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.ScopedRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
# :throttle_scope = 'contacts', 10
'contacts': '10/m',
# :throttle_scope = 'uploads', 5
'uploads': '5/m'
...
...
...
}
}
たとえば:from rest_framework.views import APIView
class ContactListView(APIView):
# 10
throttle_scope = 'contacts'
...
class ContactDetailView(APIView):
# 10
throttle_scope = 'contacts'
...
class UploadView(APIView):
# 5
throttle_scope = 'uploads'
...
カスタムストリームフロー制限コンポーネントは周波数コンポーネントとも呼ばれ、クライアントを制御するためにAPIの要求周波数、例えば1分間に3回アクセスし、1分間に3回以上の場合はクライアントを制限する.
現在APIへのアクセスが30 s以内で3回を超えてはいけないとしたら、どうやって実現すればいいですか?
カスタムストリーム制限コンポーネント
VISIT_RECORD = {} # ,
class VisitThrottle(object):
def __init__(self): # await
self.history = None
def allow_request(self,request,view):
# ip
remote_addr = request.META.get('REMOTE_ADDR')
#
ctime = time.time()
# , , True,
if remote_addr not in VISIT_RECORD:
VISIT_RECORD[remote_addr] = [ctime,]
return True
# ,
history = VISIT_RECORD.get(remote_addr)
self.history = history
# , 60s , ,
#
while history and history[-1] < ctime - 30:
history.pop()
# ,
if len(history) < 3:
history.insert(0,ctime)
return True
def wait(self):
#
ctime = time.time()
return 60 - (ctime - self.history[-1])
対応するビューで設定します.class BookView(ListAPIView):
throttle_classes = [VisitThrottle,] #
queryset = models.Book.objects.all()
serializer_class = BookModelSerializer
限流の原理rest frame ewarkフレームでは、クラスのリストとして定義されています.グローバル構成またはローカル構成だけが必要です.上記のフロー制限の原理は、クライアントの一意の表示をキーとして、アクセスの瞬間に形成されるリストを値として形成した辞書であり、辞書を介して動作する.
{
http://127.0.0.1:8020/ :[11:43:30,11:42:22,11:42:20,11:42:09]
}
上の辞書に示すように、後の訪問時間はリストの一番左に挿入され、現在の訪問時間は11:43:30である.最初の訪問時間と11:42:09と差をつけて、規定時間30 sと比較し、30秒以内でない場合は一番左の記録を除去し、同じようにwhileを使って順番に比較します.最後に決められた時間範囲での記録:{
http://127.0.0.1:8020/ :[11:43:30,]
}
訪問回数を再計算します.つまりリストの数です.明らかにリストの数が3より小さい場合はアクセスを続けてもいいです.そうでなければいけません.上記ではグローバル変数を使って記録することもできます.もちろんキャッシュを使って記録することもできます.djangoのキャッシュAPI、from django.com re.cache import cacheを使用して、このAPIを導入したらsetとget方法を使用して、cacheに格納されているオブジェクトを設定して取得して、グローバル変数を操作して置換するだけでいいです.
from django.core.cache import cache as default_cache
import time
class VisitThrottle(object):
cache = default_cache
def allow_request(self,request,view):
...
...
# , , True,
if not self.cache.get(remote_addr):
self.cache.set(remote_addr,[ctime,])
return True
# ,
history = self.cache.get(remote_addr)
self.history = history
...
...
rest frame ewarkの限流コンポーネントはcacheに基づいて完成した. 上記のwait方法では、このAPIにどれぐらいの時間がかかりますか?
{
"detail": "Request was throttled. Expected available in 56 seconds."
}