PHP7 学习笔记(十四)Reids 键空间通知配合TP5 实现分布式延时任务
测试环境:windows 10 + phpStudy
配置redis配置文件 redis.windows.conf
1 | notify-keyspace-events "Ex" |
重启redis服务
重新打开一个控制台窗口,执行命令
1 | psubscribe __keyevent@0__:expired |
打开新窗口执行了阻塞订阅操作后的终端,等会会有信息输出:
1 2 3 4 5 6 | C:\Users\admin>redis-cli 127.0.0.1:6379> psubscribe __keyevent@0__:expired Reading messages... (press Ctrl-C to quit) 1) "psubscribe" 2) "__keyevent@0__:expired" 3) (integer) 1 |
再开启一个终端,redis-cli 进入 redis,新增一个 6秒过期的键 username:
命令行完成了
二、借助TP5.1 的命令行工具
命令行工具的使用:https://www.kancloud.cn/manual/thinkphp5_1/354146
1、新建命令行pay
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <?php /**.------------------------------------------------------------------------------------------------------------------- * | Github: https://github.com/Tinywan * '------------------------------------------------------------------------------------------------------------------*/ namespace app\common\command; use app\pay\service\RedisSubscribe; use think\console\Command; use think\console\Input; use think\console\input\Argument; use think\console\Output; class Pay extends Command { // 配置指令 public function configure() { $this ->setName( 'pay' ) ->addArgument( 'type' , Argument::REQUIRED, "the type of the task that pay needs to run" ) ->setDescription( 'this is payment system command line tools' ); } // 执行指令 public function execute(Input $input , Output $output ) { $type = $input ->getArgument( 'type' ); if ( $type == 'psubscribe' ) { // 发布订阅任务 $this ->psubscribe(); } } /** * Redis 发布订阅模式 */ private function psubscribe() { $service = new RedisSubscribe(); $service ->sub(); } } |
2、编写脚本 RedisSubscribe.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?php /**.------------------------------------------------------------------------------------------------------------------- * | Github: https://github.com/Tinywan * '------------------------------------------------------------------------------------------------------------------*/ namespace app\pay\service; use redis\BaseRedis; use think\facade\Log; class RedisSubscribe { public function sub() { Log::error(get_current_date(). '--过期事件的订阅-- ' ); $redis = BaseRedis::location(); //这里是直接连接本地redis $redis ->setOption(\Redis::OPT_READ_TIMEOUT, -1); $redis ->psubscribe( array ( '__keyevent@0__:expired' ), function ( $redis , $pattern , $chan , $msg ) { Log::error( '[1]--过期事件的订阅 ' . $msg ); }); } } |
说明:psubscribe( $patterns, $callback ) 方法的第二个参数为一个回调函数,这里我使用闭包作为一个回调。
官方解释:匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。当然,也有其它应用的情况。
3、在TP5 项目根目录执行pay 命令工具
1 | php think pay psubscribe |
4、新打开console 窗口终端
1 2 3 4 5 6 7 8 | C:\Users\admin>redis-cli 127.0.0.1:6379> setex UserName 10 Tinywan OK 127.0.0.1:6379> get UserName "Tinywan" 127.0.0.1:6379> get UserName (nil) 127.0.0.1:6379> |
5、查看打日志文件,看有没有接收到过期的key
6、最终的结果如下所示
更高级的慢慢扩展
1、自动取消订单
2、订单完成后发送短信
3、延迟任务等等
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构