SquirrelMQ消息隊列介紹

jopen 11年前發布 | 20K 次閱讀 消息系統 SquirrelMQ

代碼量不算多,非常適合學習(socket,poll,memory方面都不錯)

SquirrelMQ是一個快速的消息隊列。

SquirrelMQ特性:

1. SquirrelMQ使用Slab內存分配算法來降低內存碎片,使用epoll來解決高并發問題。效率比redis要高,使用簡單。

2. 另外SquirrelMQ支持持久化,在down機的情況下也不用擔心數據丟失。

3. SquirrelMQ支持lua腳本,你可以制定自己的處理隊列程序,只要在cron/main.lua中編寫代碼即可。

一,SquirrelMQ使用

下面,我們介紹使用SquirrelMQ消息隊列來完成上面所說的應用吧。

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 
 # 最大可以使用內存數(單位:字節) 
memoryLimitUsed 524288000 
 # 多長時間進行存儲數據到硬盤(防止down機時數據丟失,單位為秒) 
secondsToSaveDisk 30 
 # 多少次數據變化才進行存儲數據到硬盤(防止寫數據過于頻繁) 
chagesToSaveDisk 30 
 # 客戶端連接多長時間不操作自動關閉(單位為秒) 
clientExpiredTime 60 
 # 多長時間運行一次cron(單位為毫秒) 
cronLoops 5000 
 # 是否需要密碼認證 
enableAuth 0 
 # 認證密碼(在enableAuth為1時才需要) 
authPwd xn2k@*%bse!@ 
 # lua腳本的路徑 
luaFilePath /var/squirrelmq/main.lua 
 # 提供給SquirrelMQ調用的函數 
luaMainFunction __main__ 
 # 是否使用守護進程模式運行 
daemonize 0

我們根據自己的需求來修改配置,特別說明一下的是,當開啟Lua處理線程時,我們可以編寫Lua腳本來處理隊列(在cron/main.lua)。這樣就可以讓服務器本身來處理消息隊列的數據,而不用另外寫一個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的消息條數:

<?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)取得隊列的狀態: 
$stat = $smq->stat();

三,使用Lua處理隊列

SquirrelMQ的一個令人興奮的特性就是支持使用Lua處理隊列中的消息,下面我們來介紹一下這個功能。

要開啟Lua處理線程,需要在配置文件中把enableLuaThread設置為1。這樣SquirrelMQ就會開啟Lua處理線程。我們可以在 cron/main.lua文件中編寫我們的Lua代碼來處理隊列中的消息。在cron/main.lua文件中,必須編寫一個main的函數,SquirrelMQ就是以這個函數作為入口,如:

function __main__() ...... end

在main函數中,我們可以使用一些SquirrelMQ提供的API函數取得隊列中的消息,如smq_pop_head()和smq_pop_tail()等。main函數可以這樣寫:

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都是阻塞的,也就是說,當隊列為空時,API會阻塞知道隊列有消息可以獲取為止,這樣做的目的是為了盡量減少Lua線程的運行時間。

在上面例子中,我們使用smq_pop_head()來取得隊列的第一條消息,然后執行此消息(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對應PHP客戶端的API。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!