什么是限流?
- 限流类似于权限机制 , 它也决定是否接受当前请求,用于控制客户端在某段时间内允许向API发出请求的次数 , 也就是频率
- 假设有客户端(比如爬虫程序)短时间发起大量请求 , 超过了服务器能够处理的能力 , 将会影响其他用户的正常使用
- 为了保证服务的稳定性 , 并防止接口受到恶意用户的攻击 , 我们可以对接口进行限流
- 又或者可以对未经身份验证的请求设置访问频率 , 对经过身份验证的请求不限制访问频率
- 限流也不止单指限制访问次数的措施,例如付费数据服务的特点访问次数
- 区分用户场景,比如匿名和已登录 , 不同权限的用户不同的限流策略
- API的不同,根据不同API设置不同的策略
- 请求的爆发期和持续期不同的限流策略
- 可以同时支持使用多个限流策略
REST_FRAMEWORK = {# 全局限流类的配置'DEFAULT_THROTTLE_CLASSES': ('rest_framework.throttling.AnonRateThrottle',# 对于匿名用户的限流'rest_framework.throttling.UserRateThrottle' #对于登录用户的限流),# 限流频率的配置'DEFAULT_THROTTLE_RATES': {'anon': '100/day', # 未认证用户一天只许访问100次'user': '1000/day' # 认证用户一天可以访问1000次}}
DEFAULT_THROTTLE_RATES设置限流频率格式 次数/时间单位- second: 按秒设置频率次数
- minute:按分钟设置频率次数
- hour:按小时设置频率次数
- day: 按天设置频率次数
#导入限流模块from rest_framework import throttling class getInfoList(ModelViewSet):# 通过throttle_classes 设置该视图的限流类# 视图指定会覆盖settings设置的全局限流throttle_classes = (throttling.UserRateThrottle,)def infoList(self):...
识别请求的客户端我们既然要对请求进行限流 , 那么肯定要失识 别是谁发来的请求,然后进行对应的措施,不然无法确定请求者身份 , 那么就无法得知是不是需要限制的请求 , 常见的方法有三种- drf利用http报头的 x-forwarded-for 或者wsgi中的remote-addr变量来唯一标识客户端的IP地址
- 如果 存在x-forwarded-for 属性,则使用x-forwarded-for ,否则使用remote-addr
- 可以使用request.user的属性来标识请求 , 比如使用request.user.id 来标记唯一请求
- 使用IP地址对客户端请求进行限流,需要考虑使用伪造代理IP请求的情况
- BaseThrottle: 限流基类
- SimpleRateThrottle:频率校验类
- AnonRateThrottle:匿名用户限流
- UserRateThrottle:认证用户限流
- ScopedRateThrottle:api视图级别的限流
class BaseThrottle:# allow_request源码并没有直接实现功能 , 只是写好了方法占位 , 待后续继承实现# 该方法主要是处理是否允许请求通过# 如果后续继承基类实现该方法 , 允许请求通过返回True , 不允许请求通过返回Falsedef allow_request(self, request, view):raise NotImplementedError('.allow_request() must be overridden')# 获取IP地址def get_ident(self, request):# 获取请求头中真实IP地址xff = request.META.get('HTTP_X_FORWARDED_FOR')# 获取代理IP地址remote_addr = request.META.get('REMOTE_ADDR')# 获取设置的允许的最大代理数 , 默认不设置为Nonenum_proxies = api_settings.NUM_PROXIES# 如果num_proxies不是None , 说明设置了该值if num_proxies is not None:# 如果设置为0 , 或者 xff没有值if num_proxies == 0 or xff is None:# 返回代理IP地址return remote_addr#使用代理IP的话会有多个地址 , 使用逗号分割成一个listaddrs = xff.split(',')'''通过min函数 , 拿到允许的代理数和IP地址长度最小的值 , 使用-变成负数在addrs列表中通过该下标取对应值'''client_addr = addrs[-min(num_proxies, len(addrs))]return client_addr.strip()# 如果没有设置允许的代理数 并且xff有值则直接返回 , 否则返回remote_addrreturn ''.join(xff.split()) if xff else remote_addr# 等待时间,告诉客户端被限流 , 等待多久可以访问# 后续继承实现 , 可选def wait(self):return None
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 微服务组件--限流框架Spring Cloud Hystrix分析
- b站限流是什么意思
- 网上的限流是什么意思
- 电信限速不限量套餐 电信不限量套餐是无限流量吗?
- 头条被限流了怎么办?
- 一个手机2个抖音号会限流吗?
- 抖音连续点赞会被限流是什么意思?
- 抖音显示你的视频专属口令是被限流了吗?
- 快手为什么会被限流?
- 抖音连着点赞限流是什么意思?