利用redis實(shí)現(xiàn)定時(shí)任務(wù),完全不需要crontab

主要原理

利用redis過(guò)期通知事件
1.redis配置
daemonize yes //守護(hù)進(jìn)程
這里需要配置 notify-keyspace-events 的參數(shù)為 “Ex”。x 代表了過(guò)期事件
2.封裝redis類

<?php
namespace app\common\service;
class MyRedis
{
    private $redis;

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

    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);
    }
}

3.接受過(guò)期通知
這里用的是tp5的命令模式,框架如果支持命令模式會(huì)方便很多

<?php
#! /usr/local/php/bin/php
namespace app\api\command;

use think\console\Command;
use think\console\Input;
use think\console\Output;
use app\common\model\Order;
use app\common\service\MyRedis;

class Test extends Command
{
    protected function configure()
    {
        $this->setName('test')->setDescription('Here is the remark ');
    }
    
    protected function execute(Input $input, Output $output)
    {
        $redis = new MyRedis();
        $redis->psubscribe(array('__keyevent@0__:expired'),
            function ($redis, $pattern, $chan, $msg) use ($output) {
                if ($pattern = '__keyevent@0__:expired' && $msg) {
                    $array = explode('_', $msg);
                    $function = $array['0'];
                    $this->$function($array['1']);
                    $output->writeln($msg);
                }
            });
    }

    /*
     * 具體事件
     */
    public function order($id)
    {
        $Order = Order::get($id);
        $a=mt_rand(10000,99999);
        $data['status'] = $a;
        $Order->save($data);
    }

}

4.把命令掛到后臺(tái)一直去執(zhí)行
nohup php /home/www/app/think test &
jobs #查看是否生效
ps aux | grep php #再看看也行
5.在需要的地方設(shè)置過(guò)期事件
setex order_1 5 chokingwin
然后就會(huì)自動(dòng)觸發(fā)order方法,參數(shù)是"_"后面的1

注意事項(xiàng)

如果代碼修改過(guò),記得kill掉 nohup,再啟動(dòng)一次

感謝chokingwin的文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容