Django REST 使用 Redis 进行节流

问题描述 投票:0回答:2

我注意到在多个线程中,我们需要使用更好的缓存,例如“Redis”,而不是 Django 的默认“LocMemCache”,尤其是在生产中。

我有多个设置文件,包括

base.py
master.py

我已在

base.py
中添加了我的 Redis 缓存,如以下代码片段所示:

CACHES = {
    "alternate": {
        "BACKEND": "redis_cache.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "DB": 1,
            "CLIENT_CLASS": "redis_cache.client.DefaultClient",
        }
    }
}

我故意将其交替使用,因为我不想更改应用程序中的缓存。

不在我的自定义油门中,我有以下实现:

from rest_framework.throttling import UserRateThrottle
from myproject.settings.base import CACHES

class CustomThrottle(UserRateThrottle):
    scope = 'custom_throttle'
    cache = CACHES['alternate']

节流率存在于同一个

base.py
文件中

但是,当我向该端点运行请求时,遇到以下错误。

line 26, in throttle_success
    self.cache.set(self.key, self.history, self.duration)
AttributeError: 'dict' object has no attribute 'set'

我知道在这种情况下我必须覆盖throttle_success,但我不确定到底要改变什么。 帮助?! 谢谢。

django caching django-rest-framework redis throttling
2个回答
4
投票

您的配置有问题,您的设置也应该有默认缓存。

CACHES = {
    "alternate": {
        "BACKEND": "redis_cache.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "DB": 1,
            "CLIENT_CLASS": "redis_cache.client.DefaultClient",
        }
    },
    "default": {
        "BACKEND": "redis_cache.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "DB": 2,
            "CLIENT_CLASS": "redis_cache.client.DefaultClient",
        }
    }
}

一旦定义了这样的设置,您应该使用缓存对象而不是 CACHE 设置来更新 CustomThrottle。

from django.core.cache import caches
class CustomThrottle(UserRateThrottle):
    scope = 'custom_throttle'
    cache = caches['alternate']

0
投票

我正在尝试实现一个解决方案,其中 Django 的

LocMemCache
用作默认缓存,Redis 作为备用缓存来处理速率限制会话。但是,当我尝试在
throttles.py
中打印缓存对象时,我注意到所有缓存条目都存储在默认缓存 (
LocMemCache
) 中,并且没有任何条目存储在备用缓存 (
Redis
) 中。

这导致速率限制功能无法按预期运行,因为未使用备用缓存 (Redis)。

设置.py

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'
    },
    "alternate": {
        "BACKEND": "django_redis.cache.RedisCache",
        'LOCATION': 'redis://127.0.0.1:6379',
        "OPTIONS": {
            "DB": 1,
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
}

节流阀.py

class GetProductThrottle(UserRateThrottle):
    scope = 'list_products'
    cache = caches['alternate']

    def get_cache_key(self, request, view):
        # Create a session for anonymous users
        if not request.session.session_key:
            request.session.create()  # This forces the session to be created
        return f'throttle_{self.scope}_{request.session.session_key}'

    def allow_request(self, request, view):
        if request.method == 'GET':
            cache_key = self.get_cache_key(request, view)

            num_requests = self.cache.get(cache_key, 0)
            print(f"Current number of requests: {num_requests}")

            return super().allow_request(request, view)
        return True

    def wait(self):
        return super().wait()
© www.soinside.com 2019 - 2024. All rights reserved.