隊列的基本功能是:壓入和彈出,先進先出。
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): 彈出一個數據
隊列的使用範圍
需要異步處理的時候,使用隊列,可以縮短響應時間,比如網頁發短信,可以把需要發送的短信保存在隊列中,然後直接提示玩家短信發送成功,其實,這個時候短信可能還沒有發送出去,發送短信的服務器再讀取這個隊列,然後發送短信。所以提示玩家短信發送成功和發送短信是異步處理的