ngx lua: local 变量的作用域问题,init_by_lua_block 中的初始化

我刚接触 nginx lua,之前开发者留下了一个设置给我。现在我正在阅读文档以了解作用域,但我还是很不确定。

当前状态如下

init_by_lua_block {
    my_module = require 'my_module'
    my_module.load_data()
}

location / {
    content_by_lua_block {
        my_module.use_data()
    }
}

在 my_module 中

local _M = {}
local content = {}

function _M.use_data()
    -- 访问 content 变量
end

function _M.load_data()
    -- 将 JSON 数据加载到 content 变量中的代码
end

return _M

因此,我理解 content 是一个局部变量,因此其生命周期在每个请求中。然而,它是在 init_by_lua_block 中初始化的,并且被其他局部函数使用,这让我感到困惑。这是一个好的做法吗?而这个 content 变量的实际生命周期是什么?

非常感谢您的阅读。

点赞
用户3422711
用户3422711

init_by_lua[_block] 在 nginx 加载配置阶段运行,在工作进程 fork 之前。

因此,content 变量是全局的,在每个请求中都是一样的。

https://github.com/openresty/lua-nginx-module/#init_by_lua

2018-03-16 09:46:40
用户2799495
用户2799495

发现了这个:https://github.com/openresty/lua-nginx-module#data-sharing-within-an-nginx-worker

要在同一个 nginx 工作进程处理的所有请求之间全局共享数据,需要将共享数据封装到一个 Lua 模块中,使用 Lua 的 require 内置函数导入模块,然后在 Lua 中操作共享数据。这样可以工作的原因是,已经导入的 Lua 模块只被加载一次,并且所有协程将共享模块的相同副本(包括代码和数据)。但是,请注意,由于单协程处理单个请求的隔离设计,Lua 全局变量(注意,不是模块级变量)不会在请求之间持久存在。

这里是一个完整的小例子:

-- mydata.lua
local _M = {}

local data = {
    dog = 3,
    cat = 4,
    pig = 5,
}

function _M.get_age(name)
    return data[name]
end

return _M

然后从 nginx.conf 访问它:

location /lua {
    content_by_lua_block {
        local mydata = require "mydata"
        ngx.say(mydata.get_age("dog"))
    }
}
2018-03-16 10:15:50