Python如何实现字典单key对应多值及命令调用阈值限制功能
Python实现IP命令调用限流功能
实现思路
采用Python内置的defaultdict实现嵌套字典结构,无需手动判断key是否存在,天然满足「命令不存在则初始化、存在则不重复插入」的要求。限流逻辑可根据精度要求选择固定窗口或滑动窗口方案,两种方案性能均达到O(1)级,完全满足日常使用需求。
方案1:固定窗口限流(高性能首选)
适合对限流精度要求不高的场景,实现最简单、性能最优:
from collections import defaultdict import time # 可自定义配置 MAX_CALLS = 3 # 单IP单命令时间窗口内最大调用次数 WINDOW_SECONDS = 3600 # 时间窗口长度,单位:秒,此处为1小时 # 初始化嵌套结构:外层key=命令名,内层key=IP,值为[窗口起始时间戳, 当前窗口调用次数] cmd_counter = defaultdict(lambda: defaultdict(lambda: [0.0, 0])) def check_call_permission(cmd: str, remote_ip: str) -> bool: now = time.time() window_start, call_count = cmd_counter[cmd][remote_ip] # 超出时间窗口则重置计数 if now - window_start > WINDOW_SECONDS: cmd_counter[cmd][remote_ip] = [now, 1] return True # 窗口内未超阈值则允许调用 if call_count < MAX_CALLS: cmd_counter[cmd][remote_ip][1] += 1 return True # 超出阈值禁止调用 return False
使用示例
# 测试同一IP调用stats命令 print(check_call_permission("stats", "192.168.1.2")) # 第1次 → True print(check_call_permission("stats", "192.168.1.2")) # 第2次 → True print(check_call_permission("stats", "192.168.1.2")) # 第3次 → True print(check_call_permission("stats", "192.168.1.2")) # 第4次 → False # 测试不同命令 print(check_call_permission("Add", "192.168.1.2")) # Add命令第1次 → True
方案2:滑动窗口限流(高精度首选)
适合需要严格控制1小时内最多调用3次的场景,避免固定窗口边界处短时间调用量超出阈值的问题:
from collections import defaultdict import time MAX_CALLS = 3 WINDOW_SECONDS = 3600 # 初始化嵌套结构:外层key=命令名,内层key=IP,值为最近N次调用的时间戳列表 cmd_call_records = defaultdict(lambda: defaultdict(list)) def check_call_permission(cmd: str, remote_ip: str) -> bool: now = time.time() records = cmd_call_records[cmd][remote_ip] # 清理所有超出时间窗口的历史记录 while records and now - records[0] > WINDOW_SECONDS: records.pop(0) # 剩余记录数小于阈值则允许调用 if len(records) < MAX_CALLS: records.append(now) return True return False
内容的提问来源于stack exchange,提问作者Zahid
相关产品推荐
相关产品推荐

