动态配置Lua脚本及应用

🙈 By 洪昕 2024-05-07

OpenNJet 是基于Nginx fork并独立演进的应用引擎,提供的Lua脚本运行能力移植自OpenResty 社区开源的lua-nginx-module 模块,该开源的Lua模块可以将Lua脚本通过内嵌的方式直接写在配置文件中,或者通过 *_by_lua_file 的指令(如content_by_lua_file, access_by_lua_file) 写在外部文件中。

Nginx 上难于进行动态化配置的问题,同样存在于Lua脚本的修改上。一旦完成初始配置,脚本内容进行修改后,需要生效一般只能通过两种方式。其一是服务进程重新加载配置(reload),另一种方案是将脚本放置于外部文件,并通过配置 lua_code_cache off的方式关闭代码缓存机制,但这种方式只适用于开发阶段,生产环境并不适用。

OpenNJet 架构设计已经考虑了动态配置的问题,Lua 脚本内容的修改上,使用架构提供的能力,在兼顾性能的情况下,实现了无需重启或重加载,实时更新Lua脚本的功能。

1 功能说明

Lua动态配置能力,通过模块 ”njt_http_dyn_lua_module”实现,使用时需要在数据面的配置文件中加载该模块。

在文件njet.conf中,首先配置测试的server及location, 接下来的功能演示测试中将用到, 配置如下:

worker_processes auto;
cluster_name njet;
node_name node1;
error_log logs/error.log error;
helper ctrl modules/njt_helper_ctrl_module.so conf/njet_ctrl.conf;
helper broker modules/njt_helper_broker_module.so;
load_module modules/njt_http_location_module.so;
load_module modules/njt_http_lua_module.so;
load_module modules/njt_http_dyn_lua_module.so;
events {
    worker_connections  1024;
}
http {
    include mime.types;
    access_log off;
    lua_package_path "$prefix/lualib/lib/?.lua;/usr/local/njet/modules/?.lua;;";
lua_package_cpath "$prefix/lualib/clib/?.so;;";
upstream weba {
      server 127.0.0.1:8888;
    }
    server {
     listen 8888;
     location / {
       return 200 "return from server8888\n";
     }
    }
    server {
        listen       8080;
        location / {
           root html;
        }
        location /lua {
          content_by_lua_block {
               njt.say("lua test")
         }
        }
    }
}

该配置文件使用内嵌的方式,在location /lua 下, 配置了content_by 脚本。服务进程启动后, 访问该测试地址,可以看到输出的内容。

img

通过查询接口,获取当前配置。

img

通过Restful 接口提交新的Lua脚本内容,变更将实时生效,不需要重加载配置。

img

除了修改content_by 脚本内容,还可以添加或修改access 阶段的脚本。

img

2 进阶场景

结合OpenNJet 的动态Location 配置能力,可以实现更为复杂的场景。

例如设计如下场景:

-> 动态添加一个location, location 中使用proxy_pass 代理到后端服务

-> 使用动态Lua设置,覆盖掉proxy_pass的配置,输出Lua 脚本中的内容

-> 动态删除location

-> 重新添加location

场景验证如下:

img

动态Lua 配置,目前实现了最为常用的content_by, access_by 两个阶段,能够实时替换当前服务进程使用的Lua脚本内容,后续也可以逐步将动态配置能力扩展到其它阶段(如log_by, header_filter, body_filter)。