SquirrelMQ快速的消息隊列
SquirrelMQ是一個快速的消息隊列。
SquirrelMQ特性:
1. SquirrelMQ使用Slab內(nèi)存分配算法來降低內(nèi)存碎片,使用epoll來解決高并發(fā)問題。效率比redis要高,使用簡單。
2. 另外SquirrelMQ支持持久化,在down機(jī)的情況下也不用擔(dān)心數(shù)據(jù)丟失。
3. SquirrelMQ支持lua腳本,你可以制定自己的處理隊列程序,只要在cron/main.lua中編寫代碼即可。
一,SquirrelMQ使用
下面,我們介紹使用SquirrelMQ消息隊列來完成上面所說的應(yīng)用吧。1) 安裝Lua。
2) 首先下載編譯SquirrelMQ:
#> wget http://squirrel-message-queue.googlecode.com/files/squirrel-with-lua-v1.2.zip
#> tar –zxvf squirrel-with-lua-v1.2.zip
#> cd squirrel-with-lua-v1.2
#> make
3) 修改SquirrelMQ配置(squirrel.conf文件):
# 偵聽端口
listingPort 6061
# 最大可以使用內(nèi)存數(shù)(單位:字節(jié))
memoryLimitUsed 524288000
# 多長時間進(jìn)行存儲數(shù)據(jù)到硬盤(防止down機(jī)時數(shù)據(jù)丟失,單位為秒)
secondsToSaveDisk 30
# 多少次數(shù)據(jù)變化才進(jìn)行存儲數(shù)據(jù)到硬盤(防止寫數(shù)據(jù)過于頻繁)
chagesToSaveDisk 30
# 客戶端連接多長時間不操作自動關(guān)閉(單位為秒)
clientExpiredTime 60
# 多長時間運行一次cron(單位為毫秒)
cronLoops 5000
# 是否開啟Lua處理線程
enableLuaThread 1
# 是否使用守護(hù)進(jìn)程模式運行
daemonize 0
我們根據(jù)自己的需求來修改配置,特別說明一下的是,當(dāng)開啟Lua處理線程時,我們可以編寫Lua腳本來處理隊列(在cron/main.lua)。這樣就可以讓服務(wù)器本身來處理消息隊列的數(shù)據(jù),而不用另外寫一個cron程序來處理。下面我們會介紹。
4) 運行SquirrelMQ:
#> ./squirrel –c squirrel.conf
二,使用客戶端API
SquirrelMQ提供一個PHP訪問的API,在php/squirrel.class.php。我們可以使用這個API文件輕松地訪問SquirrelMQ。這個API文件把所有訪問SquirrelMQ的操作封裝成一個類,叫Squirrel,在使用時直接new一個Squirrel的對象即可,如下:
<?php
include("squirrel.class.php");
$smq = new Squirrel('127.0.0.1', 6061);
$smq->push_tail("INSERT INTO mytable(uid, username, password)VALUES(NULL, 'liexusong', '123456');");
?>
這樣,我們就可以把一條消息插入到消息隊列了。我們可以使用size()方法來獲取SquirrelMQ的消息條數(shù):
<?php
include("squirrel.class.php");
$smq = new Squirrel('127.0.0.1', 6061);
$size = $smq->size();
echo "The SquirrelMQ size: $size";
?>
SquirrelMQ支持的API有:
1)插入到隊列的頭部:
$smq->push_head($message);
2)插入到隊列的尾部:
$smq->push_tail($message);
3)取得隊列的第一條消息,并從隊列中刪除:
$message = $smq->pop_head();
4)取得隊列的最后一條消息,并從隊列中刪除:
$message = $smq->pop_tail();
5)取得隊列的第n條消息,并且從隊列中刪除:
$message = $smq->pop_index($index);
6)取得隊列的第一條消息,但不從隊列中刪除:
$message = $smq->get_head();
7)取得隊列的最后一條消息,但不從隊列中刪除:
$message = $smq->get_tail();
8)取得隊列的第n條消息,但不從隊列中刪除:
$message = $smq->get_index($index);
9)取得隊列的大小:
$size = $smq->size();
10)取得隊列的狀態(tài):
$stat = $smq->stat();
三,使用Lua處理隊列
SquirrelMQ的一個令人興奮的特性就是支持使用Lua處理隊列中的消息,下面我們來介紹一下這個功能。要開啟Lua處理線程,需要在配置文件中把enableLuaThread設(shè)置為1。這樣SquirrelMQ就會開啟Lua處理線程。我們可以在cron/main.lua文件中編寫我們的Lua代碼來處理隊列中的消息。在cron/main.lua文件中,必須編寫一個 main 的函數(shù),SquirrelMQ就是以這個函數(shù)作為入口,如:
function __main__()
......
end
在 main 函數(shù)中,我們可以使用一些SquirrelMQ提供的API函數(shù)取得隊列中的消息,如smq_pop_head()和smq_pop_tail()等。 main 函數(shù)可以這樣寫:
require "luasql.mysql"
function __main__()
env = luasql.mysql()
con = env:connect("database", "username", "password", "127.0.0.1", 3306)
while true do
local ok, sql = smq_pop_head()
if ok then
res = con:execute(sql)
end
end
con:close()
env:close()
end
記住,SquirrelMQ提供的API都是阻塞的,也就是說,當(dāng)隊列為空時,API會阻塞知道隊列有消息可以獲取為止,這樣做的目的是為了盡量減少Lua線程的運行時間。
在上面例子中,我們使用smq_pop_head()來取得隊列的第一條消息,然后執(zhí)行此消息(con:execute(sql))。
SquirrelMQ提供給Lua線程使用的API有:
# ok, item = smq_pop_head()
# ok, item = smq_pop_tail()
# ok, item = smq_pop_index()
# ok, item = smq_get_head()
# ok, item = smq_get_tail()
# ok, item = smq_get_index()
# size = smq_queue_size()
# ok = smq_push_head(item)
# ok = smq_push_tail(item)
上面的API對應(yīng)PHP客戶端的API。
有問題可以聯(lián)系我,新浪微薄:旭松_Lie
