Stream模块lua深层清理

1. 功能描述

NJet 集成了Lua 的运行环境,在不配置 lua_code_cache off; 的情况下,worker收到请求时,会从context中获取已经创建的Lua VM (第一次执行Lua相关代码时创建)。Lua VM中, package.loaded 是一个核心的 Lua 表,它扮演着 Lua 模块缓存的角色。当使用 require(“module_name”) 加载一个 Lua 模块时,Lua 解释器会首先检查 package.loaded 表中是否已经存在名为 module_name 的模块。如果存在,它会直接返回已缓存的模块值;如果不存在,它才会去文件系统(根据 package.path)查找、加载并执行该模块文件,然后将其返回值存储到 package.loaded 中,供后续调用。

在配置了多个 worker 进程时, 每个worker 进程都拥有自己独立的 LuaJIT 虚拟机实例 (Lua State)。这意味着每个 worker 进程的 Lua 虚拟机都有自己独立的 package.loaded 表,它们之间互不影响。有可能造成部分worker进程缓存了模块,部分进程没有对模块进行缓存。

当更新了磁盘上的 Lua 模块文件时,例如 mylib.lua, package.loaded 中已经缓存了旧版本的 mylib的worker进程将执行旧版的代码,而未缓存该模块的部分worker进程收到请求时将直接使用新版本,这样照成了各个worker的行为不一致。并且那些被间接 require 的模块(即主 Lua 脚本 require 了 A,而 A 又 require 了 B),Lua 自身也没有机制去追踪这种深层次的依赖关系并自动刷新。

2. 依赖模块

stream模块lua深层清理依赖于stream动态lua功能:

load_module modules/njt_stream_lua_module.so; 
load_module modules/njt_stream_dyn_lua_module.so; 

特殊说明:njt_stream_lua_module.so要在njt_stream_lua_module.so上面。

3. API说明

清理接口:

PUT http://IP+port/api/v1/config/stream_lua_package_clean

4. 调用样例

4.1 深层清理lua

njet.conf

helper ctrl modules/njt_helper_ctrl_module.so conf/njet_ctrl.conf;
helper broker modules/njt_helper_broker_module.so conf/mqtt.conf;
load_module modules/njt_stream_lua_module.so; 
load_module modules/njt_stream_dyn_lua_module.so; 


stream {
   ...
   server {

     listen 22222
  
     lua_package_path "$prefix/lualib/lib/?.lua;/usr/local/njet/modules/?.lua;;";
     lua_package_cpath "$prefix/lualib/clib/?.so;;";

      content_by_lua_block {
           local mylib = require("mylib")
           njt.say("from 22222")
           mylib.run()
      }


        ...
   }
}

mylib.lua

local _M={}

function _M.run()
    njt.say("in mylib version 1")
end

return _M

启动njet后,访问端口22222

curl --http0.9 http://127.0.0.1:22222/

from 22222
in mylib version 1

修改mylib.lua

local _M={}

function _M.run()
    njt.say("in mylib version 2")
end

return _M

再次访问22222,依然返回version 1

curl --http0.9 http://127.0.0.1:22222/

from 22222
in mylib version 1

执行lua深层清理

curl -X 'PUT' \
  'http://192.168.40.119:8081/api/v1/config/stream_lua_package_clean' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '[
  "mylib"
]'

再次访问22222,返回version 2

curl --http0.9 http://127.0.0.1:22222/

from 22222
in mylib version 2