基于PostgreSQL 14.5实现API限流:单用户每分钟仅可操作一次
PostgreSQL实现单用户每分钟API限流方案
针对你需求的单用户每分钟仅可执行一次目标操作的限流规则,结合PostgreSQL 14.5的特性,推荐使用原子UPSERT操作实现,避免并发竞态条件,同时保证性能满足每秒2次的总请求量。
1. 创建限流记录表
首先创建用于存储用户操作时间的表,主键确保每个用户+操作类型的唯一性:
CREATE TABLE api_rate_limit ( user_id TEXT NOT NULL, operation_type TEXT NOT NULL, -- 若仅有一种目标操作,可省略或设为固定常量 last_executed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), PRIMARY KEY (user_id, operation_type) );
2. 原子限流判断与更新
使用PostgreSQL的INSERT ... ON CONFLICT(UPSERT)语法,在单个SQL语句中完成存在性检查、时间判断、更新/插入的原子操作,彻底避免并发场景下的绕过问题:
WITH upsert AS ( INSERT INTO api_rate_limit (user_id, operation_type, last_executed_at) VALUES ('目标用户ID', '目标操作标识', NOW()) ON CONFLICT (user_id, operation_type) DO UPDATE SET last_executed_at = NOW() WHERE EXTRACT(EPOCH FROM (NOW() - api_rate_limit.last_executed_at)) >= 60 RETURNING 1 AS allowed ) SELECT COALESCE((SELECT allowed FROM upsert), 0) AS allowed;
逻辑说明:
- 若该用户+操作无历史记录:直接插入新记录,返回
1(允许执行操作) - 若已有历史记录:检查距离上次执行是否超过60秒,是则更新时间并返回
1,否则不执行更新,返回0(拒绝请求)
3. 旧数据清理(可选)
为避免表中积累大量长期无操作的用户记录,可添加定时任务(如每天执行)清理过期数据:
DELETE FROM api_rate_limit WHERE last_executed_at < NOW() - INTERVAL '7 days';
性能说明
你的总请求量约每秒2次,该方案的单SQL操作属于轻量级事务,PostgreSQL 14.5完全可以轻松承载,无需额外性能优化。
内容的提问来源于stack exchange,提问作者aosho235
相关产品推荐
相关产品推荐

