美文网首页redis
利用redis实现定时任务,完全不需要crontab

利用redis实现定时任务,完全不需要crontab

作者: 勤学会 | 来源:发表于2017-08-20 19:27 被阅读0次

    主要原理

    利用redis过期通知事件
    1.redis配置
    daemonize yes //守护进程
    这里需要配置 notify-keyspace-events 的参数为 “Ex”。x 代表了过期事件
    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.接受过期通知
    这里用的是tp5的命令模式,框架如果支持命令模式会方便很多

    <?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.把命令挂到后台一直去执行
    nohup php /home/www/app/think test &
    jobs #查看是否生效
    ps aux | grep php #再看看也行
    5.在需要的地方设置过期事件
    setex order_1 5 chokingwin
    然后就会自动触发order方法,参数是"_"后面的1

    注意事项

    如果代码修改过,记得kill掉 nohup,再启动一次

    感谢chokingwin的文章

    相关文章

      网友评论

        本文标题:利用redis实现定时任务,完全不需要crontab

        本文链接:https://www.haomeiwen.com/subject/ponfdxtx.html