游乐游手机版
首页/AI教程/文章详情

Redis实战:限制操作频率的实现方法

时间:2026-06-12 15:45
基于Redis实现操作频率限制的通用方案,从评论、点赞、上传等场景抽象出限制对象、时间范围、操作次数及禁止时间参数,利用Redis过期与计数器设计统一函数,控制超限后的提示与禁止。

最近一直忙于业务开发一线工作,博客更新有所搁置。接下来的计划是逐步分享从真实业务场景中沉淀下来的实战方案与设计思路,例如本文即将探讨的频率限制通用实现。不再追求一次性覆盖整个主题的大而全,而是侧重于具体问题的深入剖析与精细挖掘。通过持续的分享与复盘,将经验系统沉淀,同时保持稳定的输出节奏。

场景

场景1

留言功能限制,30秒内只能评论10次,超出次数不让再评论,并提示:过于频繁

场景2

点赞功能限制,10秒内只能点赞10次,超出次数后不能再点赞,并禁止操作1个小时,提示:过于频繁,被禁止操作1小时

场景3

上传记录功能,限制一天只能上传100次,超出次数不让再上传,并提示:超出今日上限

抽离本质

长期从事业务开发会发现,许多场景虽然打着不同的业务模块标签,但本质上解决的是同一个问题。例如上述几个场景——评论、点赞、上传——看似毫不相干,底层逻辑却高度相似。如果只是机械地为每个场景单独编写代码,那就成了俗称的“CV(复制粘贴)工程师”。更有价值的做法是:挖掘问题的共性,设计一套通用解决方案。这或许就是有灵魂的工程师与纯工具人之间的本质区别。

对上面三个场景进行分析,可以绘制出如下逻辑流程图:

流程图

进一步提炼,它们都依赖于以下几个条件:

  • 限制对象:当前用户
  • 限制操作:评论、点赞、上传等具体动作
  • 时间范围:X秒内的允许窗口
  • 限制操作数:Y次上限
  • 超出后禁止操作时间:Z(秒或具体时间戳)
  • 超出后的响应:拒绝操作并给出提示信息

脑图

如果将该功能抽离为通用函数,大致形式如下:

1,'ttl'=>过期时间/秒] ['type'=>2,'ttl'=>具体过期时间戳] 二选一
 * @return bool
 * @throws Exception
 */
public static function frequencyLimit(string $action, int $userId, int $time, int $number, $expire = [])
{
    // todo 根据用户操作动作时间范围,进行频率的控制和失效释放
}

解决方案落地

功能核心需要记录用户每次操作的时间与累计次数,同时支持自动过期清理。如果依赖MySQL实现,频繁的读写操作和过期数据清理会带来较高的性能和维护成本。这时Redis成为理想方案——利用INCR的原子操作和Key的过期机制,结合内存存储的高效特性,Redis能简洁灵活地完成这项任务。

以下是通用功能的简易实现代码:

1,'ttl'=>过期时间/秒] ['type'=>2,'ttl'=>具体过期时间戳] 二选一
 * @return bool
 * @throws Exception
 */
public function frequencyLimit(string $action, int $userId, int $time, int $number, $expire = [])
{
    if (empty($action) || $userId <= 0 || $time <= 0 || $number <= 0) {
        throw new Exception('非法参数');
    }
    $key = 'act:limit:' . $action . ':' . $userId;
    $r = RedisClient::connect();
    // 获取当前累计次数
    $current = intval($r->get($key));
    if ($current >= $number) return false;
    // 累计并返回最新值
    $current = $r->incr($key);
    // 第一次累加,设置控制操作频率的有效时间
    if ($current === 1) $r->expire($key, $time);
    // 未超出限制次数先放过
    if ($current < $number) return true;
    // 超出后根据需要重新设置过期失效时间,$current === $number 判断保证只重新设置一次
    $type = empty($expire['type']) ? 0 : intval($expire['type']);
    $ttl = empty($expire['ttl']) ? 0 : intval($expire['ttl']);
    if ($current === $number && $ttl > 0 && in_array($type, [1, 2])) {
        if ($type === 1) $r->expire($key, $ttl);
        if ($type === 2) $r->expireAt($key, $ttl);
    }
    return false;
}

// 场景1:评论限制
public function doComment(int $userId)
{
    try {
        $pass = FrequencyLimit::doHandle('comment', $userId, 30, 10);
        if (!$pass) return '过于频繁';
        // todo 评论逻辑
        return true;
    } catch (Exception $e) {
        return $e->getMessage();
    }
}

// 场景2:点赞限制
public function doLike(int $userId)
{
    try {
        $pass = FrequencyLimit::doHandle('like', $userId, 10, 10, ['type' => 1, 'ttl' => 1 * 60 * 60]);
        if (!$pass) return '过于频繁,被禁止操作1小时';
        // todo 点赞逻辑
        return true;
    } catch (Exception $e) {
        return $e->getMessage();
    }
}

// 场景3:上传限制
public function doUpload(int $userId)
{
    try {
        $expire = strtotime(date('Y-m-d', strtotime('+1 days')));
        $pass = FrequencyLimit::doHandle('upload', $userId, 1 * 24 * 60 * 60, 100, ['type' => 2, 'ttl' => $expire]);
        if (!$pass) return '超出今日上限';
        // todo 上传逻辑
        return true;
    } catch (Exception $e) {
        return $e->getMessage();
    }
}
// 场景N……

总结

将相似的业务场景归集分析,识别本质问题并设计通用解决方案,远比每次重新造轮子更加高效。Redis的原子操作与过期机制在此场景中发挥了关键作用——INCR保证了并发安全,EXPIRE自动清理过期数据,代码简洁且性能出色。做一个有灵魂的开发者,从习惯抽象共性问题开始。

来源:https://developer.aliyun.com/article/704678
上一篇终端安全运营为何最终依赖数据边界持续执行 下一篇校车监控系统改造:JT/T808与1078协议融合实践
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
CapCut AI Docker 一键部署:镜像拉取、端口映射与数据目录配置教程
AI教程 · 2026-06-30

CapCut AI Docker 一键部署:镜像拉取、端口映射与数据目录配置教程

CapCutAI容器化部署需先确认镜像来源与授权范围,再完成环境准备、镜像拉取、端口映射、数据目录挂载和启动验证,适合本地试用、团队内网演示与轻量化AI剪辑服务管理。

CapCut AI Windows本地安装配置2026最新版含下载与环境要求
AI教程 · 2026-06-30

CapCut AI Windows本地安装配置2026最新版含下载与环境要求

CapCutAI与剪映AI在Windows端适合短视频、口播、课程和营销素材剪辑,安装前需确认系统、显卡、存储与网络条件,优先选择官方渠道下载,并完成账号、素材目录、硬件加速和导出参数配置。

Veo新手保姆级安装教程:从下载到首次运行
AI教程 · 2026-06-30

Veo新手保姆级安装教程:从下载到首次运行

Veo适合用文字生成短视频,新手应先确认官方入口、准备账号与设备环境,再按网页或应用方式完成启用。首次运行重点在提示词、参数、素材合规与结果保存,避免使用非官方安装包。

Veo本地模型运行下载路径设置与性能优化指南
AI教程 · 2026-06-30

Veo本地模型运行下载路径设置与性能优化指南

Veo本地模型部署需先确认模型来源与硬件条件,再完成下载校验、目录规划、路径配置和推理参数优化。重点关注显存占用、依赖版本、缓存位置、授权范围与常见报错处理。

Veo安装失败解决指南:常见报错与日志排查及升级回滚方案
AI教程 · 2026-06-30

Veo安装失败解决指南:常见报错与日志排查及升级回滚方案

Veo安装失败通常与系统环境、依赖版本、网络源、权限和缓存有关。排查时应先确认版本要求,再查看安装日志,按报错类型处理,并提前备份项目,确保升级与回滚可控。