Redis使用延迟队列

redis操作类
class RedisHandler
        {
            public $provider;
            private static $_instance = null;
        
            /**
             * 连接redis
             * RedisHandler constructor.
             */
            private function __construct()
            {
                $this->provider = new \Redis();
                $redis = config('database.redis');
                $this->provider->connect($redis['host'], $redis['port']);
                $this->provider->auth($redis['auth']);
            }
        
            //防克隆
            final private function __clone(){}
        
            //单例模式
            public static function getInstance()
            {
                if (!self::$_instance) {
                    self::$_instance = new RedisHandler();
                }
                return self::$_instance;
            }
        
            /**
             * @param string $key 有序集key
             * @param number $score 排序值
             * @param string $value 格式化的数据
             * @return int
             */
            public function zAdd($key, $score, $value)
            {
                return $this->provider->zAdd($key, $score, $value);
            }
        
            /**
             * 获取有序集数据
             * @param $key
             * @param $start
             * @param $end
             * @param null $withscores
             * @return array
             */
            public function zRange($key, $start, $end, $withscores = null)
            {
                return $this->provider->zRange($key, $start, $end, $withscores);
            }
        
            /**
             * 删除有序集数据
             * @param $key
             * @param $member
             * @return int
             */
            public function zRem($key, $member)
            {
                return $this->provider->zRem($key, $member);
            }
        }
		*

消息队列生产和消费

class RedisDelayQueue
    {
        private $prefix = 'delay_queue:';
    
        private $queue;
    
        private static $_instance = null;
    
        protected $payload;
    
        public function preform()
        {
            // todo
            return true;
        }
    
        public function setPayload($args = null)
        {
            $this->payload = $args;
    
        }
    
      
        private function __construct($queue)
        {
            $this->queue = $queue;
        }

        public static function getInstance($queue = '')
        {
            if (!self::$_instance) {
                self::$_instance = new RedisDelayQueue($queue);
            }
            return self::$_instance;
        }
    
        /**
         * 添加任务信息到队列
         *
         * @param $jobClass
         * @param int $runTime 执行时间
         * @param array $args
         */
        public function addTask($jobClass, $runTime, $args = null)
        {
            $key = $this->prefix . $this->queue;
    
            $params = [
                'class' => $jobClass,
                'args' => $args,
                'runtime' => $runTime,
            ];
    
            RedisHandler::getInstance()->zAdd(
                $key,
                $runTime,
                serialize($params)
            );
        }
    
        /**
         * 执行job
         * @return bool
         */
        public function perform()
        {
            $key = $this->prefix . $this->queue;
            //取出有序集第一个元素
            $result = RedisHandler::getInstance()->zRange($key, 0, 0);
            if (!$result) {
                return false;
            }
    
            $jobInfo = unserialize($result[0]);
    //        print_r('job: ' . $jobInfo['class'] . ' will run at: ' . date('Y-m-d H:i:s', $jobInfo['runtime']) . PHP_EOL);
            $jobClass = $jobInfo['class'];
            if (!@class_exists($jobClass)) {
                print_r($jobClass . ' undefined' . PHP_EOL);
                RedisHandler::getInstance()->zRem($key, $result[0]);
                return false;
            }
            // 到时间执行
            if (time() >= $jobInfo['runtime']) {
                $job = new $jobClass;
                $job->setPayload($jobInfo['args']);
                $jobResult = $job->preform();
                //移除有序集合
                RedisHandler::getInstance()->zRem($key, $result[0]);
            }
            return false;
        }
    }

队列执行

class Hello
{
    protected $data = null;

    public $rand = null;


    public function setPayload($data)
    {
        $this->data = $data;
    }

    /**
     * 消息队列
     * @return bool
     */
    public function preform()
    {
        //实际业务为准$this->data 传过来的数组
    }

如何添加队列

//推入队列 RedisDelayQueue::getInstance('Hello')->addTask(Hello::class, $time,[]); //[]以实际业务为准

消费队列(使用命令行加入常驻内存)

 while (true) {
   RedisDelayQueue::getInstance('pushMessage')->perform();
}
posted @ 2021-02-22 14:54  惊风破浪的博客  阅读(151)  评论(0编辑  收藏  举报