현재 시장에서 작동시 기계의 종류는 매우 다양하다. 저기 서버에 대한 요청의 매일 수백만 거의 대역폭과 컴퓨팅 자원을 소모합니다. 당신은 서버의 안정성을 보장하기 위해 특정 전략의 요청의 일부를 필터링 할 수 있습니다.
추가 읽기 :
1. 물론,이 계층은 논리적으로 액세스 레이어 떨어질 수 있으며, 비즈니스 계층도 떨어질 수 있습니다. 여기에, 다른 온라인 서비스에 영향을 미치는 시스템 안정성 및 추적 코드를 확인하지 주문. 또한 내가 비즈니스 계층에서 왼쪽, 최소한의 검증의 구현을 용이하게합니다.
2. 예를 들어 여러 알고리즘의 흐름 제한 : 카운터, 토큰 버킷, 버킷. 카운터는 상대적으로 간단하고, 사용된다.
카운터 알고리즘은 특정 기간 내에, 액세스 요청의 수는 증가합니다. 상한을 초과하는 모든 요청을 버리십시오.
1. 먼저 루아 스크립트 (ratelimit.lua)를 생성
local key = KEYS[1] local limit = tonumber(ARGV[1]) local expire_time = ARGV[2] local current = tonumber(redis.call('get', key) or "0") if current > 0 then if current + 1 > limit then return 0 else redis.call("INCR", key) return 1 end else redis.call("SET", key, 1) redis.call("EXPIRE", key, expire_time) return 1 end
요약 루아 스크립트를 확보합니다
redis-cli script load "$(cat ratelimit.lua)"
"123456789b24c879d926f3a38cb21a3fd9062e55"
장식을 정의합니다
# 异步限流策略 2个/10秒
# key_str: 部门:项目:路由:ID 例: a:b:Test:ratelimit:1234
# 装饰器这里的参数都是根据Lua定义的参数来配置的
# sha1: 就是redis-cli script load "$(cat ratelimit.lua)"的返回值
# 1: 表示key的个数 # limit: 限制次数 # expire: key过期时间 def async_ratelimit(key_str, limit=2, expire=10, sha1="123456789b24c879d926f3a38cb21a3fd9062e55"): def decorator(func): async def wrap(*args, **kw): self = args[0] key = key_str % (self.__class__.__name__, func.__name__, self.get_argument('id')) raw = redis.evalsha(sha1, 1, key, limit, expire) if raw == 0: return self.send_json(errcode=10001, errmsg='接口请求频率过高') else: await func(*args, **kw) return wrap return decorator
예
@async_ratelimit('a:b:%s:%s:%s') async def ratelimit(self, method): try: mac_id = self.get_argument('id') except Exception as e: logging.error(e) return self.send_json(errcode=10001) return self.send_json()