首页 > 解决方案 > 将嵌套表存储在 nginx 共享内存中

问题描述

我正在使用 open-resty 和 lua 创建一个用于重定向请求的服务器。重定向是基于来自 lua 数据树结构(嵌套表)的一些数据完成的

我正在寻找一种方法来在启动时填充这些数据,然后在工作人员之间共享数据。

ngx.ctx 可以保存任意数据,但仅在请求期间持续。共享字典持续到最后,但只能保存原语列表。

我读过可以跨 lua 模块共享数据。因为模块在启动时只被实例化一次。代码是这样的

local _M = {}

local data = {
    dog = {"value1", "value4"},
    cat = {"value2", "value5"},
    pig = {"value3", "value6"}
}


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"))
    }
}

这第三种可能性线程安全吗?还有其他东西可以实现这一目标吗?

这方面的文档不多,这就是为什么在这里发布它。任何信息都会有所帮助,谢谢

标签: nginxlualua-tableopenrestylua-5.1

解决方案


您可以在 中填充您的数据init_by_lua,并在以后访问它。在您的情况下,模块的初始化mydata可以通过以下方式实现:

init_by_lua_block {
     require "mydata"
}

init_by_lua在 nginx 启动期间运行一次,然后它运行的进程分叉成工作人员,因此每个工作人员都包含此数据的独立副本。

Worker 是单线程的,因此您可以安全地访问您的数据。


现在,如果你想在运行时修改你的配置,而不重新加载 nginx,那么它会变得有点复杂。每个工作人员都是独立的,但我们可以使用ngx.shared.DICT来传播更改。根据您的要求,您可以使用两种解决方案:

  1. 每次更改后,将您的配置放入共享字典中。创建一个计时器,定期从该共享缓存中重新加载工作人员的配置。
  2. 每次更改后,将您的配置连同当前时间戳或版本号一起放入共享字典中。在工作人员中的每个请求上,检查此时间戳/版本是否永远不会比本地缓存的那个 - 如果是则反序列化此配置并在本地缓存它。

如果你有一个应该可用的 API,那么你可以使用lua-resty-lock来创建同步修改的跨工作者关键部分。


推荐阅读