基于 Redis 有序集合, 实现简单的延时任务
https://www.youhuajun.com/article/31
延时任务的场景很多, 开发过程中我们经常会遇到, 比如说:
1. 订单未付款, 5 分钟后自动取消, 这是电商网站非常普遍的需求;
2. 用户创建订单不付款, 3 分钟后自动发短信, 微信消息提醒;
3. 会员到期提醒 等等, 这些都算延时任务提醒.
实现延时任务功能的方式很多, 我们公司的业务不大, 没打算用中间件, 所以, 我干脆直接用 Redis 实现.
Redis 实现延时任务有 2 种方式, 一种是根据有序集合去实现, 还有种是根据键的过期, 去触发延时任务, 两个方式都可以, 今天我主要说的是第一种. 因为我用的是 yii2, 所以代码我用的 yii2 写.
Redis 有序集合和集合一样也是 string 类型元素的集合, 且不允许重复的成员. 不同的是每个元素都会关联一个 double 类型的分数. Redis 正是通过分数来为集合中的成员进行从小到大的排序. 有序集合的成员是唯一的, 但分数 (score) 却可以重复. 我们这边分数就是我们的时间, 我们根据 score 的大小去处理业务.
一: 添加 Redis 延时任务
- /*** 添加延时任务
- * @param $setName 集合名字
- *@param $time 启动任务的时间
- * @param array $task 任务详情
- * @return mixed
- */
- public static function product($setName,$time, $task){
- $redisModel = Yii::$App->Redis;
- if(is_array($task)){
- $task = json_encode($task,JSON_UNESCAPED_UNICODE);
- }
- // 延时 2 秒, 避免结束时间和到点时间出现并发问题
- return $redisModel->zadd($setName,$time+2,$task);
- }
- PHP
- Copy
二: 获取任务条数 我们可以做个定时任务, 去定时获取需要消费的延时任务, 当有任务才继续执行
- /** 获取剩余任务数
- * @param $setName
- * @return int
- */
- public static function count($setName){
- $redisModel = Yii::$App->Redis;
- return $redisModel->zcard($setName);
- }
- PHP
- Copy
三: 消费延时任务 这边是获取延时任务代码, 具体怎么去进一步抄作, 可以根据业务需要去写.
- /**
- * 消费延时任务
- */
- public static function consume($setName){
- $redisModel = Yii::$App->Redis;
- return $redisModel->zrangebyscore($setName,0,time());
- }
- PHP
- Copy
四: 删除任务 任务处理完毕, 删除集合中已经处理好的任务
- /** 删除任务
- * @param $setName
- * @param $value
- * @return mixed
- */
- public static function delTask($setName,$value)
- {
- $redisModel = Yii::$App->Redis;
- return $redisModel->zrem($setName, $value);
- }
来源: https://www.cnblogs.com/jianqingwang/p/12189037.html