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

在这里插入图片描述

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

文章目录

  • 🚀一、背景
  • 🚀二、准备工作
  • 🚀三、实现逻辑
    • 🔎3.1 查询用户的已发送通知数量
    • 🔎3.2 发送通知
    • 🔎3.3 获取用户通知列表
    • 🔎3.4 清理过期通知记录
    • 🔎3.5 定时任务
  • 🚀四、结语


🚀一、背景

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

在这里插入图片描述

🚀二、准备工作

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

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

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

$ pecl install redis

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

在这里插入图片描述

🚀三、实现逻辑

🔎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;
}

🔎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;
}

🔎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;
}

🔎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);
}

🔎3.5 定时任务

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

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

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

<?phprequire_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);
}

🚀四、结语

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

在这里插入图片描述

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/100909.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入解析Spring Boot中最常用注解的使用方式(上篇)

摘要&#xff1a;本文将详细介绍Spring Boot中最常用的注解的使用方式&#xff0c;并通过代码示例加以说明。通过学习这些注解&#xff0c;读者将能够更好地理解和运用Spring Boot框架&#xff0c;构建高效的企业级应用。 目录 第一部分&#xff1a;常见的控制器注解1.RequestM…

IDEA maven上传速度很慢、解决办法

maven上传的速度很慢&#xff0c;排除网络原因&#xff0c;需要检查配置 一、项目配置 以下针对于maven仓库不在C盘的情况&#xff1a; File | Settings | Build, Execution, Deployment | Build Tools | Maven 以IDEA为例&#xff0c;打开 File&#xff08;文件&#xff09;…

Json解析流程

一、拿到了题库 分析一下可以定义的 1、序号&#xff0c;用来区分题目数&#xff0c;每个题有唯一的序号 2、题目&#xff0c;就是下图的Q 3、预设的回答&#xff0c;下图的A 分析完我可以知道有三个字段&#xff0c;分别是int index、string Q、string A。 二、把字段丢到…

人工智能的优势:使用 GPT 和扩散模型生成图像

推荐&#xff1a;使用 NSDT场景编辑器快速搭建3D应用场景 世界被人工智能 &#xff08;AI&#xff09; 所吸引&#xff0c;尤其是自然语言处理 &#xff08;NLP&#xff09; 和生成 AI 的最新进展&#xff0c;这是有充分理由的。这些突破性技术有可能提高各种任务的日常生产力。…

工业4.0时代生产系统对接集成优势,MES和ERP专业一体化管理-亿发

在现代制造业中&#xff0c;市场变化都在不断加速。企业面临着不断加强生产效率、生产质量和快速适应市场需求的挑战。在制造行业&#xff0c;日常管理中的ERP系统、MES系统就显得尤为重要。越来越多的企业正在采用MES系统和ERP管理系统的融合&#xff0c;以实现智能化生产管理…

Windows系统管理一:操作系统概述

计算机系统的层次结构 五大基本功能 处理器管理 其工作主要是进程调度&#xff0c;在单用户单任务的情况下&#xff0c;必处理器仅为一个用户的一个任务所独占&#xff0c;进程管理的工作十分简单。但在多道程序或多用户的情况下&#xff0c;组织多个作业或任务时&#xff0c…

基于SSM的营业厅宽带系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

基于循环队列和信号量的生产和消费者模型

这一节为什么要基于信号量来实现同一个模型&#xff0c;原因&#xff1a; void push(const T& in){pthread_mutex_lock(&_lock);while(is_Full()){//这里说明阻塞队列是满的&#xff0c;需要让生产者等待pthread_cond_wait(&_pcond,&_lock);}//这里说明阻塞队列…

云备份——实用类工具实现

一&#xff0c;文件实用类设计实现 不管是客户端还是服务端&#xff0c;文件的传输备份都涉及到文件的读写&#xff0c;包括数据管理信息的持久化也是如此&#xff0c;因此首先设计封装文件操作类&#xff0c;这个类封装完毕之后&#xff0c;则在任意模块中对文件进行操作时都将…

[机器学习]分类算法系列①:初识概念

目录 1、概念 2、数据集介绍与划分 2.1、数据集的划分 2.2、sklearn数据集介绍 2.2.1、API 2.2.2、分类和回归数据集 分类数据集 回归数据集 返回类型 3、sklearn转换器和估计器 3.1、转换器 三种方法的区别 3.2、估计器 3.2.1、简介 3.2.2、API 3.3、工作流程 …

static关键字

static 是Java中的一个关键字&#xff0c;它可以用于修饰类的成员变量和方法&#xff0c;具有特殊的含义和用途。下面是关于static关键字的主要用法和含义&#xff1a; 静态变量&#xff08;Static Variables&#xff09;&#xff1a; 静态变量也称为类变量&#xff0c;它们属于…

ZDH-权限模块

本次介绍基于ZDH v5.1.2版本 目录 项目源码 预览地址 安装包下载地址 ZDH权限模块 ZDH权限模块-重要名词划分 ZDH权限模块-菜单管理 ZDH权限模块-角色管理 ZDH权限模块-用户配置 ZDH权限模块-权限申请 项目源码 zdh_web: GitHub - zhaoyachao/zdh_web: 大数据采集,抽…