ngx lua module内存共享特性问题,ngxlua


直接上代码,总共两个文件:
common.lua

local _M = {}

local bucket = {}

function _M.add(key)
    bucket[key] = key
end

function _M.get()
    return bucket
end

return _M

index.lua

local common = require "path.to.common" -- 加载common文件,路径根据实际情况填写

math.randomseed(ngx.now())
local key = tostring(math.random(1, 100)) -- 生成一个随机数字
common.add(key)
local bucket = common.get()
print(cjson.encode(bucket) .. "\n")
ngx.exit(200)

接着,确保nginx.conf开启了lua缓存:

lua_code_cache on;

第一次请求执行index.lua输出:

{"28":"28"}

第二次请求执行index.lua输出:

{"77":"77","28":"28"}

看到没?第二次执行index.lua的时候,第一次执行时添加的元素28仍然在bucket变量里,说明第一次对bucket变量的修改影响到了第二次的执行,说明不同的请求是共用一个bucket变量的。

关于这个问题,是由于require()函数在第一次加载 common 模块的时候会把它缓存在package.loaded这个全局表中(当然,这个表其实也不是全局变量,而是注册在 Lua registry 里),而Lua registry是在VM内共享的,所以也导致了common模块在VM内共享。

而在openresty里,一个worker共用一个VM,所以就出现了同个worker里的请求都共用了common模块。

如果在开发中不注意这个问题,可能会带来不可预料的后果,因此,在模块内放置的变量,最好是弄成只读,不要试图去修改它们。

相关资料:
https://groups.google.com/forum/#!topic/openresty/3ylMdtvUJqg
https://github.com/openresty/lua-nginx-module#data-sharing-within-an-nginx-worker

相关内容

    暂无相关文章