当前位置 主页 > 服务器问题 > Linux/apache问题 >

    使用PHP+Redis实现延迟任务,实现自动取消订单功能

    栏目:Linux/apache问题 时间:2019-11-22 10:49

    简单定时任务解决方案:使用redis的keyspace notifications(键失效后通知事件) 需要注意此功能是在redis 2.8版本以后推出的,因此你服务器上的reids最少要是2.8版本以上;

    (A)业务场景:

    1、当一个业务触发以后需要启动一个定时任务,在指定时间内再去执行一个任务(如自动取消订单,自动完成订单等功能)

    2、redis的keyspace notifications 会在key失效后发送一个事件,监听此事件的的客户端就可以收到通知

    (B)服务准备:

    1、修改reids配置文件(redis.conf)【window系统配置文件为:redis.windows.conf 】

    redis默认不会开启keyspace notifications,因为开启后会对cpu有消耗

    备注:E:keyevent事件,事件以__keyevent@<db>__为前缀进行发布;

    x:过期事件,当某个键过期并删除时会产生该事件;

    原配置为:

    notify-keyspace-events ""

    更改 配置如下:

    notify-keyspace-events "Ex"

    保存配置后,重启Redis服务,使配置生效

    [root@chokingwin etc]#
    service redis-server restart /usr/local/redis/etc/redis.conf 
    Stopping redis-server: [ OK ] 
    Starting redis-server: [ OK ]

    window系统重启redis ,先切换到redis文件目录,然后关闭redis服务(redis-server --service-stop),再开启(redis-server --service-start)

    C)文件代码:

    phpredis实现订阅Keyspace notification,可实现自动取消订单,自动完成订单。以下为测试例子

    创建4个文件,然后自行修改数据库和redis配置参数

    db.class.php

    <?php
    class mysql
    {
     private $mysqli;
     private $result;
     /**
     * 数据库连接
     * @param $config 配置数组
     */
    
     public function connect()
     {
     $config=array(
     'host'=>'127.0.0.1',
     'username'=>'root',
     'password'=>'168168',
     'database'=>'test',
     '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;
     }
    }