Qless是一个基于redis的分布式任务架构。相关代码在
https://github.com/seomoz/qless
它是完全有lua实现的,依靠 redis 对lua的支持,http://www.cnblogs.com/ghj1976/p/4298206.html 它实现了对redis的功能扩展。
有关lua的一些语法基础知识可以参考:http://www.cnblogs.com/ghj1976/p/4298178.html
https://github.com/seomoz/qless 这里我们可以看到下面文件,它们分别是下面功能:
base.lua -- 提前声明的部分和一些未分类的功能
config.lua -- 所有配置
job.lua -- 定时job类
recurring.lua -- 重复的job类
queue.lua -- 队列类
api.lua -- 客户端调用封装,这里做了一个非常轻量的封装
我们用的时候其实用的是 qless.lua 文件, 要用这个文件,需要用 make qless.lua 命令才产生:
在 qless.lua 的最后,我们可以看到下面一段代码,对这部分代码的解释如下:
if #KEYS > 0 then error('No Keys should be provided') end
local command_name = assert(table.remove(ARGV, 1), 'Must provide a command')
local command = assert(
QlessAPI[command_name], 'Unknown command ' .. command_name)
local now = tonumber(table.remove(ARGV, 1))
local now = assert(
now, 'Arg "now" missing or not a number: ' .. (now or 'nil'))
return command(now, unpack(ARGV))
来自外部的调用,其实都被执行到 QlessAPI下的对应方法了, 外部调用传递进来的第1个参数是 QlessAPI 下对应的命令名字, 第二个是 这个命令的 now 参数,其他是其他参数。
在Redis中执行Lua的参数说明
在Redis中执行lua,我们最常用下面三个命令:EVAL、EVALSHA、SCRIPT LOAD
参考:http://www.cnblogs.com/ghj1976/p/4298206.html
以 eval 为例,它的参数如下,其他几个参数也类似:
EVAL script numkeys key [key ...] arg [arg ...]
script 参数是一段 Lua 5.1 脚本程序,它会被运行在 Redis 服务器上下文中,这段脚本不必(也不应该)定义为一个 Lua 函数。
numkeys 参数用于指定键名参数的个数。
键名参数 key [key ...] 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。
在命令的最后,那些不是键名参数的附加参数 arg [arg ...] ,可以在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。
上面这几段长长的说明可以用一个简单的例子来概括:
> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"
其中 "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 是被求值的 Lua 脚本,数字 2 指定了键名参数的数量, key1 和 key2 是键名参数,分别使用 KEYS[1] 和 KEYS[2] 访问,而最后的 first 和 second 则是附加参数,可以通过 ARGV[1] 和 ARGV[2] 访问它们。
参考: http://redis.readthedocs.org/en/latest/script/eval.html#eval
table.remove
table 的默认初始索引一般以 1 开始
table.remove(table, pos)
table.remove()函数删除并返回table数组部分位于pos位置的元素. 其后的元素会被前移. pos参数可选, 默认为table长度, 即从最后一个元素删起.
参考:http://dhq.me/lua-learning-notes-table
assert (v [, message])
功能:相当于C的断言,
参数:
v:当表达式v为nil或false将触发错误,
message:发生错误时返回的信息,默认为"assertion failed!"
unpack
函数unpack可以返回多个值,它传入一个array,然后返回array中的每一个值
参考:http://blog.csdn.net/wzzfeitian/article/details/8653101
Golang 这个的实现版本在: https://github.com/kdar/goqless
其中的调用逻辑被封装在下面代码:
github.com\kdar\goqless\client.go
func (c *Client) Do(name string, keysAndArgs ...interface{}) (interface{}, error) {
return c.lua.Do(name, keysAndArgs...)
}
这里的 name 是 qless的命令, 类似下面的 get, 其他是这里的参数。
-- Return json for the job identified by the provided jid. If the job is not
-- present, then `nil` is returned
function QlessAPI.get(now, jid)
local data = Qless.job(jid):data()
if not data then
return nil
end
return cjson.encode(data)
end