tp5命令行+redis发布订阅实现定时任务

最近遇到个这样的需求:点赞排行榜,在规定的时间内(可能有好几天),谁获赞多谁就获胜。今天试了下redis消息订阅,发现还可以,写写具体过程吧。

1.安装redis,phpredis扩展 

    这些网上一搜一大把

2.搜了个redis类,新建类:app\common\controller\MyRedis,代码如下:

redis = new \Redis();
        $this->redis->config('notify-keyspace-events','Ex');//开启redis key 过期通知(改过配置文件,但没成功)
        $this->redis->connect($host, $port);
    }

    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 subscribe($patterns = array(), $callback)
    {
        $this->redis->subscribe($patterns, $callback);
    }

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

}

注意看我代码注释那句:

3.使用tp5命令行

   在application下新建文件command.php(没有的就新建),代码:

   然后新建 application\index\command\Index.php,代码如下:

setName('hello')
            ->setDescription('Say Hello world');
    }

    protected function execute(Input $input, Output $output)
    {
        $redis = new MyRedis();
        $redis->setOption();
        $redis->psubscribe(array('__keyevent@0__:expired'), function ($redis, $pattern, $chan, $msg){
//            echo $msg.' ';
//            $teacher = new Teacher();
//            $teacher->name = $msg;
//            $teacher->save();
            var_dump($redis,$pattern,$chan,$msg);
        });


    }

}

建了一个 “hello”命令,重点是execute()方法,redis的psubscribe监听 “0”这个数据库,有 key "expired"(过期)就执行后面的回调方法,在回调方法里可以使用curl方式调用写好的接口,功能逻辑有变动也不需要修改这里命令行的代码,$msg参数就是过期的键名,在我这里就应该是存放的是某个项目的id。

4.执行

   在项目根目录,先php think查看是有已有“hello”这个命令,

tp5命令行+redis发布订阅实现定时任务_第1张图片

然后执行hello命令

现在就在“监听”有没有过期的key了,有的话会打印出来:

tp5命令行+redis发布订阅实现定时任务_第2张图片

5.完善

  1)使用supervisor将"php think hello"命令加入守护命令,并将supervisor设置开机自启

      安装supervisor。。。

      在supervisor配置文件supervisord.conf末尾,有这样一句话

[include]
files = supervisord.d/*.conf

     在对应路径下,新建自己的配置文件 hello.conf,其内容如下:

[program:hello]
command=/usr/bin/php /usr/html/php/think hello
process_name=%(program_name)s_%(process_num)02d
;numprocs=5
autostart=true
autorestart=true
startsecs=1 ;程序重启时候停留在runing状态的秒数
startretries=10 ;启动失败时的最多重试次数
redirect_stderr=true
user=root
stdout_logfile=/etc/supervisord.d/challenge.log
[supervisord]
 
[supervisorctl]

  注意:command, /usr/bin/php是php运行文件,/usr/html/php/是tp项目根目录,后面think hello就是创建的tp命令行,所以这句话的意思就是执行 php think hello

       stdout_logfile 是日志、echo var_dump等输出的地方

另外,每次改动命令行相关代码,都需要重新加载supervisor。

 

2)redis持久化

你可能感兴趣的:(thinkphp5,php,redis)