SquirrelMQ特性:
1. SquirrelMQ使用Slab内存分配算法来降低内存碎片,使用epoll来解决高并发问题。效率比redis要高,使用简单。
2. 另外SquirrelMQ支持持久化,在down机的情况下也不用担心数据丢失。
3. SquirrelMQ支持lua脚本,你可以制定自己的处理队列程序,只要在cron/main.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
# 是否开启Lua处理线程
enableLuaThread 1
# 是否使用守护进程模式运行
daemonize 0
我们根据自己的需求来修改配置,特别说明一下的是,当开启Lua处理线程时,我们可以编写Lua脚本来处理队列(在cron/main.lua)。这样就可以让服务器本身来处理消息队列的数据,而不用另外写一个cron程序来处理。下面我们会介绍。
4) 运行SquirrelMQ:
#> ./squirrel –c squirrel.conf
<?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();
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)