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