使用memcache和redis实现队列
队列的基本功能是:压入和弹出,先进先出。
memcache的实现方式
使用memcache实现队列,需要使用两个key来标记队列的状态:pushKey 记录压入队列的总数,popKey记录弹出队列的总数。
压入数据:pushKey初始值为0,每压入队列一个数据的时候,pushKey自增1。
弹出数据:popKey初始值为0,每从队列中弹出一个数据的时候,popKey自增1。同时删除队列弹出数据的时候,从小标0开始,实现了先进先出的特点。弹出数据的实质是:获取这个数据,然后在把这个数据从队列中删除。
队列初始化代码
- public function __construct($queue, array $config)
- {
- if (! $queue) {
- throw new Core_Exception_Fatal('队列名不能为空');
- }
- // 连接实例
- $this->_memcache = new Com_Cache_Memcache();
- // 初始化键名
- $this->_pushedCountKey = 'Queue:' . strtoupper($queue) . ':PushedCount'; // 已压进元素数
- $this->_popedCountKey = 'Queue:' . strtoupper($queue) . ':PopedCount'; // 已弹出元素数
- $this->_queueDataKey = 'Queue:' . strtoupper($queue) . ':Data'; // 队列数据前缀
- }
PUSH数据
- public function push($value)
- {
- if (! $value) {
- return false;
- }
- $pushed = intval($this->_memcache->get($this->_pushedCountKey));
- // 压进
- $key = $this->_queueDataKey . ':' . $pushed;
- if (! $this->_memcache->set($key, $value)) {
- return false;
- }
- // 累加已压进了几个元素
- if (! $this->_memcache->increment($this->_pushedCountKey)) {
- $this->_memcache->set($this->_pushedCountKey, 1);
- }
- return true;
- }
pop数据:
- public function pop()
- {
- $poped = intval($this->_memcache->get($this->_popedCountKey));
- // 弹出
- $key = $this->_queueDataKey . ':' . $poped;
- $value = $this->_memcache->get($key);
- // 如队列已全部弹出,则跳出
- if ($value === false) {
- return false;
- }
- // 从队列中删除此数据
- $this->_memcache->delete($key);
- // 累加弹出了几个元素
- if (! $this->_memcache->increment($this->_popedCountKey)) {
- $this->_memcache->set($this->_popedCountKey, 1);
- }
- return $value;
- }
redis实现
Redis提供了列表,可以很容易的实现队列,主要需要的函数有:
rpush($value) : 向队列中压入一个数据
lpop($value): 弹出一个数据
队列的使用范围
需要异步处理的时候,使用队列,可以缩短响应时间,比如网页发短信,可以把需要发送的短信保存在队列中,然后直接提示玩家短信发送成功,其实,这个时候短信可能还没有发送出去,发送短信的服务器再读取这个队列,然后发送短信。所以提示玩家短信发送成功和发送短信是异步处理的