redis单例模式以及think-queue的redis

单例模式redis


<?php
namespace app\admin\common;
use think\helper\Str;
class RedisManager
{
  private static $handler = null;
  private static $_instance = null;
  private function __construct()
  {
    if (!extension_loaded('redis')) {
      throw new \BadFunctionCallException('not support: redis');      //判断是否有扩展
    }
    $config = app()->config->get('queue.connections.redis');
    $func = $config['persistent'] ? 'pconnect' : 'connect';
    self::$handler = new \Redis;
    self::$handler->$func($config['host'], $config['port'], $config['timeout']);
    if ('' != $config['password']) {
      self::$handler->auth($config['password']);
    }
    if (0 != $config['select']) {
      self::$handler->select($config['select']);
    }
  }
  /**
   * @return RedisPackage|null 对象
   */
  public static function getInstance()
  {
    if (!(self::$_instance instanceof self)) {
      self::$_instance = new self();
    }
    return self::$_instance;
  }
  /**
   * 禁止外部克隆
   */
  public function __clone()
  {
    trigger_error('Clone is not allow!',E_USER_ERROR);
  }
  /**
   * 写入缓存
   * @param string $key 键名
   * @param string $value 键值
   * @param int $exprie 过期时间 0:永不过期
   * @return bool
   */
  public static function set($key, $value, $exprie = 0)
  {
    if ($exprie == 0) {
      $set = self::$handler->set($key, $value);
    } else {
      $set = self::$handler->setex($key, $exprie, $value);
    }
    return $set;
  }
  /**
   * 读取缓存
   * @param string $key 键值
   * @return mixed
   */
  public static function get($key)
  {
    $fun = is_array($key) ? 'Mget' : 'get';
    return self::$handler->{$fun}($key);
  }
  /**
   * 删除key
   * @param $key
   * @return int
   * @author peter
   * @date 2022-04-09 上午10:39
   */
  public static function delKey($key){
    return self::$handler->del($key);
  }
  /**
   * 获取值长度
   * @param string $key
   * @return int
   */
  public static function lLen($key)
  {
    return self::$handler->lLen($key);
  }
  /**
   * 将一个或多个值插入到列表头部
   * @param $key
   * @param $value
   * @return int
   */
  public static function LPush($key, $value)
  {
    return self::$handler->lPush($key, $value);
  }
  /**
   * 移出并获取列表的第一个元素
   * @param string $key
   * @return string
   */
  public static function lPop($key)
  {
    return self::$handler->lPop($key);
  }
  public static function brPop($queue, $timeout = 0){
    return self::$handler->brPop($queue, $timeout);
  }
  public static function lrange($key,$start,$end){
    return self::$handler->lrange($key,$start,$end);
  }
}

调用方式


$redis = RedisManager::getInstance();
$redis->lrange('calc_list',0,-1);

代码摘自:think-queue redis

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: yunwuxin <448901948@qq.com>
// +----------------------------------------------------------------------

namespace think\queue\connector;

use Closure;
use Exception;
use RedisException;
use think\helper\Str;
use think\queue\Connector;
use think\queue\InteractsWithTime;
use think\queue\job\Redis as RedisJob;

class Redis extends Connector
{
    use InteractsWithTime;

    /** @var  \Redis */
    protected $redis;

    /**
     * The name of the default queue.
     *
     * @var string
     */
    protected $default;

    /**
     * The expiration time of a job.
     *
     * @var int|null
     */
    protected $retryAfter = 60;

    /**
     * The maximum number of seconds to block for a job.
     *
     * @var int|null
     */
    protected $blockFor = null;

    public function __construct($redis, $default = 'default', $retryAfter = 60, $blockFor = null)
    {
        $this->redis      = $redis;
        $this->default    = $default;
        $this->retryAfter = $retryAfter;
        $this->blockFor   = $blockFor;
    }

    public static function __make($config)
    {
        if (!extension_loaded('redis')) {
            throw new Exception('redis扩展未安装');
        }

        $redis = new class($config) {
            protected $config;
            protected $client;

            public function __construct($config)
            {
                $this->config = $config;
                $this->client = $this->createClient();
            }

            protected function createClient()
            {
                $config = $this->config;
                $func   = $config['persistent'] ? 'pconnect' : 'connect';

                $client = new \Redis;
                $client->$func($config['host'], $config['port'], $config['timeout']);

                if ('' != $config['password']) {
                    $client->auth($config['password']);
                }

                if (0 != $config['select']) {
                    $client->select($config['select']);
                }
                return $client;
            }

            public function __call($name, $arguments)
            {
                try {
                    return call_user_func_array([$this->client, $name], $arguments);
                } catch (RedisException $e) {
                    if (Str::contains($e->getMessage(), 'went away')) {
                        $this->client = $this->createClient();
                    }

                    throw $e;
                }
            }
        };

        return new self($redis, $config['queue'], $config['retry_after'] ?? 60, $config['block_for'] ?? null);
    }

    public function size($queue = null)
    {
        $queue = $this->getQueue($queue);

        return $this->redis->lLen($queue) + $this->redis->zCard("{$queue}:delayed") + $this->redis->zCard("{$queue}:reserved");
    }

    public function push($job, $data = '', $queue = null)
    {
        return $this->pushRaw($this->createPayload($job, $data), $queue);
    }

    public function pushRaw($payload, $queue = null, array $options = [])
    {
        if ($this->redis->rPush($this->getQueue($queue), $payload)) {
            return json_decode($payload, true)['id'] ?? null;
        }
    }

    public function later($delay, $job, $data = '', $queue = null)
    {
        return $this->laterRaw($delay, $this->createPayload($job, $data), $queue);
    }

}

posted @ 2023-06-08 10:12  窦戈  阅读(114)  评论(0编辑  收藏  举报