• Redis限流实践:实现用户消息推送每天最多通知2次的功能


    在这里插入图片描述

    🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。
    🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人
    🏆本文已收录于PHP专栏:PHP进阶实战教程
    🏆另有专栏PHP入门基础教程,希望各位大佬多多支持❤️。
    🎉欢迎 👍点赞✍评论⭐收藏


    🚀一、背景

    在开发应用程序中,经常需要向用户推送消息通知,但是为了避免过多的打扰用户,我们希望限制每天最多通知2次。本篇博文将介绍如何使用 PHP 和 Redis 实现这一功能。

    在这里插入图片描述

    🚀二、准备工作

    首先,我们需要准备好数据库和 Redis 服务。在 MySQL 数据库中创建一个 user_notifications 表, 包含以下字段:

    • id:主键自增长ID
    • user_id:用户ID
    • content:通知内容
    • created_at:记录创建时间

    此外,还需要安装 Redis 扩展,在 PHP 中可以通过以下命令安装:

    $ pecl install redis
    
    • 1

    常见的推送消息场景如下图。

    在这里插入图片描述

    🚀三、实现逻辑

    🔎3.1 查询用户的已发送通知数量

    在用户登录或接收新通知时,我们需要查询用户今天已发送的通知数量。我们可以利用 Redis 的 Sorted Set 数据结构来存储每个用户的通知记录。将用户ID作为 Sorted Set 的 key,通知的发送时间戳作为 score 值,这样就可以按照时间顺序存储用户的通知记录。

    使用以下代码实现查询用户已发送通知数量的函数:

    function getNotificationCount($userId) {
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
    
        $todayStart = strtotime('today'); // 当天开始的时间戳
        $todayEnd = strtotime('tomorrow') - 1; // 当天结束的时间戳
    
        $count = $redis->zcount('user_notifications:' . $userId, $todayStart, $todayEnd);
    
        return $count;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    🔎3.2 发送通知

    在发送通知之前,先检查用户已发送通知数量是否达到限制。如果已发送通知数量大于等于2,则不再发送新通知;否则,保存通知记录到数据库,并将通知记录的发送时间戳添加到 Redis Sorted Set 中。

    使用以下代码实现发送通知的函数:

    function sendNotification($userId, $content) {
        // 检查用户已发送通知数量
        $count = getNotificationCount($userId);
        if ($count >= 2) {
            return false;
        }
    
        // 保存通知记录到数据库
        $pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
        $stmt = $pdo->prepare("INSERT INTO user_notifications (user_id, content, created_at) VALUES (?, ?, NOW())");
        $stmt->execute([$userId, $content]);
    
        // 将通知记录的发送时间戳添加到 Redis Sorted Set
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        $redis->zadd('user_notifications:' . $userId, time(), $content);
    
        return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    🔎3.3 获取用户通知列表

    用户可以通过接口或页面查看自己的通知列表。我们可以从数据库中查询用户的通知记录,并按照发送时间倒序排列。

    使用以下代码实现获取用户通知列表的函数:

    function getNotificationList($userId) {
        $pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
        $stmt = $pdo->prepare("SELECT * FROM user_notifications WHERE user_id = ? ORDER BY created_at DESC");
        $stmt->execute([$userId]);
    
        $notifications = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
        return $notifications;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    🔎3.4 清理过期通知记录

    为了避免 Redis Sorted Set 中存储的用户通知记录过多,我们可以定时清理过期的通知记录。通过设置 Redis 的过期时间来实现自动清理。例如,我们可以设置 Sorted Set 的过期时间为2天,在用户查询通知列表时,先删除过期的通知记录,再返回有效的通知列表。

    function cleanExpiredNotifications($userId) {
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
    
        // 设置 Sorted Set 的过期时间为2天
        $expireTime = strtotime('2 days ago');
        $redis->expireAt('user_notifications:' . $userId, $expireTime);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    🔎3.5 定时任务

    为了每天凌晨清理用户的通知记录,我们可以使用 Linux 的 crontab 来定时执行清理任务。编辑 crontab 文件,添加如下代码:

    0 0 * * * php /path/to/clean_expired_notifications.php
    
    • 1

    并创建 clean_expired_notifications.php 文件,内容如下:

    
    
    require_once 'redis.php';
    
    $pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
    $stmt = $pdo->prepare("SELECT DISTINCT user_id FROM user_notifications");
    $stmt->execute();
    
    $userIds = $stmt->fetchAll(PDO::FETCH_COLUMN);
    
    foreach ($userIds as $userId) {
        cleanExpiredNotifications($userId);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    🚀四、结语

    通过 PHP 和 Redis 实现用户消息推送每天最多通知2次的功能,并结合定时任务清理过期通知记录,可以有效地避免过多地打扰用户。以上是基本实现逻辑和代码示例,你可以根据自己的实际需求进行修改和扩展,例如根据不同用户设置不同的通知限制次数等。

    在这里插入图片描述

    推荐您阅读本专栏其他内容,PHP进阶实战教程,相信不会让您失望。如果你对上面的功能有疑问,随时欢迎与我交流。

  • 相关阅读:
    Python的web自动化学习(一)Selenium库的工作原理
    K8s安装部署-----二进制安装部署
    使用sqlmap的 ua注入
    102.网络游戏逆向分析与漏洞攻防-ui界面的设计-反隐身功能的界面设计与实现(有不使用MFC生成,自己手写代码创建复选框与事件的例子)
    c 语言 log
    【嵌入式开发 Linux 常用命令系列 8 --代码格式修改工具 astyle】
    网络分析笔记10:解析RTP协议
    mysql锁机制
    Python Opencv实践 - 霍夫圆检测(Hough Circles)
    力扣刷题 day49:10-19
  • 原文地址:https://blog.csdn.net/qq_21891743/article/details/132537612