mirror of
https://github.com/xfgryujk/blivechat.git
synced 2024-12-26 12:50:33 +08:00
限制请求开放平台的频率
This commit is contained in:
parent
65a9efa37e
commit
9c3538f17b
@ -16,6 +16,7 @@ import tornado.web
|
|||||||
import api.base
|
import api.base
|
||||||
import config
|
import config
|
||||||
import services.open_live
|
import services.open_live
|
||||||
|
import utils.rate_limit
|
||||||
import utils.request
|
import utils.request
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -32,6 +33,8 @@ END_GAME_COMMON_SERVER_URL = COMMON_SERVER_BASE_URL + '/api/internal/open_live/e
|
|||||||
GAME_HEARTBEAT_COMMON_SERVER_URL = COMMON_SERVER_BASE_URL + '/api/internal/open_live/game_heartbeat'
|
GAME_HEARTBEAT_COMMON_SERVER_URL = COMMON_SERVER_BASE_URL + '/api/internal/open_live/game_heartbeat'
|
||||||
|
|
||||||
_error_auth_code_cache = cachetools.LRUCache(256)
|
_error_auth_code_cache = cachetools.LRUCache(256)
|
||||||
|
# 用于限制请求开放平台的频率
|
||||||
|
_open_live_rate_limiter = utils.rate_limit.TokenBucket(5, 9)
|
||||||
|
|
||||||
|
|
||||||
class TransportError(Exception):
|
class TransportError(Exception):
|
||||||
@ -66,7 +69,7 @@ async def request_open_live_or_common_server(open_live_url, common_server_url, b
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
async def request_open_live(url, body: dict) -> dict:
|
async def request_open_live(url, body: dict, *, ignore_rate_limit=False) -> dict:
|
||||||
cfg = config.get_config()
|
cfg = config.get_config()
|
||||||
assert cfg.is_open_live_configured
|
assert cfg.is_open_live_configured
|
||||||
|
|
||||||
@ -77,6 +80,10 @@ async def request_open_live(url, body: dict) -> dict:
|
|||||||
else:
|
else:
|
||||||
auth_code = ''
|
auth_code = ''
|
||||||
|
|
||||||
|
# 频率限制,防止触发B站风控被下架
|
||||||
|
if not _open_live_rate_limiter.try_decrease_token() and not ignore_rate_limit:
|
||||||
|
raise BusinessError({'code': 4009, 'message': '接口访问限制', 'request_id': '0', 'data': None})
|
||||||
|
|
||||||
body_bytes = json.dumps(body).encode('utf-8')
|
body_bytes = json.dumps(body).encode('utf-8')
|
||||||
headers = {
|
headers = {
|
||||||
'x-bili-accesskeyid': cfg.open_live_access_key_id,
|
'x-bili-accesskeyid': cfg.open_live_access_key_id,
|
||||||
|
@ -73,7 +73,8 @@ async def _flush_game_heartbeat_tasks():
|
|||||||
try:
|
try:
|
||||||
res = await api.open_live.request_open_live(
|
res = await api.open_live.request_open_live(
|
||||||
api.open_live.GAME_BATCH_HEARTBEAT_OPEN_LIVE_URL,
|
api.open_live.GAME_BATCH_HEARTBEAT_OPEN_LIVE_URL,
|
||||||
{'game_ids': game_ids}
|
{'game_ids': game_ids},
|
||||||
|
ignore_rate_limit=True
|
||||||
)
|
)
|
||||||
failed_game_ids = res['data']['failed_game_ids']
|
failed_game_ids = res['data']['failed_game_ids']
|
||||||
if failed_game_ids is None: # 哪个SB后端给数组传null的
|
if failed_game_ids is None: # 哪个SB后端给数组传null的
|
||||||
|
32
utils/rate_limit.py
Normal file
32
utils/rate_limit.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class TokenBucket:
|
||||||
|
def __init__(self, tokens_per_sec, max_token_num):
|
||||||
|
self._tokens_per_sec = float(tokens_per_sec)
|
||||||
|
self._max_token_num = float(max_token_num)
|
||||||
|
self._stored_token_num = self._max_token_num
|
||||||
|
self._last_update_time = datetime.datetime.now()
|
||||||
|
|
||||||
|
if self._tokens_per_sec <= 0.0 and self._max_token_num >= 1.0:
|
||||||
|
logger.warning('TokenBucket token_per_sec=%f <= 0, rate has no limit', tokens_per_sec)
|
||||||
|
|
||||||
|
def try_decrease_token(self):
|
||||||
|
if self._tokens_per_sec <= 0.0:
|
||||||
|
# self._max_token_num < 1.0 时完全禁止
|
||||||
|
return self._max_token_num >= 1.0
|
||||||
|
|
||||||
|
cur_time = datetime.datetime.now()
|
||||||
|
last_update_time = min(self._last_update_time, cur_time) # 防止时钟回拨
|
||||||
|
add_token_num = (cur_time - last_update_time).total_seconds() * self._tokens_per_sec
|
||||||
|
self._stored_token_num = min(self._stored_token_num + add_token_num, self._max_token_num)
|
||||||
|
self._last_update_time = cur_time
|
||||||
|
|
||||||
|
if self._stored_token_num < 1.0:
|
||||||
|
return False
|
||||||
|
self._stored_token_num -= 1.0
|
||||||
|
return True
|
Loading…
Reference in New Issue
Block a user