django restframework 中使用throttle进行限流

一. 什么是限流
限流(Throttle)就是限制客户端对API 的调用频率,是API开发者必须要考虑的因素。比如个别客户端(比如爬虫程序)短时间发起大量请求,超过了服务器能够处理的能力,将会影响其它用户的正常使用。又或者某个接口占用数据库资源比较多,如果同一时间该接口被大量调用,服务器可能会陷入僵死状态。为了保证API服务的稳定性,并防止接口受到恶意用户的攻击,我们必须要对我们的API服务进行限流。

DRF中限制对API的调用频率非常简便,它为我们主要提供了3个可插拔使用的限流类,分别是AnonRateThrottle, UserRateThrottle和ScopeRateThrottle类。

  1. AnonRateThrottle 用于限制未认证用户的请求频率,主要根据用户的 IP地址来确定用户身份。
  2. UserRateThrottle 用于限定认证用户的请求频率,可对不同类型的用户实施不同的限流政策。
  3. ScopeRateThrottle可用于限制对 API 特定部分的访问。只有当正在访问的视图包含 throttle_scope 属性时才会应用此限制。这个与UserRateThrottle类的区别在于一个针对用户限流,一个针对API接口限流。
    DRF限制频率的指定格式为 “最大访问次数/时间间隔”,例如设置为 5/min,则只允许一分钟内最多调用接口 5 次。其它常用格式包括”10/s”, “100/d”等。超过限定次数的调用将抛出 exceptions.Throttled 异常,客户端收到 429 状态码(too many requests)的响应。

二. 设置自定义限流
定义throttle类

from rest_framework import throttling
from rest_framework.throttling import UserRateThrottle

class CustomScopeThrottle(throttling.ScopedRateThrottle):
    # scope = 'anon'
    rate = '1/second'
    # scope = 'll'
    # THROTTLE_RATES = {"anon": "1/s"}

class CustomUserRateThrottle(UserRateThrottle):
    rate= '1/second'

定义setting

REST_FRAMEWORK = {
    # 'DEFAULT_THROTTLE_CLASSES': [
    #     'testthrottle.throttling.GetUserRateThrottle'
    # ],
    'DEFAULT_THROTTLE_RATES': {
        'll': '1/second',
    }
}

三. 在API view中给特定接口添加限流

from rest_framework.viewsets import GenericViewSet
from rest_framework.decorators import throttle_classes
from rest_framework.response import Response
from rest_framework import status
from testthrottle.models import EllisTest
from testthrottle.serilizerModel.ellisTest import EllisTestSerilizer
from testthrottle.throttling import CustomScopeThrottle,CustomUserRateThrottle


class EllisTestView(GenericViewSet):
    serializer_class = EllisTestSerilizer
    queryset = EllisTest.objects.all()
    throttle_scope = "ll"
    # throttle_classes = [CustomUserRateThrottle]
    # 通过这个函数实现给不同的API 添加不同的限流
    def get_throttles(self):
        if self.action == 'create':
            throttle_classes = [CustomUserRateThrottle]
        else:
            # throttle_classes = []  # No throttle for other actions
            throttle_classes = [CustomScopeThrottle]  # No throttle for other actions
        return [throttle() for throttle in throttle_classes]

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    # @throttle_classes([CustomUserRateThrottle])
    def create(self, request):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)




https://www.django-rest-framework.org/api-guide/throttling/

https://pythondjango.cn/django/rest-framework/10-throttling/

https://stackoverflow.com/questions/69068513/how-to-apply-throttling-just-to-create-action-in-drf-viewsets

https://stackoverflow.com/questions/32932357/custom-throttling-response-in-django-rest-framework

https://medium.com/analytics-vidhya/throttling-requests-with-django-rest-framework-for-different-http-methods-3ab0461044c

demo源码

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值