最近项目中用到好多用异步队列处理的后台任务,有些心得,记录一下。
下面引用百度百科的对队列的解释:
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。 简单点讲就是:先进先出
要实现一个队列,你可以根据自身服务器资源,可选数据库或者redis或者其他更高级的队列资源来实现。
简单实现,大概代码是这样子的:
class Queue{
protected $items = [];
/**
* 从队列尾部插入数据
* @param string $key 对列名称
* @return mixed $value 数据
*/
public function push($key, $value){
isset($this->items[$key]) or $this->items[$key] = [];
return array_push($this->items[$key], $value);
}
/**
* 从队列头部取出数据
* @param string $key 对列名称
*/
public function pop($key){
isset($this->items[$key]) or $this->items[$key] = [];
return array_shift($this->items[$key]);
}
}
测试:
$queue = new Queue();
var_dump($queue->pop('list_1')); //输出 NULL
$queue->push('list_1', '1');
$queue->push('list_1', '2');
$queue->push('list_1', '3');
var_dump($queue->pop('list_1')); //输出 string(1) "1"
var_dump($queue->pop('list_1')); //输出 string(1) "2"
上面是一个直接存储在数组中的队列,只能在一个php生命周期中使用。我们可以把存储的方式改成别的,例如数据库或者redis什么的。
这里我们使用redis,用到redis的有序列表(list)
class RedisQueue{
protected $client; //这里使用了predis这个库连接redis
public function __construct(PredisClient $client)
{
$this->client = $client;
}
/**
* Add an element to the end of the queue
* @param string $key
* @param mixed $value
* @return int
*/
public function push($key, $value){
return $this->client->rpush($key, $value);
}
/**
* Take an element from the queue header
* @param string $key
* @return mixed
*/
public function pop($key){
return $this->client->lpop($key);
}
}
你还是可以使用上面的例子测试下。
当然了,还有很多情况下,我们的队列要延时出队,我们就要使用redis的另外一种数据类型:有序集合
(未完待续)