Redis键值过期自动执行回调函数

用到了 redis 的键空间通知(keyspace notifications)

  • 今天帮忙解决问题时遇到的redis一个功能点
  • 具体行为就是:某个键值到了过期时间自动触发回调函数,然后执行一些操作,比如订单15分钟未支付就自动取消。

系统环境Win10, PHP7.1

  • 下面记录下刚才爬的坑:

    • 1、redis 2.8版本的升级到 3.0 以上再说,比如 3.2
    • 2、如果将redis加入到windows的系统服务了,建议在初始阶段停止服务,使用redis-server "配置文件路径" 来启动redis,因为系统服务启动的redis使用的配置文件你可能搞不清楚,导致修改配置文件不生效,在最后我会讲。
    • 3、各种路径,参数问题,加不加引号等问题。
  • 本文仅就此功能进行讲解,业务逻辑不过多累述。

首先找一个空目录,新建四个文件,文件名以及内容如下:

  • index.php 经过一些业务逻辑后,设置一个 10s 后过期的键值
<?php
require_once 'Redis2.class.php';
// require_once 'db.class.php';

$redis2 = new \Redis2();
// $mysql      = new \mysql();   // 注释是你的业务逻辑
// $mysql->connect();

// $order_sn='SN'.time().'T'.rand(10000000,99999999);
// $data = ['ordersn'=>$order_sn,'status'=>0,'createtime'=>date('Y-m-d H:i:s',time())];
// $mysql->insert('order',$data);

$res = $redis2->setex('kkk',10, "It is no pay");
var_dump($res);exit;
  • psubscribe.php 监听,超时回调函数
    <?php
require_once 'Redis2.class.php';

ini_set('default_socket_timeout', -1);  //不超时
$redis = new Redis2();
// 解决Redis客户端订阅时候超时情况
$redis->setOption();
$redis->psubscribe(array('[email protected]__:expired'), 'keyCallback');
// 回调函数,这里写处理逻辑
function keyCallback($redis, $pattern, $chan, $msg)
{
    echo date('Y-M-D H:i:s');   // 这两行留作查看是否执行回调函数
    // file_put_contents("d:/lizheng.log", "\n\n".print_r(123, true),8);

    // 下面写你的业务逻辑
    //修改订单状态
    // $order=model('order')->where(['order_no'=>$msg])->find();
    // $order->status=-1;
    // $order->save();
    // //库存还原
    // $products=json_decode($order->snap_items,true);
    // foreach($products as $v){
    //     model('product')->where(['id'=>$v['id']])->setInc('stock',$v['count']);
    // }
}
  • Redis2.class.php 封装 redis 类
<?php
class Redis2
{
    private $redis;

    public function __construct($host = '127.0.0.1', $port = 6379)
    {
        $this->redis = new Redis();
        $this->redis->connect($host, $port);
        // $this->redis->auth('123456');
    }

    public function setex($key, $time, $val)
    {
        return $this->redis->setex($key, $time, $val);
    }

    public function set($key, $val)
    {
        return $this->redis->set($key, $val);
    }

    public function get($key)
    {
        return $this->redis->get($key);
    }

    public function expire($key = null, $time = 0)
    {
        return $this->redis->expire($key, $time);
    }

    public function psubscribe($patterns = array(), $callback)
    {
        $this->redis->psubscribe($patterns, $callback);
    }

    public function setOption()
    {
        $this->redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
    }

    public function lRange($key,$start,$end)
    {
        return $this->redis->lRange($key,$start,$end);
    }

    public function lPush($key, $value1, $value2 = null, $valueN = null ){
        return $this->redis->lPush($key, $value1, $value2 = null, $valueN = null );
    }

    public function delete($key1, $key2 = null, $key3 = null)
    {
        return $this->redis->delete($key1, $key2 = null, $key3 = null);
    }

}
  • db.class.php 封装mysql, 这里我们不涉及业务逻辑所以未使用
<?php
class mysql
{
    private $mysqli;
    private $result;
    /**
     * 数据库连接
     * @param $config 配置数组
     */

    public function connect()
    {
        $config=array(
            'host'=>'127.0.0.1',
            'username'=>'root',
            'password'=>'123456qwerty',
            'database'=>'marhal',
            'port'=>3306,
            );

        $host = $config['host'];    //主机地址
        $username = $config['username'];//用户名
        $password = $config['password'];//密码
        $database = $config['database'];//数据库
        $port = $config['port'];    //端口号
        $this->mysqli = new mysqli($host, $username, $password, $database, $port);

    }
    /**
     * 数据查询
     * @param $table 数据表
     * @param null $field 字段
     * @param null $where 条件
     * @return mixed 查询结果数目
     */
    public function select($table, $field = null, $where = null)
    {
        $sql = "SELECT * FROM `{$table}`";
        //echo $sql;exit;
        if (!empty($field)) {
            $field = '`' . implode('`,`', $field) . '`';
            $sql = str_replace('*', $field, $sql);
        }
        if (!empty($where)) {
            $sql = $sql . ' WHERE ' . $where;
        }

        $this->result = $this->mysqli->query($sql);

        return $this->result;
    }
    /**
     * @return mixed 获取全部结果
     */
    public function fetchAll()
    {
        return $this->result->fetch_all(MYSQLI_ASSOC);
    }
    /**
     * 插入数据
     * @param $table 数据表
     * @param $data 数据数组
     * @return mixed 插入ID
     */
    public function insert($table, $data)
    {
        foreach ($data as $key => $value) {
            $data[$key] = $this->mysqli->real_escape_string($value);
        }
        $keys = '`' . implode('`,`', array_keys($data)) . '`';
        $values = '\'' . implode("','", array_values($data)) . '\'';
        $sql = "INSERT INTO `{$table}`( {$keys} )VALUES( {$values} )";
        $this->mysqli->query($sql);
        return $this->mysqli->insert_id;
    }
    /**
     * 更新数据
     * @param $table 数据表
     * @param $data 数据数组
     * @param $where 过滤条件
     * @return mixed 受影响记录
     */
    public function update($table, $data, $where)
    {
        foreach ($data as $key => $value) {
            $data[$key] = $this->mysqli->real_escape_string($value);
        }
        $sets = array();
        foreach ($data as $key => $value) {
            $kstr = '`' . $key . '`';
            $vstr = '\'' . $value . '\'';
            array_push($sets, $kstr . '=' . $vstr);
        }
        $kav = implode(',', $sets);
        $sql = "UPDATE `{$table}` SET {$kav} WHERE {$where}";

        $this->mysqli->query($sql);
        return $this->mysqli->affected_rows;
    }
    /**
     * 删除数据
     * @param $table 数据表
     * @param $where 过滤条件
     * @return mixed 受影响记录
     */
    public function delete($table, $where)
    {
        $sql = "DELETE FROM `{$table}` WHERE {$where}";
        $this->mysqli->query($sql);
        return $this->mysqli->affected_rows;
    }
}

配置文件

原文地址:https://www.cnblogs.com/lz0925/p/12168165.html

时间: 2024-10-05 00:45:12

Redis键值过期自动执行回调函数的相关文章

spring中订阅redis键值过期消息通知

1.首先启用redis通知功能(ubuntu下操作):编辑/etc/redis/redis.conf文件,添加或启用以下内容(过期通知): notify-keyspace-events Ex 或者登陆redis-cli之后,输入以下命令: config set notify-keyspace-events Ex 更多通知详见:http://redis.io/topics/notifications#configuration 2.Java Spring中配置监听 接口类: import java

redis 键值对 有效期设置

redis 键值对 有效期设置redis中可以使用expire命令设置一个键的生存时间, 到时间后redis会自动删除它<-----> 类比于javaweb系统临时数据 过期删除功能 expire 设置失效时间(单位/秒)persist 取消失效时间 ttl/pttl(单位为 秒/毫秒) 查看键的剩余时间 返回三种值 -2(健已经不存在了)  -1(表示永久有效)  大于0的数(还有多少有效时间) pexpire设置失效时间(单位/毫秒) expireat [key] unix时间戳13518

php数组键值操作和数组统计函数-函数

1.数组函数//作用:提供了很多官方写的很多有用的代码段,提高编写速度 1)数组的键值操作函数 array_values();//获取数组中的值 array_keys();//获取数组中的键 in_array();//检查一个值是否在数组中 array_flip();//键和值对调 array_reverse();//数组中的值反转 模拟获取key的数值<?php $arr=array ("name"=>"user1","age"=&

$.getJSON()不执行回调函数

解决getJson方法不执行回调函数的问题 标签:jq Ajax 使用$.getjson缺不能执行回调函数很大的原因都是服务器不能把json解析成正确的格式. 1---  alert(1)     $.getJSON(url,args,function(data){ 2---   alert(2);      var name = data.person.name;      var website = data.person.website;      var email = data.per

jquery Ajax 不执行回调函数success的原因

jquery Ajax 不执行回调函数success的原因: $.ajax({ type: "post", contentType: "application/json", url: basePath+"pages/Tongji/disposeAgree.action?cepingitem="+cepingitem+"&userrelation="+userrelation, //data: {fenshu:8},da

register_shutdown_function函数详解--脚本退出时执行回调函数

register_shutdown_function — Register a function for execution on shutdown. ps:Registers a callback to be executed after script execution finishes or exit() is called. 1.脚本时常死掉,而且并不总是那么好看.我们可不想给用户显示一个致命错误,又或者一个空白页(在display_errors设为off的情况下) . PHP中有一个叫

Ajax不执行回调函数的原因(转)

今天用ajax的post请求后台,但是始终不执行回调函数,经查得知,ajax不执行回调函数的原因如下: jquery中规定返回的JSON字符串的KEY要用引号括起来,如{"result": 1}这样才可以. 所以是数据返回的格式问题,如把dataType设置为json,那么就需要按照json的格式将数据返回,如设置为text,则无需是json的数据格式. 原文地址:https://www.cnblogs.com/tianyublog/p/9251442.html

redis 键值相关命令

键值相关命令 keys *   返回所有的键  keys my* exists mykey1 是否存在mykey1键 del mykey 删除mykey键 expire mykey 10 设置mykey键过期时间为10秒 ttl mykey 得到mykey的过期时间(不断变化),-1 表示已经过期,过期则被销毁掉 ,如果没设置过期时间,默认就是-1 redis 默认16个数据库,从0-15. 默认为0数据库 select 1 选择1 数据库 move age 1 将age移到1数据库 persi

Redis 键值数据类型及基本操作

到目前为止,Redis 支持的键值数据类型如下: 字符串(String) 哈希(Map) 列表(list) 集合(sets) 有序集合(sorted sets)   1. String 字符串类型 string是redis最基本的类型,一个key对应一个value. string类型是二进制安全的.意思是redis的string可以包含任何数据.比如jpg图片或者序列化的对象 . string类型是Redis最基本的数据类型,一个键最大能存储512MB. String 命令: 赋值与取值 set